Skip to content

Commit ccdc188

Browse files
committed
improvement: raise clearer error on unsupported foreign key drops in SQLite migrations
fixes #196
1 parent 78bd8d1 commit ccdc188

File tree

2 files changed

+86
-9
lines changed

2 files changed

+86
-9
lines changed

lib/migration_generator/operation.ex

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -366,10 +366,10 @@ defmodule AshSqlite.MigrationGenerator.Operation do
366366
# We only need to drop it before altering an attribute with `references/3`
367367
defstruct [:attribute, :table, :multitenancy, :direction, no_phase: true]
368368

369-
import Helper
370-
371369
def up(%{table: table, attribute: %{references: reference}, direction: :up}) do
372-
"drop constraint(:#{as_atom(table)}, #{join([inspect(reference.name)])})"
370+
~s[raise "SQLite does not support dropping foreign key constraints. " <>
371+
"You will need to manually recreate the `#{table}` table without the `#{reference.name}` constraint. " <>
372+
"See https://www.techonthenet.com/sqlite/foreign_keys/drop.php for guidance."]
373373
end
374374

375375
def up(_) do
@@ -381,7 +381,9 @@ defmodule AshSqlite.MigrationGenerator.Operation do
381381
attribute: %{references: reference},
382382
direction: :down
383383
}) do
384-
"drop constraint(:#{as_atom(table)}, #{join([inspect(reference.name)])})"
384+
~s[raise "SQLite does not support dropping foreign key constraints. " <>
385+
"You will need to manually recreate the `#{table}` table without the `#{reference.name}` constraint. " <>
386+
"See https://www.techonthenet.com/sqlite/foreign_keys/drop.php for guidance."]
385387
end
386388

387389
def down(_) do

test/migration_generator_test.exs

Lines changed: 80 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -740,14 +740,86 @@ defmodule AshSqlite.MigrationGeneratorTest do
740740
assert file =~
741741
~S[references(:posts, column: :id, name: "special_post_fkey", type: :uuid, on_delete: :delete_all, on_update: :update_all)]
742742

743-
assert file =~ ~S[drop constraint(:posts, "posts_post_id_fkey")]
743+
assert file =~ ~S[raise "SQLite does not support dropping foreign key constraints.]
744+
assert file =~ ~S[posts_post_id_fkey]
744745

745746
assert [_, down_code] = String.split(file, "def down do")
746747

747-
assert [_, after_drop] =
748-
String.split(down_code, "drop constraint(:posts, \"special_post_fkey\")")
748+
assert down_code =~ ~S[raise "SQLite does not support dropping foreign key constraints.]
749+
assert down_code =~ ~S[special_post_fkey]
750+
assert down_code =~ ~S[references(:posts]
751+
end
752+
753+
test "dropping foreign keys raises with guidance since SQLite doesn't support it" do
754+
defposts do
755+
attributes do
756+
uuid_primary_key(:id)
757+
attribute(:title, :string)
758+
end
759+
end
760+
761+
defposts Post2 do
762+
attributes do
763+
uuid_primary_key(:id)
764+
attribute(:name, :string)
765+
end
766+
767+
relationships do
768+
belongs_to(:post, Post)
769+
end
770+
end
771+
772+
defdomain([Post, Post2])
773+
774+
AshSqlite.MigrationGenerator.generate(Domain,
775+
snapshot_path: "test_snapshots_path",
776+
migration_path: "test_migration_path",
777+
quiet: true,
778+
format: false,
779+
auto_name: true
780+
)
781+
782+
# Modify the reference to trigger constraint modification
783+
defposts Post2 do
784+
sqlite do
785+
references do
786+
reference(:post, name: "new_post_fkey", on_delete: :delete)
787+
end
788+
end
789+
790+
attributes do
791+
uuid_primary_key(:id)
792+
attribute(:name, :string)
793+
end
794+
795+
relationships do
796+
belongs_to(:post, Post)
797+
end
798+
end
749799

750-
assert after_drop =~ ~S[references(:posts]
800+
AshSqlite.MigrationGenerator.generate(Domain,
801+
snapshot_path: "test_snapshots_path",
802+
migration_path: "test_migration_path",
803+
quiet: true,
804+
format: false,
805+
auto_name: true
806+
)
807+
808+
assert [_file1, file2] =
809+
Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs"))
810+
811+
file_contents = File.read!(file2)
812+
813+
# Up migration should raise with helpful message
814+
assert file_contents =~ ~S[raise "SQLite does not support dropping foreign key constraints.]
815+
assert file_contents =~ ~S[posts_post_id_fkey]
816+
assert file_contents =~ ~S[https://www.techonthenet.com/sqlite/foreign_keys/drop.php]
817+
818+
# Down migration should also raise
819+
[_, down_code] = String.split(file_contents, "def down do")
820+
821+
assert down_code =~ ~S[raise "SQLite does not support dropping foreign key constraints.]
822+
assert down_code =~ ~S[new_post_fkey]
751823
end
752824
end
753825

@@ -961,7 +1033,10 @@ defmodule AshSqlite.MigrationGeneratorTest do
9611033
assert [before_index_drop, after_index_drop] =
9621034
String.split(file, ~S[drop constraint("posts", "posts_pkey")], parts: 2)
9631035

964-
assert before_index_drop =~ ~S[drop constraint(:comments, "comments_post_id_fkey")]
1036+
assert before_index_drop =~
1037+
~S[raise "SQLite does not support dropping foreign key constraints.]
1038+
1039+
assert before_index_drop =~ ~S[comments_post_id_fkey]
9651040

9661041
assert after_index_drop =~ ~S[modify :id, :uuid, null: true, primary_key: false]
9671042

0 commit comments

Comments
 (0)