@@ -381,15 +381,64 @@ defmodule AshSqlite.MigrationGenerator do
381381 end
382382 end
383383
384+ if Mix . env ( ) == :test do
385+ defp with_repo_not_in_test ( repo , fun ) do
386+ fun . ( repo )
387+ end
388+ else
389+ defp with_repo_not_in_test ( repo , fun ) do
390+ Ecto.Migrator . with_repo ( repo , fun )
391+ end
392+ end
393+
384394 defp remove_dev_migrations_and_snapshots ( dev_migrations , repo , opts , snapshots ) do
385- # Remove dev migration files
386- Enum . each ( dev_migrations , fn migration_name ->
387- opts
388- |> migration_path ( repo )
389- |> Path . join ( migration_name )
390- |> File . rm! ( )
395+ dev_migrations =
396+ Enum . map ( dev_migrations , fn migration ->
397+ opts
398+ |> migration_path ( repo )
399+ |> Path . join ( migration )
400+ end )
401+
402+ with_repo_not_in_test ( repo , fn repo ->
403+ { repo , query , opts } = Ecto.Migration.SchemaMigration . versions ( repo , [ ] , nil )
404+
405+ repo . transaction ( fn ->
406+ Ecto.Migration.SchemaMigration . ensure_schema_migrations_table! (
407+ repo ,
408+ repo . config ( ) ,
409+ [ ]
410+ )
411+
412+ versions = repo . all ( query , opts )
413+
414+ dev_migrations
415+ |> Enum . map ( & extract_migration_info / 1 )
416+ |> Enum . filter ( & & 1 )
417+ |> Enum . map ( & load_migration! / 1 )
418+ |> Enum . sort ( )
419+ |> Enum . filter ( fn { version , _ } ->
420+ version in versions
421+ end )
422+ |> Enum . each ( fn { version , mod } ->
423+ Ecto.Migration.Runner . run (
424+ repo ,
425+ [ ] ,
426+ version ,
427+ mod ,
428+ :forward ,
429+ :down ,
430+ :down ,
431+ all: true
432+ )
433+
434+ Ecto.Migration.SchemaMigration . down ( repo , repo . config ( ) , version , [ ] )
435+ end )
436+ end )
391437 end )
392438
439+ # Remove dev migration files
440+ Enum . each ( dev_migrations , & File . rm! ( & 1 ) )
441+
393442 # Remove dev snapshots
394443 Enum . each ( snapshots , fn snapshot ->
395444 snapshot_folder =
@@ -411,6 +460,34 @@ defmodule AshSqlite.MigrationGenerator do
411460 end )
412461 end
413462
463+ defp load_migration! ( { version , _ , file } ) when is_binary ( file ) do
464+ loaded_modules = file |> compile_file ( ) |> Enum . map ( & elem ( & 1 , 0 ) )
465+
466+ if mod = Enum . find ( loaded_modules , & migration? / 1 ) do
467+ { version , mod }
468+ else
469+ raise Ecto.MigrationError ,
470+ "file #{ Path . relative_to_cwd ( file ) } does not define an Ecto.Migration"
471+ end
472+ end
473+
474+ defp compile_file ( file ) do
475+ Code . compile_file ( file )
476+ end
477+
478+ defp migration? ( mod ) do
479+ function_exported? ( mod , :__migration__ , 0 )
480+ end
481+
482+ defp extract_migration_info ( file ) do
483+ base = Path . basename ( file )
484+
485+ case Integer . parse ( Path . rootname ( base ) ) do
486+ { integer , "_" <> name } -> { integer , name , file }
487+ _ -> nil
488+ end
489+ end
490+
414491 defp add_order_to_operations ( { snapshot , operations } ) do
415492 operations_with_order = Enum . map ( operations , & add_order_to_operation ( & 1 , snapshot . attributes ) )
416493
0 commit comments