Skip to content

Commit

Permalink
[#63] Migrations schema creation. Migrate function.
Browse files Browse the repository at this point in the history
  • Loading branch information
jfacorro committed Sep 17, 2014
1 parent 9ff1351 commit 755fdbb
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 4 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ examples/blog/log
*.o
*.beam
*.plt
.rebar
.rebar
*.dump
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ HOST?=$(shell hostname)
NODE?=${NAME}@${HOST}
DIALYZER_OUT?=${NAME}.plt

ERL_ARGS?=-pa ebin -pa deps/*/ebin -name ${NODE}
ERL_ARGS?=-pa ebin -pa deps/*/ebin -name ${NODE} -s sync

all: getdeps compile edoc
all: getdeps compile
${REBAR} compile

blog:
Expand Down
3 changes: 2 additions & 1 deletion rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
{emysql, "0.*", {git, "[email protected]:Eonblast/Emysql.git", "master"}},
{emongo, ".*", {git, "[email protected]:marcelog/emongo.git", "marcelog_login_for_2_2_and_higher"}},
{'sqlite3', ".*", {git, "[email protected]:alexeyr/erlang-sqlite3.git", "HEAD"}},
{worker_pool, ".*", {git, "[email protected]:inaka/worker_pool.git", "master"}}
{worker_pool, ".*", {git, "[email protected]:inaka/worker_pool.git", "master"}},
{sync, ".*", {git, "[email protected]:rustyio/sync.git", "master"}}
]}.
{xref_warnings, true}.
{xref_checks, [undefined_function_calls, undefined_functions, locals_not_used, deprecated_function_calls, deprecated_functions]}.
15 changes: 15 additions & 0 deletions src/sumo.erl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
-export([find/2, find_all/1, find_all/4, find_by/2, find_by/4, find_one/2]).
-export([call/2, call/3]).

%%% API for migrations.
-export([migrate/0, rollback/0]).

-type schema_name() :: atom().

-type field_attr() :: id|unique|index|not_null|auto_increment|{length, integer()}.
Expand Down Expand Up @@ -243,3 +246,15 @@ new_field(Name, Type, Attributes) ->
-spec new_field(field_name(), field_type()) -> field().
new_field(Name, Type) ->
new_field(Name, Type, []).

%% @doc Runs all migrations to get the DB up to date.
-spec migrate() -> ok | {error, term()}.
migrate() ->
sumo_migration:migrate(),
halt(0).

%% @doc Rolls back the last migration and downgrades the DB version.
-spec rollback() -> ok | {error, term()}.
rollback() ->
sumo_migration:rollback(),
halt(0).
85 changes: 85 additions & 0 deletions src/sumo_migration.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
-module(sumo_migration).

-behavior(sumo_doc).

-export([migrate/0, rollback/0]).

-export([migration_update_list/1]).

%%% sumo_db callbacks
-export([sumo_schema/0, sumo_wakeup/1, sumo_sleep/1]).

-callback up() -> string().
-callback down() -> string().

-type migration() :: atom().

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Exported
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

-spec migrate() -> ok.
migrate() ->
ensure_sumo_migration_doc(),
LastMigration = last_migration_update(),
Migrations = migration_update_list(LastMigration),
lists:foreach(fun(M) -> M:up() end, Migrations).

-spec rollback() -> ok.
rollback() ->
ensure_sumo_migration_doc(),
ok.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% sumo_doc callbacks
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

-spec sumo_schema() -> sumo:schema().
sumo_schema() ->
Fields = [sumo:new_field(version, string)],
sumo:new_schema(?MODULE, Fields).

-spec sumo_sleep(migration()) -> sumo:doc().
sumo_sleep(Migration) ->
[{version, Migration}].

-spec sumo_wakeup(sumo:doc()) -> migration().
sumo_wakeup(Migration) ->
VersionBin = proplists:get_value(version, Migration),
binary_to_atom(VersionBin, utf8).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Internal
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% @doc Make sure the schema_version table is present in the datastore.
-spec ensure_sumo_migration_doc() -> ok.
ensure_sumo_migration_doc() ->
sumo:create_schema(?MODULE).

-spec last_migration_update() -> migration().
last_migration_update() ->
Migrations = sumo:find_all(?MODULE),
lists:max(Migrations).

-spec migration_update_list(migration()) -> [migration()].
migration_update_list(LastMigration) ->
MigrationsDir = migrations_dir(),
Files = filelib:wildcard("*.erl", MigrationsDir),
F = compose([fun filename:rootname/1, fun list_to_atom/1]),
AvailableMigrations = lists:map(F, Files),
lists:filter(fun(X) -> X > LastMigration end, AvailableMigrations).

-spec migrations_dir() -> string().
migrations_dir() ->
case application:get_env(migrations_dir, sumo_db) of
undefined -> "src/migrations";
Dir -> Dir
end.

-spec compose([fun()]) -> fun().
compose(Funs) ->
Compose = fun(F, X) -> F(X) end,
fun(X) ->
lists:foldl(Compose, X, Funs)
end.
13 changes: 13 additions & 0 deletions test/migrations/20140901_mig1.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-module('20140901_mig1').

-behavior(sumo_migration).

-export([up/0, down/0]).

up() ->
io:format("=== ~p up/0~n", [?MODULE]),
ok.

down() ->
io:format("=== ~p down/0~n", [?MODULE]),
ok.
13 changes: 13 additions & 0 deletions test/migrations/20140902_mig.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-module('20140902_mig').

-behavior(sumo_migration).

-export([up/0, down/0]).

up() ->
io:format("=== ~p up/0~n", [?MODULE]),
ok.

down() ->
io:format("=== ~p down/0~n", [?MODULE]),
ok.
13 changes: 13 additions & 0 deletions test/migrations/20140903_mig.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-module('20140903_mig').

-behavior(sumo_migration).

-export([up/0, down/0]).

up() ->
io:format("=== ~p up/0~n", [?MODULE]),
ok.

down() ->
io:format("=== ~p down/0~n", [?MODULE]),
ok.

0 comments on commit 755fdbb

Please sign in to comment.