fix: go back to old migration sorting algorithm

closes: #139
This commit is contained in:
Zach Daniel 2023-05-01 10:51:09 -04:00
parent a0fc28a503
commit cd821cc153
2 changed files with 74 additions and 57 deletions

View file

@ -1125,69 +1125,68 @@ defmodule AshPostgres.MigrationGenerator do
group_into_phases(operations, nil, [phase | acc])
end
defp sort_operations(ops) do
digraph = :digraph.new()
defp sort_operations(ops, acc \\ [])
defp sort_operations([], acc), do: acc
ops
|> Enum.each(fn op ->
:digraph.add_vertex(digraph, op)
end)
defp sort_operations([op | rest], []), do: sort_operations(rest, [op])
ops
|> Enum.each(fn left ->
ops
|> Enum.each(fn right ->
if left != right do
left_before_right? = after?(right, left)
left_after_right? = after?(left, right)
defp sort_operations([op | rest], acc) do
acc = Enum.reverse(acc)
cond do
# They can't both be after eachother
left_before_right? && left_after_right? ->
:ok
after_index = Enum.find_index(acc, &after?(op, &1))
left_before_right? ->
:digraph.add_edge(digraph, left, right)
new_acc =
if after_index do
acc
|> List.insert_at(after_index, op)
|> Enum.reverse()
else
[op | Enum.reverse(acc)]
end
left_after_right? ->
:digraph.add_edge(digraph, right, left)
true ->
:ok
end
end
end)
end)
transformers = walk_rest(digraph)
:digraph.delete(digraph)
transformers
sort_operations(rest, new_acc)
end
defp walk_rest(digraph, acc \\ []) do
case :digraph.vertices(digraph) do
[] ->
Enum.reverse(acc)
# defp sort_operations(ops) do
vertices ->
case Enum.find(vertices, &(:digraph.in_neighbours(digraph, &1) == [])) do
nil ->
case Enum.find(vertices, &(:digraph.out_neighbours(digraph, &1) == [])) do
nil ->
raise "Cycle detected in migration operator order"
# digraph = :digraph.new()
vertex ->
:digraph.del_vertex(digraph, vertex)
walk_rest(digraph, acc ++ [vertex])
end
# ops
# |> Enum.each(fn op ->
# :digraph.add_vertex(digraph, op)
# end)
vertex ->
:digraph.del_vertex(digraph, vertex)
walk_rest(digraph, [vertex | acc])
end
end
end
# ops
# |> Enum.each(fn left ->
# ops
# |> Enum.each(fn right ->
# if left != right do
# left_before_right? = after?(right, left)
# left_after_right? = after?(left, right)
# cond do
# # They can't both be after eachother
# left_before_right? && left_after_right? ->
# :ok
# left_before_right? ->
# :digraph.add_edge(digraph, left, right)
# left_after_right? ->
# :digraph.add_edge(digraph, right, left)
# true ->
# :ok
# end
# end
# end)
# end)
# transformers = walk_rest(digraph)
# :digraph.delete(digraph)
# transformers
# end
defp after?(
%Operation.RemovePrimaryKey{},
@ -1383,6 +1382,16 @@ defmodule AshPostgres.MigrationGenerator do
}),
do: true
defp after?(
%Operation.AlterAttribute{table: table, schema: schema},
%Operation.DropForeignKey{
table: table,
schema: schema,
direction: :down
}
),
do: false
defp after?(
%Operation.DropForeignKey{
table: table,

View file

@ -811,11 +811,19 @@ defmodule AshPostgres.MigrationGeneratorTest do
|> Path.wildcard()
|> Enum.sort()
|> Enum.at(1)
|> File.read!()
assert File.read!(file) =~
~S[references(:posts, column: :id, prefix: "public", name: "special_post_fkey", type: :uuid, on_delete: :delete_all, on_update: :update_all)]
assert file =~
~S[references(:posts, column: :id, name: "special_post_fkey", type: :uuid, prefix: "public", on_delete: :delete_all, on_update: :update_all)]
assert File.read!(file) =~ ~S[drop constraint(:posts, "posts_post_id_fkey")]
assert file =~ ~S[drop constraint(:posts, "posts_post_id_fkey")]
assert [_, down_code] = String.split(file, "def down do")
assert [_, after_drop] =
String.split(down_code, "drop constraint(:posts, \"special_post_fkey\")")
assert after_drop =~ ~S[references(:posts]
end
end
@ -1217,7 +1225,7 @@ defmodule AshPostgres.MigrationGeneratorTest do
assert after_index_drop =~ ~S[modify :id, :uuid, null: true, primary_key: false]
assert after_index_drop =~
~S[modify :post_id, references(:posts, column: :id, prefix: "public", name: "comments_post_id_fkey", type: :uuid)]
~S[modify :post_id, references(:posts, column: :id, name: "comments_post_id_fkey", type: :uuid, prefix: "public")]
end
end
end