-module(migrant@filesystem). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([load_migration_files/2]). -spec is_directory( binary(), fun((binary()) -> {ok, nil} | {error, migrant@types:error()}) ) -> {ok, nil} | {error, migrant@types:error()}. is_directory(Path, Next) -> case simplifile:is_directory(Path) of true -> Next(Path); false -> {error, expected_folder_error} end. -spec list_files( binary(), fun((list(binary())) -> {ok, nil} | {error, migrant@types:error()}) ) -> {ok, nil} | {error, migrant@types:error()}. list_files(Path, Next) -> case simplifile:read_directory(Path) of {ok, Files} -> Next(Files); {error, E} -> {error, {file_error, E}} end. -spec read_file(binary(), binary()) -> gleam@option:option(binary()). read_file(Path, Filename) -> Filepath = case gleam@string:ends_with(Path, <<"/"/utf8>>) of true -> <>; false -> <<<>/binary, Filename/binary>> end, case simplifile:read(Filepath) of {ok, Contents} -> {some, gleam@string:trim(Contents)}; {error, _} -> none end. -spec parse_files( binary(), list(binary()), gleam@dict:dict(binary(), migrant@types:migration()) ) -> {ok, gleam@dict:dict(binary(), migrant@types:migration())} | {error, migrant@types:error()}. parse_files(Migrations_dir, Files, Migrations) -> case Files of [] -> {ok, Migrations}; [File | Rest] -> Res = case begin _pipe = File, gleam@string:split(_pipe, <<"."/utf8>>) end of [Name, Direction, <<"sql"/utf8>>] -> migrant@lib:validate_direction( Direction, fun(Direction@1) -> migrant@lib:get_or_make_migration( Name, Migrations, fun(Migration) -> Sql = read_file(Migrations_dir, File), Migration@1 = case Direction@1 of <<"up"/utf8>> -> erlang:setelement(2, Migration, Sql); <<"down"/utf8>> -> erlang:setelement(3, Migration, Sql) end, {ok, {Name, Migration@1}} end ) end ); _ -> {error, {extraction_error, <<<<"Failed to extract up/down from "/utf8, File/binary>>/binary, ". Migration files must be named in the format ..sql e.g 00001_create_users.up.sql"/utf8>>}} end, case Res of {ok, {Name@1, Migration@2}} -> Migrations@1 = gleam@dict:insert( Migrations, Name@1, Migration@2 ), parse_files(Migrations_dir, Rest, Migrations@1); {error, E} -> {error, E} end end. -spec load_migration_files( binary(), fun((gleam@dict:dict(binary(), migrant@types:migration())) -> {ok, nil} | {error, migrant@types:error()}) ) -> {ok, nil} | {error, migrant@types:error()}. load_migration_files(Migrations_dir, Next) -> gleam@io:println( <<"-> Loading migrations from "/utf8, Migrations_dir/binary>> ), is_directory( Migrations_dir, fun(Migrations_dir@1) -> list_files( Migrations_dir@1, fun(Files) -> case parse_files(Migrations_dir@1, Files, gleam@dict:new()) of {ok, Migrations} -> Next(Migrations); {error, E} -> {error, E} end end ) end ).