From 25097af134e9c441076a295b98054c154f53af7e Mon Sep 17 00:00:00 2001 From: Sean Corfield Date: Sat, 26 Sep 2020 15:16:12 -0700 Subject: [PATCH] First cut of on conflict support --- src/honey/sql.cljc | 18 ++++++++++++++++++ test/honey/sql_test.cljc | 4 ++++ 2 files changed, 22 insertions(+) diff --git a/src/honey/sql.cljc b/src/honey/sql.cljc index 17f21b9..4a0ed91 100644 --- a/src/honey/sql.cljc +++ b/src/honey/sql.cljc @@ -21,6 +21,7 @@ :join :left-join :right-join :inner-join :outer-join :full-join :cross-join :where :group-by :having :order-by :limit :offset :values + :on-conflict :on-constraint :do-nothing :do-update-set :returning]) (defn- add-clause-before @@ -297,6 +298,19 @@ xs)] (into [(str (sql-kw k) " " (str/join ", " sqls))] params))) +(defn- format-on-conflict [k x] + (if (keyword? x) + [(str (sql-kw k) " (" (format-entity x) ")")] + (let [[sql & params] (format-dsl x)] + (into [(str (sql-kw k) " " sql)] params)))) + +(defn- format-do-update-set [k x] + (if (keyword? x) + (let [e (format-entity x {:drop-ns? true})] + [(str (sql-kw k) " " e " = EXCLUDED." e)]) + (let [[sql & params] (format-set-exprs :set x)] + (into [(str (sql-kw k) " " sql)] params)))) + (def ^:private base-clause-order "The (base) order for known clauses. Can have items added and removed. @@ -341,6 +355,10 @@ :limit #'format-on-expr :offset #'format-on-expr :values #'format-values + :on-conflict #'format-on-conflict + :on-constraint #'format-selector + :do-nothing (fn [k _] (vector (sql-kw k))) + :do-update-set #'format-do-update-set :returning #'format-selects})) (assert (= (set @base-clause-order) diff --git a/test/honey/sql_test.cljc b/test/honey/sql_test.cljc index e39f323..1401019 100644 --- a/test/honey/sql_test.cljc +++ b/test/honey/sql_test.cljc @@ -398,3 +398,7 @@ (format {:select [:*] :from [[:foo :f]] :cross-join [[:bar :b]]})))) + +(comment ; make on conflict tests, based on nilenso repo and PG docs + (format {:insert-into :foo, :values [[1 2 3]], :on-conflict :e :do-nothing true}) + (format {:insert-into :foo, :values [[1 2 3]], :on-conflict {:on-constraint :foo_key} :do-update-set {:a 42 :b :excluded.b}}))