-module(gorrion@loader). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/gorrion/loader.gleam"). -export([load_migrations/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " Loads migration SQL files from disk.\n" " Convention: {NNN}_{name}.sql (up) / {NNN}_{name}_down.sql (optional rollback)\n" ). -file("src/gorrion/loader.gleam", 43). -spec parse_migration(binary(), binary()) -> {ok, gorrion@types:migration()} | {error, gorrion@types:migration_error()}. parse_migration(Directory, Filename) -> Base = gleam@string:drop_end(Filename, string:length(<<".sql"/utf8>>)), Down_filename = <>, case gleam@string:split_once(Base, <<"_"/utf8>>) of {error, _} -> {error, {file_error, <<"Invalid migration filename: "/utf8, Filename/binary>>}}; {ok, {Version_str, Name}} -> case gleam_stdlib:parse_int(Version_str) of {error, _} -> {error, {file_error, <<"Invalid version number in filename: "/utf8, Filename/binary>>}}; {ok, Version} -> Up_path = <<<>/binary, Filename/binary>>, Down_path = <<<>/binary, Down_filename/binary>>, case simplifile:read(Up_path) of {error, E} -> {error, {file_error, <<<<<<"Cannot read "/utf8, Up_path/binary>>/binary, ": "/utf8>>/binary, (gleam@string:inspect(E))/binary>>}}; {ok, Up_sql} -> Down_sql = case simplifile:read(Down_path) of {ok, Sql} -> Sql; {error, _} -> <<""/utf8>> end, {ok, {migration, Version, Name, Up_sql, Down_sql}} end end end. -file("src/gorrion/loader.gleam", 14). ?DOC( " Load all migrations from .sql files in the given directory.\n" " Scans for *.sql files (excluding *_down.sql), and optionally pairs\n" " each with a *_down.sql companion. If no down file exists, down = \"\".\n" ). -spec load_migrations(binary()) -> {ok, list(gorrion@types:migration())} | {error, gorrion@types:migration_error()}. load_migrations(Directory) -> case simplifile_erl:read_directory(Directory) of {error, E} -> {error, {file_error, <<<<<<"Cannot read migrations directory '"/utf8, Directory/binary>>/binary, "': "/utf8>>/binary, (gleam@string:inspect(E))/binary>>}}; {ok, Files} -> Up_files = begin _pipe = Files, _pipe@1 = gleam@list:filter( _pipe, fun(F) -> gleam_stdlib:string_ends_with(F, <<".sql"/utf8>>) andalso not gleam_stdlib:string_ends_with( F, <<"_down.sql"/utf8>> ) end ), gleam@list:sort(_pipe@1, fun gleam@string:compare/2) end, _pipe@2 = Up_files, _pipe@3 = gleam@list:try_map( _pipe@2, fun(F@1) -> parse_migration(Directory, F@1) end ), gleam@result:map( _pipe@3, fun(Migrations) -> gleam@list:sort( Migrations, fun(A, B) -> gleam@int:compare( erlang:element(2, A), erlang:element(2, B) ) end ) end ) end.