Current section
Files
Jump to
Current section
Files
src/cigogne.erl
-module(cigogne).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([new_migration/1, get_migrations/0, get_schema/1, update_schema_file/1, print_error/1, apply_migration/2, apply_next_migration/1, migrate_up/0, execute_migrations_to_last/1, migrate_to_last/0, roll_back_migration/2, roll_back_previous_migration/1, migrate_down/0, execute_n_migrations/2, migrate_n/1, main/0]).
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 16).
-spec migration_zero() -> cigogne@types:migration().
migration_zero() ->
{migration,
<<""/utf8>>,
cigogne@internal@utils:tempo_epoch(),
<<"CreateMigrationsTable"/utf8>>,
[<<"CREATE TABLE IF NOT EXISTS _migrations(
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
createdAt TIMESTAMP WITHOUT TIME ZONE NOT NULL,
appliedAt TIMESTAMP NOT NULL DEFAULT NOW()
);"/utf8>>],
[]}.
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 56).
-spec show_usage() -> {ok, nil} | {error, cigogne@types:migrate_error()}.
show_usage() ->
gleam_stdlib:println(<<"======================================="/utf8>>),
gleam_stdlib:println(<<"= CIGOGNE ="/utf8>>),
gleam_stdlib:println(<<"======================================="/utf8>>),
gleam_stdlib:println(<<""/utf8>>),
gleam_stdlib:println(<<"Usage: gleam run -m cigogne [command]"/utf8>>),
gleam_stdlib:println(<<""/utf8>>),
gleam_stdlib:println(<<"List of commands:"/utf8>>),
gleam_stdlib:println(
<<" - show: Show the last currently applied migration"/utf8>>
),
gleam_stdlib:println(
<<" - up: Migrate up one version / Apply one migration"/utf8>>
),
gleam_stdlib:println(
<<" - down: Migrate down one version / Rollback one migration"/utf8>>
),
gleam_stdlib:println(
<<" - last: Apply all migrations until the last one defined"/utf8>>
),
gleam_stdlib:println(
<<" - apply N: Apply or roll back N migrations (N can be positive or negative)"/utf8>>
),
gleam_stdlib:println(
<<" - new NAME: Create a new migration file in /priv/migrations with the specified name"/utf8>>
),
{ok, nil}.
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 123).
-spec new_migration(binary()) -> {ok, nil} |
{error, cigogne@types:migrate_error()}.
new_migration(Name) ->
gleam@result:map(
cigogne@internal@fs:create_new_migration_file(
tempo@naive_datetime:now_utc(),
Name
),
fun(Path) ->
gleam_stdlib:println(
<<"Migration file created : "/utf8, Path/binary>>
)
end
).
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 286).
-spec get_migrations() -> {ok, list(cigogne@types:migration())} |
{error, cigogne@types:migrate_error()}.
get_migrations() ->
cigogne@internal@fs:get_migrations().
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 291).
-spec get_schema(binary()) -> {ok, binary()} |
{error, cigogne@types:migrate_error()}.
get_schema(Url) ->
cigogne@internal@database:get_schema(Url).
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 297).
-spec update_schema_file(binary()) -> {ok, nil} |
{error, cigogne@types:migrate_error()}.
update_schema_file(Url) ->
gleam@result:'try'(
get_schema(Url),
fun(Schema) -> _pipe = cigogne@internal@fs:write_schema_file(Schema),
gleam@result:map(
_pipe,
fun(_) ->
gleam_stdlib:println(<<"Schema file updated"/utf8>>)
end
) end
).
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 371).
-spec print_error(cigogne@types:migrate_error()) -> nil.
print_error(Error) ->
cigogne@types:print_migrate_error(Error).
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 321).
-spec get_applied_migrations(pog:connection()) -> {ok,
list(cigogne@types:migration())} |
{error, cigogne@types:migrate_error()}.
get_applied_migrations(Conn) ->
_pipe = pog:'query'(
<<"SELECT createdAt, name FROM _migrations ORDER BY appliedAt ASC;"/utf8>>
),
_pipe@1 = pog:returning(
_pipe,
begin
gleam@dynamic@decode:field(
0,
pog:timestamp_decoder(),
fun(Timestamp) ->
gleam@dynamic@decode:field(
1,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Name) ->
gleam@dynamic@decode:success({Timestamp, Name})
end
)
end
)
end
),
_pipe@2 = pog:execute(_pipe@1, Conn),
_pipe@3 = gleam@result:map_error(
_pipe@2,
fun(Field@0) -> {pgo_query_error, Field@0} end
),
gleam@result:then(_pipe@3, fun(Returned) -> case Returned of
{returned, 0, _} ->
{error, no_result_error};
{returned, _, []} ->
{error, no_result_error};
{returned, _, Applied} ->
_pipe@4 = Applied,
gleam@list:try_map(
_pipe@4,
fun(Data) ->
_pipe@5 = cigogne@internal@utils:pog_to_tempo_timestamp(
erlang:element(1, Data)
),
_pipe@6 = gleam@result:map(
_pipe@5,
fun(Timestamp@1) ->
{migration,
<<""/utf8>>,
Timestamp@1,
erlang:element(2, Data),
[],
[]}
end
),
gleam@result:replace_error(
_pipe@6,
{date_parse_error,
cigogne@internal@utils:pog_timestamp_to_string(
erlang:element(1, Data)
)}
)
end
)
end end).
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 303).
-spec get_last_applied_migration(pog:connection()) -> {ok,
cigogne@types:migration()} |
{error, cigogne@types:migrate_error()}.
get_last_applied_migration(Conn) ->
_pipe = get_applied_migrations(Conn),
_pipe@1 = gleam@result:map(_pipe, fun lists:reverse/1),
gleam@result:then(
_pipe@1,
fun(Migs) ->
case begin
_pipe@2 = Migs,
gleam@list:first(_pipe@2)
end of
{error, nil} ->
{error, no_migration_to_rollback_error};
{ok, Mig} ->
case tempo@naive_datetime:compare(
erlang:element(3, Mig),
cigogne@internal@utils:tempo_epoch()
) of
eq ->
{error, no_migration_to_rollback_error};
_ ->
{ok, Mig}
end
end
end
).
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 212).
-spec apply_migration(pog:connection(), cigogne@types:migration()) -> {ok, nil} |
{error, cigogne@types:migrate_error()}.
apply_migration(Connection, Migration) ->
gleam_stdlib:println(
<<<<<<"\nApplying migration "/utf8,
(begin
_pipe = erlang:element(3, Migration),
tempo@naive_datetime:format(
_pipe,
<<"YYYYMMDDhhmmss"/utf8>>
)
end)/binary>>/binary,
"-"/utf8>>/binary,
(erlang:element(4, Migration))/binary>>
),
Queries = begin
_pipe@1 = gleam@list:map(
erlang:element(5, Migration),
fun pog:'query'/1
),
lists:append(
_pipe@1,
[begin
_pipe@2 = pog:'query'(
<<"INSERT INTO _migrations(createdAt, name) VALUES ($1, $2);"/utf8>>
),
_pipe@4 = pog:parameter(
_pipe@2,
pog:timestamp(
begin
_pipe@3 = erlang:element(3, Migration),
cigogne@internal@utils:tempo_to_pog_timestamp(
_pipe@3
)
end
)
),
pog:parameter(
_pipe@4,
pog_ffi:coerce(erlang:element(4, Migration))
)
end]
)
end,
_pipe@5 = cigogne@internal@database:execute_batch(
Connection,
Queries,
cigogne@internal@migrations:compare_migrations(
Migration,
migration_zero()
)
=:= eq
),
gleam@result:map(
_pipe@5,
fun(_) ->
gleam_stdlib:println(
<<<<<<"Migration applied : "/utf8,
(begin
_pipe@6 = erlang:element(3, Migration),
tempo@naive_datetime:format(
_pipe@6,
<<"YYYYMMDDhhmmss"/utf8>>
)
end)/binary>>/binary,
"-"/utf8>>/binary,
(erlang:element(4, Migration))/binary>>
)
end
).
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 198).
-spec apply_migration_zero_if_not_applied(pog:connection()) -> {ok, nil} |
{error, cigogne@types:migrate_error()}.
apply_migration_zero_if_not_applied(Connection) ->
case get_applied_migrations(Connection) of
{error, {pgo_query_error, {postgresql_error, Code, _, _}}} when Code =:= <<"42P01"/utf8>> ->
apply_migration(Connection, migration_zero());
_ ->
{ok, nil}
end.
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 134).
-spec apply_next_migration(pog:connection()) -> {ok, nil} |
{error, cigogne@types:migrate_error()}.
apply_next_migration(Connection) ->
gleam@result:'try'(
apply_migration_zero_if_not_applied(Connection),
fun(_) ->
gleam@result:'try'(
get_applied_migrations(Connection),
fun(Applied) ->
gleam@result:'try'(
cigogne@internal@fs:get_migrations(),
fun(Migs) ->
gleam@result:'try'(
cigogne@internal@migrations:find_first_non_applied_migration(
Migs,
Applied
),
fun(Migration) ->
apply_migration(Connection, Migration)
end
)
end
)
end
)
end
).
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 82).
-spec migrate_up() -> {ok, nil} | {error, cigogne@types:migrate_error()}.
migrate_up() ->
gleam@result:'try'(
cigogne@internal@database:get_url(),
fun(Url) ->
gleam@result:'try'(
cigogne@internal@database:connect(Url),
fun(Conn) ->
gleam@result:'try'(
apply_next_migration(Conn),
fun(_) -> update_schema_file(Url) end
)
end
)
end
).
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 185).
-spec execute_migrations_to_last(pog:connection()) -> {ok, nil} |
{error, cigogne@types:migrate_error()}.
execute_migrations_to_last(Connection) ->
gleam@result:'try'(
apply_migration_zero_if_not_applied(Connection),
fun(_) ->
gleam@result:'try'(
get_applied_migrations(Connection),
fun(Applied) ->
gleam@result:'try'(
cigogne@internal@fs:get_migrations(),
fun(Migs) ->
_pipe = cigogne@internal@migrations:find_all_non_applied_migration(
Migs,
Applied
),
gleam@result:then(
_pipe,
fun(_capture) ->
gleam@list:try_each(
_capture,
fun(Migration) ->
apply_migration(
Connection,
Migration
)
end
)
end
)
end
)
end
)
end
).
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 115).
-spec migrate_to_last() -> {ok, nil} | {error, cigogne@types:migrate_error()}.
migrate_to_last() ->
gleam@result:'try'(
cigogne@internal@database:get_url(),
fun(Url) ->
gleam@result:'try'(
cigogne@internal@database:connect(Url),
fun(Conn) ->
gleam@result:'try'(
execute_migrations_to_last(Conn),
fun(_) -> update_schema_file(Url) end
)
end
)
end
).
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 350).
-spec show() -> {ok, nil} | {error, cigogne@types:migrate_error()}.
show() ->
gleam@result:'try'(
cigogne@internal@database:get_url(),
fun(Url) ->
gleam@result:'try'(
cigogne@internal@database:connect(Url),
fun(Conn) ->
gleam@result:'try'(
apply_migration(Conn, migration_zero()),
fun(_) ->
gleam@result:'try'(
get_last_applied_migration(Conn),
fun(Last) ->
gleam_stdlib:println(
<<<<<<"Last applied migration: "/utf8,
(begin
_pipe = erlang:element(
3,
Last
),
tempo@naive_datetime:format(
_pipe,
<<"YYYYMMDDhhmmss"/utf8>>
)
end)/binary>>/binary,
"-"/utf8>>/binary,
(erlang:element(4, Last))/binary>>
),
gleam@result:'try'(
get_schema(Url),
fun(Schema) ->
gleam_stdlib:println(<<""/utf8>>),
gleam_stdlib:println(Schema),
{ok, nil}
end
)
end
)
end
)
end
)
end
).
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 249).
-spec roll_back_migration(pog:connection(), cigogne@types:migration()) -> {ok,
nil} |
{error, cigogne@types:migrate_error()}.
roll_back_migration(Connection, Migration) ->
gleam_stdlib:println(
<<<<<<"\nRolling back migration "/utf8,
(begin
_pipe = erlang:element(3, Migration),
tempo@naive_datetime:format(
_pipe,
<<"YYYYMMDDhhmmss"/utf8>>
)
end)/binary>>/binary,
"-"/utf8>>/binary,
(erlang:element(4, Migration))/binary>>
),
Queries = begin
_pipe@1 = gleam@list:map(
erlang:element(6, Migration),
fun pog:'query'/1
),
lists:append(
_pipe@1,
[begin
_pipe@2 = pog:'query'(
<<"DELETE FROM _migrations WHERE name = $1 AND createdAt = $2;"/utf8>>
),
_pipe@3 = pog:parameter(
_pipe@2,
pog_ffi:coerce(erlang:element(4, Migration))
),
pog:parameter(
_pipe@3,
pog:timestamp(
begin
_pipe@4 = erlang:element(3, Migration),
cigogne@internal@utils:tempo_to_pog_timestamp(
_pipe@4
)
end
)
)
end]
)
end,
_pipe@5 = cigogne@internal@database:execute_batch(
Connection,
Queries,
cigogne@internal@migrations:compare_migrations(
Migration,
migration_zero()
)
=:= eq
),
gleam@result:map(
_pipe@5,
fun(_) ->
gleam_stdlib:println(
<<<<<<"Migration rolled back : "/utf8,
(begin
_pipe@6 = erlang:element(3, Migration),
tempo@naive_datetime:format(
_pipe@6,
<<"YYYYMMDDhhmmss"/utf8>>
)
end)/binary>>/binary,
"-"/utf8>>/binary,
(erlang:element(4, Migration))/binary>>
)
end
).
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 150).
-spec roll_back_previous_migration(pog:connection()) -> {ok, nil} |
{error, cigogne@types:migrate_error()}.
roll_back_previous_migration(Connection) ->
gleam@result:'try'(
apply_migration_zero_if_not_applied(Connection),
fun(_) ->
gleam@result:'try'(
get_last_applied_migration(Connection),
fun(Last) ->
gleam@result:'try'(
cigogne@internal@fs:get_migrations(),
fun(Migs) ->
gleam@result:'try'(
cigogne@internal@migrations:find_migration(
Migs,
Last
),
fun(Migration) ->
roll_back_migration(Connection, Migration)
end
)
end
)
end
)
end
).
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 93).
-spec migrate_down() -> {ok, nil} | {error, cigogne@types:migrate_error()}.
migrate_down() ->
gleam@result:'try'(
cigogne@internal@database:get_url(),
fun(Url) ->
gleam@result:'try'(
cigogne@internal@database:connect(Url),
fun(Conn) ->
gleam@result:'try'(
roll_back_previous_migration(Conn),
fun(_) -> update_schema_file(Url) end
)
end
)
end
).
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 163).
-spec execute_n_migrations(pog:connection(), integer()) -> {ok, nil} |
{error, cigogne@types:migrate_error()}.
execute_n_migrations(Connection, Count) ->
gleam@result:'try'(
apply_migration_zero_if_not_applied(Connection),
fun(_) ->
gleam@result:'try'(
get_applied_migrations(Connection),
fun(Applied) ->
gleam@result:'try'(
cigogne@internal@fs:get_migrations(),
fun(Migs) ->
_pipe = cigogne@internal@migrations:find_n_migrations_to_apply(
Migs,
Applied,
Count
),
gleam@result:then(
_pipe,
fun(_capture) ->
gleam@list:try_each(
_capture,
fun(Migration) -> case Count > 0 of
true ->
apply_migration(
Connection,
Migration
);
false ->
roll_back_migration(
Connection,
Migration
)
end end
)
end
)
end
)
end
)
end
).
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 104).
-spec migrate_n(integer()) -> {ok, nil} | {error, cigogne@types:migrate_error()}.
migrate_n(Count) ->
gleam@result:'try'(
cigogne@internal@database:get_url(),
fun(Url) ->
gleam@result:'try'(
cigogne@internal@database:connect(Url),
fun(Conn) ->
gleam@result:'try'(
execute_n_migrations(Conn, Count),
fun(_) -> update_schema_file(Url) end
)
end
)
end
).
-file("/home/runner/work/cigogne/cigogne/src/cigogne.gleam", 39).
-spec main() -> {ok, nil} | {error, nil}.
main() ->
_pipe = case erlang:element(4, argv:load()) of
[<<"show"/utf8>>] ->
show();
[<<"up"/utf8>>] ->
migrate_up();
[<<"down"/utf8>>] ->
migrate_down();
[<<"last"/utf8>>] ->
migrate_to_last();
[<<"apply"/utf8>>, X] ->
case gleam_stdlib:parse_int(X) of
{error, _} ->
show_usage();
{ok, Mig} ->
migrate_n(Mig)
end;
[<<"new"/utf8>>, Name] ->
new_migration(Name);
_ ->
show_usage()
end,
gleam@result:map_error(_pipe, fun cigogne@types:print_migrate_error/1).