From 28a4074e12a2292f01763ac8b28aca4c4df578c0 Mon Sep 17 00:00:00 2001 From: Sean Corfield Date: Mon, 15 Feb 2021 20:43:53 -0800 Subject: [PATCH] Add flexibility for on conflict / on constraint --- doc/clause-reference.md | 9 +++++++++ doc/postgresql.md | 19 +++++++++++++++---- src/honey/sql/helpers.cljc | 2 +- test/honey/sql_test.cljc | 15 +++++++++++++++ 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/doc/clause-reference.md b/doc/clause-reference.md index 8b3cc38..09aaca6 100644 --- a/doc/clause-reference.md +++ b/doc/clause-reference.md @@ -633,6 +633,8 @@ of a SQL entity and a SQL clause. The SQL entity is a column name and the SQL clause can be an `:on-constraint` clause or a`:where` clause. +_[For convenience of use with the `on-conflict` helper, this clause can also accept any of those arguments, wrapped in a sequence; it can also accept an empty sequence, and just produce `ON CONFLICT`, so that it can be combined with other clauses directly]_ + `:on-constraint` accepts a single SQL entity that identifies a constraint name. @@ -676,6 +678,13 @@ user=> (sql/format {:insert-into :companies :on-conflict {:on-constraint :name-idx} :do-nothing true}) ["INSERT INTO companies (name) VALUES (?) ON CONFLICT ON CONSTRAINT name_idx DO NOTHING" "Microsoft"] +;; empty :on-conflict combined with :on-constraint clause: +user=> (sql/format {:insert-into :companies + :values [{:name "Microsoft"}] + :on-conflict [] + :on-constraint :name-idx + :do-nothing true}) +["INSERT INTO companies (name) VALUES (?) ON CONFLICT ON CONSTRAINT name_idx DO NOTHING" "Microsoft"] ``` ## returning diff --git a/doc/postgresql.md b/doc/postgresql.md index 00fce7a..d5c2892 100644 --- a/doc/postgresql.md +++ b/doc/postgresql.md @@ -57,7 +57,7 @@ user=> (-> (insert-into :distributors) (values [{:did 7 :dname "Redline GmbH"}]) (upsert (-> (on-conflict :did) do-nothing)) - sql/format))) + sql/format) ;; newlines inserted for readability: ["INSERT INTO distributors (did, dname) VALUES (?, ?) ON CONFLICT (did) DO NOTHING" @@ -71,7 +71,7 @@ user=> (-> (insert-into :distributors) (values [{:did 7 :dname "Redline GmbH"}]) (on-conflict :did) do-nothing - sql/format))) + sql/format) ;; newlines inserted for readability: ["INSERT INTO distributors (did, dname) VALUES (?, ?) ON CONFLICT (did) DO NOTHING" @@ -86,7 +86,18 @@ user=> (-> (insert-into :distributors) ;; nilenso used (on-conflict-constraint :distributors_pkey) here: (on-conflict (on-constraint :distributors_pkey)) do-nothing - sql/format))) + sql/format) +;; newlines inserted for readability: +["INSERT INTO distributors (did, dname) VALUES (?, ?) + ON CONFLICT ON CONSTRAINT distributors_pkey DO NOTHING" + 9 "Antwerp Design"] +user=> (-> (insert-into :distributors) + (values [{:did 9 :dname "Antwerp Design"}]) + ;; nilenso used (on-conflict-constraint :distributors_pkey) here: + on-conflict + (on-constraint :distributors_pkey) + do-nothing + sql/format) ;; newlines inserted for readability: ["INSERT INTO distributors (did, dname) VALUES (?, ?) ON CONFLICT ON CONSTRAINT distributors_pkey DO NOTHING" @@ -285,4 +296,4 @@ not supported by the nilenso library: ``` -## Window / Partition Support \ No newline at end of file +## Window / Partition Support diff --git a/src/honey/sql/helpers.cljc b/src/honey/sql/helpers.cljc index f23d7e8..bae9616 100644 --- a/src/honey/sql/helpers.cljc +++ b/src/honey/sql/helpers.cljc @@ -486,7 +486,7 @@ "Accepts a single constraint name." {:arglists '([constraint])} [& args] - (generic :on-constraint args)) + (generic-1 :on-constraint args)) (defn do-nothing "Called with no arguments, produces DO NOTHING" diff --git a/test/honey/sql_test.cljc b/test/honey/sql_test.cljc index 3ba5a5f..3337cd8 100644 --- a/test/honey/sql_test.cljc +++ b/test/honey/sql_test.cljc @@ -534,6 +534,21 @@ DO NOTHING INSERT INTO customers (name, email) VALUES ('Microsoft', 'hotline@microsoft.com') +ON CONFLICT +ON CONSTRAINT customers_name_key +DO NOTHING +"] + (format {:insert-into :customers + :columns [:name :email] + :values [[[:inline "Microsoft"], [:inline "hotline@microsoft.com"]]] + :on-conflict [] + :on-constraint :customers_name_key + :do-nothing true} + {:pretty true}))) + (is (= [" +INSERT INTO customers +(name, email) +VALUES ('Microsoft', 'hotline@microsoft.com') ON CONFLICT (name) DO NOTHING "]