mirror of
https://github.com/UzixLS/migresia.git
synced 2025-07-18 23:01:21 +03:00
Creating variants of functions that take an application, and providing a template for creating migrations.
This commit is contained in:
21
README.md
21
README.md
@ -22,11 +22,11 @@ Migresia stores all applied migrations in table `schema_migrations` which it cre
|
||||
|
||||
## Migrations
|
||||
|
||||
Each migration is an Erlang source `*.erl` file stored in folder `priv/migrate/`, where `priv` is the private folder of the Migresia application. That folder is ignored in the Migresia repository and it is recommended that `priv/migrate` is a link to a folder within the main project, of which Migresia is a dependency, where it should be kept under a version control.
|
||||
Each migration is an Erlang source `*.erl` file stored either in folder `priv/migrate/`, where `priv` is the private folder of the Migresia application, or under the priv directory of your application. If that folder is under Migresia's priv directory you will not need to pass in an application when calling Migresia; if it's under your own project you will.
|
||||
|
||||
Migresia compiles the migrations automatically when it applies them, so they should be always distributed as source files. This is mainly to allow keeping applied migrations under a version control but not have to compile them every time when building the application or creating a release.
|
||||
|
||||
When developing a new migration just use `migresia:check/0` to let Migresia to compile them and report any problems.
|
||||
When developing a new migration just use `migresia:check/0` or `migresia:check/1` to let Migresia try to compile them and report any problems.
|
||||
|
||||
#### Migration names
|
||||
|
||||
@ -38,6 +38,8 @@ The timestamp is always 14 numbers, but otherwise can contain any value. Migresi
|
||||
|
||||
The remaining part of the name, after the timestamp, is simply ignored. A migration name consisting of just the timestamp is also a valid name.
|
||||
|
||||
You can generate a timestamped stub using `migresia:create_new_migration/1` or `migresia:create_new_migration/2`
|
||||
|
||||
#### Implementing migrations
|
||||
|
||||
Migresia doesn't provide any special support for transactions. If any operations should be executed within a transaction, it just should be created and handled accordingly in the `up` or `down` functions.
|
||||
@ -62,9 +64,14 @@ Very often migrations need to know the record definitions of Mnesia tables to wh
|
||||
|
||||
## API Calls
|
||||
|
||||
Migresia exports three simple functions:
|
||||
Migresia exports 6 functions. All functions can take an optional first parameter of an application name (as an atom) if you want your migrations to be under your application rather than Migresia:
|
||||
|
||||
##### `migresia:check/0`
|
||||
|
||||
##### `migresia:create_new_migration/1` and `migresia:create_new_migration/2`
|
||||
|
||||
Creates a stubbed out migration file for you. The last argument is the name you want appended after the timestamp.
|
||||
|
||||
##### `migresia:check/0` or `migresia:check/1`
|
||||
|
||||
This function does three things:
|
||||
|
||||
@ -72,11 +79,11 @@ This function does three things:
|
||||
* List available migrations and check which ones haven't yet been applied.
|
||||
* Compile and load all unapplied migrations.
|
||||
|
||||
This is the method that should be used to check migrations for compilation errors as well as to verify which migrations will be applied if `migresia:migrate/0` is executed to migrate the database.
|
||||
This is the method that should be used to check migrations for compilation errors as well as to verify which migrations will be applied if `migresia:migrate/1` is executed to migrate the database.
|
||||
|
||||
##### `migresia:migrate/0`
|
||||
##### `migresia:migrate/0` or `migresia:migrate/1`
|
||||
|
||||
Works almost exactly like `migresia:check/0` but in the end, instead of printing information which migrations are going to be applied, just applies them by executing the required `up` or `down` functions.
|
||||
Works almost exactly like `migresia:check/1` but in the end, instead of printing information which migrations are going to be applied, just applies them by executing the required `up` or `down` functions.
|
||||
|
||||
##### `migresia:list_nodes/0`
|
||||
|
||||
|
@ -24,20 +24,42 @@
|
||||
|
||||
-module(migresia).
|
||||
|
||||
-export([check/0, migrate/0, list_nodes/0]).
|
||||
-export([create_new_migration/1, create_new_migration/2, check/0, check/1, migrate/0, migrate/1, list_nodes/0]).
|
||||
|
||||
check() ->
|
||||
Loaded = migresia_migrations:list_unapplied_ups(),
|
||||
-spec create_new_migration(string()) -> any().
|
||||
create_new_migration(Description) ->
|
||||
create_new_migration(undefined, Description).
|
||||
|
||||
-spec create_new_migration(atom(), string()) -> any().
|
||||
create_new_migration(App, Description) ->
|
||||
{{Year, Month, Day}, {Hour, Minute, Second}} = calendar:local_time(),
|
||||
Filename = lists:flatten(io_lib:format("~w~2.2.0w~2.2.0w~2.2.0w~2.2.0w~2.2.0w_", [Year, Month, Day, Hour, Minute, Second]) ++ Description),
|
||||
FullPathAndExtension = filename:join(migresia_migrations:get_priv_dir(App), Filename ++ ".erl"),
|
||||
io:format("Creating new migration: ~p~n", [FullPathAndExtension]),
|
||||
file:write_file(FullPathAndExtension, io_lib:fwrite("-module(~p).~n-behavior(db_migration).~n-export([up/0, down/0]). ~n~nup() -> ok.~n~ndown() -> throw(<<\"Downgraders not implemented.\">>)", [list_to_atom(Filename)])),
|
||||
io:format("Migration written.~n~n").
|
||||
|
||||
-spec check(atom()) -> any().
|
||||
check(App) ->
|
||||
Loaded = migresia_migrations:list_unapplied_ups(App),
|
||||
if Loaded == [] ->
|
||||
io:format("No migrations to apply.~n", []);
|
||||
true ->
|
||||
io:format("Migrations to apply: ~p~n", [ [X||{X,_} <- Loaded] ])
|
||||
end.
|
||||
|
||||
migrate() ->
|
||||
Loaded = migresia_migrations:list_unapplied_ups(),
|
||||
-spec check() -> any().
|
||||
check() -> check(undefined).
|
||||
|
||||
-spec migrate(atom()) -> any().
|
||||
migrate(App) ->
|
||||
Loaded = migresia_migrations:list_unapplied_ups(App),
|
||||
lists:foreach(fun execute_up/1, Loaded).
|
||||
|
||||
-spec migrate() -> any().
|
||||
migrate() ->
|
||||
migrate(undefined).
|
||||
|
||||
execute_up({Module, Short}) ->
|
||||
io:format("Executing up in ~s...~n", [Module]),
|
||||
Module:up(),
|
||||
@ -46,3 +68,4 @@ execute_up({Module, Short}) ->
|
||||
|
||||
list_nodes() ->
|
||||
mnesia:table_info(schema, disc_copies).
|
||||
|
||||
|
@ -26,16 +26,24 @@
|
||||
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
-export([list_unapplied_ups/0]).
|
||||
-export([list_unapplied_ups/1, get_priv_dir/1]).
|
||||
|
||||
-define(APP, migresia).
|
||||
-define(DIR, <<"migrate">>).
|
||||
-define(TABLE, schema_migrations).
|
||||
|
||||
-spec list_unapplied_ups() -> [{module(), binary()}].
|
||||
list_unapplied_ups() ->
|
||||
application:load(?APP),
|
||||
get_migrations(filename:join(code:priv_dir(?APP), ?DIR)).
|
||||
-spec list_unapplied_ups(atom()) -> [{module(), binary()}].
|
||||
list_unapplied_ups(App) when App == undefined ->
|
||||
list_unapplied_ups(?APP);
|
||||
list_unapplied_ups(App) ->
|
||||
get_migrations(get_priv_dir(App)).
|
||||
|
||||
|
||||
get_priv_dir(App) when App == undefined ->
|
||||
get_priv_dir(?APP);
|
||||
get_priv_dir(App) ->
|
||||
application:load(App),
|
||||
filename:join(code:priv_dir(App), ?DIR).
|
||||
|
||||
get_migrations({error, _} = Err) ->
|
||||
exit(Err);
|
||||
|
Reference in New Issue
Block a user