mirror of
https://github.com/UzixLS/migresia.git
synced 2025-07-18 23:01:21 +03:00
Adding rollback functionality
This commit is contained in:
@ -24,7 +24,7 @@
|
||||
|
||||
-module(migresia).
|
||||
|
||||
-export([create_new_migration/2, check/1, migrate/1, list_nodes/0, ensure_started/1]).
|
||||
-export([create_new_migration/2, check/1, migrate/1, rollback/2, list_nodes/0, ensure_started/1]).
|
||||
|
||||
-define(TABLE, schema_migrations).
|
||||
|
||||
@ -68,13 +68,33 @@ migrate(App) ->
|
||||
{error, Error} -> {error, Error}
|
||||
end.
|
||||
|
||||
-spec rollback(atom(), integer()) -> ok | {error, any()}.
|
||||
rollback(App, Time) ->
|
||||
case start_mnesia(true) of
|
||||
ok ->
|
||||
case migresia_migrations:ensure_schema_table_exists() of
|
||||
ok ->
|
||||
io:format("Waiting for tables (max timeout 2 minutes)...", []),
|
||||
ok = mnesia:wait_for_tables(mnesia:system_info(tables), 120000),
|
||||
rpc:multicall(migresia_migrations, list_all_ups, [App]), %Basically just to ensure everybody has loaded all the migrations, which is necessary in distributed Mnesia transforms.
|
||||
ToRollBack = lists:reverse([X || X<- migresia_migrations:list_all_ups(App), binary_to_integer(element(2, X)) > Time]),
|
||||
lists:foreach(fun execute_down/1, ToRollBack);
|
||||
{error, Error} -> Error
|
||||
end;
|
||||
{error, Error} -> {error, Error}
|
||||
end.
|
||||
|
||||
execute_up({Module, Short}) ->
|
||||
io:format("Executing up in ~s...~n", [Module]),
|
||||
Module:up(),
|
||||
mnesia:dirty_write(schema_migrations, {schema_migrations, Short, true}),
|
||||
io:format(" => done~n", []).
|
||||
|
||||
|
||||
execute_down({Module, Time}) ->
|
||||
io:format("Executing down in ~s...~n", [Module]),
|
||||
Module:down(),
|
||||
mnesia:dirty_delete(schema_migrations, Time),
|
||||
io:format(" => done~n", []).
|
||||
|
||||
-spec start_mnesia(boolean()) -> ok | {error, any()}.
|
||||
start_mnesia(RemoteToo) ->
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
-module(migresia_migrations).
|
||||
|
||||
-export([list_unapplied_ups/1, get_priv_dir/1, ensure_schema_table_exists/0]).
|
||||
-export([list_unapplied_ups/1, list_all_ups/1, get_priv_dir/1, ensure_schema_table_exists/0]).
|
||||
|
||||
-define(DIR, <<"migrate">>).
|
||||
-define(TABLE, schema_migrations).
|
||||
@ -33,6 +33,9 @@
|
||||
list_unapplied_ups(App) ->
|
||||
get_migrations(get_priv_dir(App)).
|
||||
|
||||
list_all_ups(App) ->
|
||||
get_all_migrations(get_priv_dir(App)).
|
||||
|
||||
-spec get_priv_dir(atom()) -> binary().
|
||||
get_priv_dir(App) ->
|
||||
case application:load(App) of
|
||||
@ -67,6 +70,12 @@ get_migrations(Dir) ->
|
||||
lists:map(Fun, ToExecute)
|
||||
end.
|
||||
|
||||
get_all_migrations(Dir) ->
|
||||
ToApply = lists:sort(check_dir(file:list_dir(Dir))),
|
||||
ToExecute = compile_unapplied(Dir, ToApply, [], []),
|
||||
Fun = fun({Module, Short, Binary}) -> load_migration(Module, Short, Binary) end,
|
||||
lists:map(Fun, ToExecute).
|
||||
|
||||
check_dir({error, Reason}) ->
|
||||
throw({file, list_dir, Reason});
|
||||
check_dir({ok, Filenames}) ->
|
||||
|
Reference in New Issue
Block a user