Skip to content

Commit 17cb713

Browse files
authored
add composite FK support, onboard related tests, closes #103 (#104)
1 parent 6a1e6f4 commit 17cb713

File tree

3 files changed

+45
-6
lines changed

3 files changed

+45
-6
lines changed

integration_test/exqlite/test_helper.exs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ ExUnit.start(
111111
:remove_column_if_exists,
112112
:alter_primary_key,
113113
:alter_foreign_key,
114-
:composite_foreign_key,
115114
:assigns_id_type,
116115
:modify_column
117116
]

lib/ecto/adapters/exqlite/connection.ex

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ defmodule Ecto.Adapters.Exqlite.Connection do
332332
@impl true
333333
def execute_ddl({:create, %Table{} = table, columns}) do
334334
{table, composite_pk_def} = composite_pk_definition(table, columns)
335+
composite_fk_defs = composite_fk_definitions(table, columns)
335336

336337
[
337338
[
@@ -341,6 +342,7 @@ defmodule Ecto.Adapters.Exqlite.Connection do
341342
?(,
342343
column_definitions(table, columns),
343344
composite_pk_def,
345+
composite_fk_defs,
344346
?),
345347
options_expr(table.options)
346348
]
@@ -350,6 +352,7 @@ defmodule Ecto.Adapters.Exqlite.Connection do
350352
@impl true
351353
def execute_ddl({:create_if_not_exists, %Table{} = table, columns}) do
352354
{table, composite_pk_def} = composite_pk_definition(table, columns)
355+
composite_fk_defs = composite_fk_definitions(table, columns)
353356

354357
[
355358
[
@@ -359,6 +362,7 @@ defmodule Ecto.Adapters.Exqlite.Connection do
359362
?(,
360363
column_definitions(table, columns),
361364
composite_pk_def,
365+
composite_fk_defs,
362366
?),
363367
options_expr(table.options)
364368
]
@@ -1521,16 +1525,17 @@ defmodule Ecto.Adapters.Exqlite.Connection do
15211525

15221526
defp options_expr(options), do: [?\s, to_string(options)]
15231527

1524-
defp reference_expr(%Reference{} = ref, table, name) do
1525-
{_, reference_columns} = Enum.unzip([{name, ref.column} | ref.with])
1528+
# composite FK is handled at table level
1529+
defp reference_expr(%Reference{with: [_]}, _table, _name), do: []
15261530

1531+
defp reference_expr(%Reference{} = ref, table, name) do
15271532
[
15281533
" CONSTRAINT ",
15291534
reference_name(ref, table, name),
15301535
" REFERENCES ",
15311536
quote_table(ref.prefix || table.prefix, ref.table),
15321537
?(,
1533-
quote_names(reference_columns),
1538+
quote_name(ref.column),
15341539
?),
15351540
reference_on_delete(ref.on_delete),
15361541
reference_on_update(ref.on_update)
@@ -1597,6 +1602,35 @@ defmodule Ecto.Adapters.Exqlite.Connection do
15971602
end
15981603
end
15991604

1605+
defp composite_fk_definitions(%Table{} = table, columns) do
1606+
composite_fk_cols = columns
1607+
|> Enum.filter(fn c ->
1608+
case c do
1609+
{_op, _name, %Reference{with: [_]}, _opts} -> true
1610+
_ -> false
1611+
end
1612+
end)
1613+
1614+
Enum.map(composite_fk_cols, &composite_fk_definition(table, &1))
1615+
end
1616+
1617+
defp composite_fk_definition(table, {_op, name, ref, _opts}) do
1618+
{current_columns, reference_columns} = Enum.unzip([{name, ref.column} | ref.with])
1619+
1620+
[
1621+
", FOREIGN KEY (",
1622+
quote_names(current_columns),
1623+
") REFERENCES ",
1624+
quote_table(ref.prefix || table.prefix, ref.table),
1625+
?(,
1626+
quote_names(reference_columns),
1627+
?),
1628+
reference_on_delete(ref.on_delete),
1629+
reference_on_update(ref.on_update)
1630+
]
1631+
1632+
end
1633+
16001634
defp get_source(query, sources, ix, source) do
16011635
{expression, name, _schema} = elem(sources, ix)
16021636
{expression || expr(source, sources, query), name}

test/ecto/adapters/exqlite/connection_test.exs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,7 +2196,10 @@ defmodule Ecto.Adapters.Exqlite.ConnectionTest do
21962196
%Reference{table: :categories, prefix: :foo, on_delete: :nilify_all}, []},
21972197
{:add, :category_6,
21982198
%Reference{table: :categories, with: [here: :there], on_delete: :nilify_all},
2199-
[]}
2199+
[]},
2200+
{:add, :category_7,
2201+
%Reference{table: :tags, with: [that: :this], on_delete: :nilify_all},
2202+
[]},
22002203
]}
22012204

22022205
assert execute_ddl(create) == [
@@ -2209,7 +2212,10 @@ defmodule Ecto.Adapters.Exqlite.ConnectionTest do
22092212
category_3 INTEGER NOT NULL CONSTRAINT posts_category_3_fkey REFERENCES categories(id) ON DELETE CASCADE, \
22102213
category_4 INTEGER CONSTRAINT posts_category_4_fkey REFERENCES categories(id) ON DELETE SET NULL, \
22112214
category_5 INTEGER CONSTRAINT posts_category_5_fkey REFERENCES foo.categories(id) ON DELETE SET NULL, \
2212-
category_6 INTEGER CONSTRAINT posts_category_6_fkey REFERENCES categories(id,there) ON DELETE SET NULL\
2215+
category_6 INTEGER, \
2216+
category_7 INTEGER, \
2217+
FOREIGN KEY (category_6,here) REFERENCES categories(id,there) ON DELETE SET NULL, \
2218+
FOREIGN KEY (category_7,that) REFERENCES tags(id,this) ON DELETE SET NULL\
22132219
)\
22142220
"""
22152221
]

0 commit comments

Comments
 (0)