Skip to content

Commit de033bb

Browse files
committed
chore: fixes for dev migrations feature
1 parent a555bdc commit de033bb

File tree

1 file changed

+83
-6
lines changed

1 file changed

+83
-6
lines changed

lib/migration_generator/migration_generator.ex

Lines changed: 83 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)