Skip to content

Commit 2441ea2

Browse files
committed
merge on_conflict changes
1 parent 580381f commit 2441ea2

File tree

2 files changed

+32
-30
lines changed

2 files changed

+32
-30
lines changed

integration_test/test_helper.exs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,6 @@ ExUnit.start(
102102
# that converts the string JSON representaiton into a map
103103
:map_type_schemaless,
104104

105-
# we should be able to fully/correctly support these, but don't currently
106-
:with_conflict_target,
107-
:without_conflict_target,
108-
109105
# right now in lock_for_migrations() we do effectively nothing, this is because
110106
# SQLite is single-writer so there isn't really a need for us to do anything.
111107
# ecto assumes all implementing adapters need >=2 connections for migrations

lib/ecto/adapters/sqlite3/connection.ex

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,11 @@ defmodule Ecto.Adapters.SQLite3.Connection do
242242
insert(prefix, table, header, rows, on_conflict, returning, [])
243243
end
244244

245-
def insert(prefix, table, [], [[]], _on_conflict, returning, []) do
245+
def insert(prefix, table, [], [[]], on_conflict, returning, []) do
246246
[
247247
"INSERT INTO ",
248248
quote_table(prefix, table),
249+
insert_as(on_conflict),
249250
" DEFAULT VALUES",
250251
returning(returning)
251252
]
@@ -256,6 +257,7 @@ defmodule Ecto.Adapters.SQLite3.Connection do
256257
[
257258
"INSERT INTO ",
258259
quote_table(prefix, table),
260+
insert_as(on_conflict),
259261
" (",
260262
fields,
261263
") ",
@@ -639,49 +641,45 @@ defmodule Ecto.Adapters.SQLite3.Connection do
639641
## Query generation
640642
##
641643

642-
def on_conflict({:raise, _, []}, _header), do: []
644+
defp on_conflict({:raise, _, []}, _header), do: []
643645

644-
def on_conflict({:nothing, _, targets}, _header) do
646+
defp on_conflict({:nothing, _, targets}, _header) do
645647
[" ON CONFLICT ", conflict_target(targets) | "DO NOTHING"]
646648
end
647649

648-
def on_conflict({:replace_all, _, []}, _header) do
650+
defp on_conflict({:replace_all, _, {:constraint, _}}, _header) do
651+
raise ArgumentError, "Upsert in SQLite3 does not support ON CONSTRAINT"
652+
end
653+
654+
defp on_conflict({:replace_all, _, []}, _header) do
649655
raise ArgumentError, "Upsert in SQLite3 requires :conflict_target"
650656
end
651657

652-
def on_conflict({:replace_all, _, {:constraint, _}}, _header) do
653-
raise ArgumentError, "Upsert in SQLite3 does not support ON CONSTRAINT"
658+
defp on_conflict({:replace_all, _, targets}, header) do
659+
[" ON CONFLICT ", conflict_target(targets), "DO " | replace(header)]
654660
end
655661

656-
def on_conflict({:replace_all, _, targets}, header) do
657-
[
658-
" ON CONFLICT ",
659-
conflict_target(targets),
660-
"DO " | replace_all(header)
661-
]
662+
defp on_conflict({fields, _, targets}, _header) when is_list(fields) do
663+
[" ON CONFLICT ", conflict_target(targets), "DO " | replace(fields)]
662664
end
663665

664-
def on_conflict({query, _, targets}, _header) do
665-
[
666-
" ON CONFLICT ",
667-
conflict_target(targets),
668-
"DO " | update_all(query, "UPDATE SET ")
669-
]
666+
defp on_conflict({query, _, targets}, _header) do
667+
[" ON CONFLICT ", conflict_target(targets), "DO " | update_all(query, "UPDATE SET ")]
670668
end
671669

672-
def conflict_target([]), do: ""
670+
defp conflict_target([]), do: ""
673671

674-
def conflict_target(targets) do
672+
defp conflict_target(targets) do
675673
[?(, intersperse_map(targets, ?,, &quote_name/1), ?), ?\s]
676674
end
677675

678-
def replace_all(header) do
676+
defp replace(fields) do
679677
[
680-
"UPDATE SET "
681-
| intersperse_map(header, ?,, fn field ->
682-
quoted = quote_name(field)
683-
[quoted, " = ", "EXCLUDED." | quoted]
684-
end)
678+
"UPDATE SET " |
679+
intersperse_map(fields, ?,, fn field ->
680+
quoted = quote_name(field)
681+
[quoted, " = ", "EXCLUDED." | quoted]
682+
end)
685683
]
686684
end
687685

@@ -721,6 +719,14 @@ defmodule Ecto.Adapters.SQLite3.Connection do
721719
end)
722720
end
723721

722+
defp insert_as({%{sources: sources}, _, _}) do
723+
{_expr, name, _schema} = create_name(sources, 0, [])
724+
[" AS " | name]
725+
end
726+
defp insert_as({_, _, _}) do
727+
[]
728+
end
729+
724730
binary_ops = [
725731
==: " = ",
726732
!=: " != ",

0 commit comments

Comments
 (0)