First cut of on conflict support

This commit is contained in:
Sean Corfield 2020-09-26 15:16:12 -07:00
parent 9154d73678
commit 25097af134
2 changed files with 22 additions and 0 deletions

View file

@ -21,6 +21,7 @@
:join :left-join :right-join :inner-join :outer-join :full-join :join :left-join :right-join :inner-join :outer-join :full-join
:cross-join :cross-join
:where :group-by :having :order-by :limit :offset :values :where :group-by :having :order-by :limit :offset :values
:on-conflict :on-constraint :do-nothing :do-update-set
:returning]) :returning])
(defn- add-clause-before (defn- add-clause-before
@ -297,6 +298,19 @@
xs)] xs)]
(into [(str (sql-kw k) " " (str/join ", " sqls))] params))) (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 (def ^:private base-clause-order
"The (base) order for known clauses. Can have items added and removed. "The (base) order for known clauses. Can have items added and removed.
@ -341,6 +355,10 @@
:limit #'format-on-expr :limit #'format-on-expr
:offset #'format-on-expr :offset #'format-on-expr
:values #'format-values :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})) :returning #'format-selects}))
(assert (= (set @base-clause-order) (assert (= (set @base-clause-order)

View file

@ -398,3 +398,7 @@
(format {:select [:*] (format {:select [:*]
:from [[:foo :f]] :from [[:foo :f]]
:cross-join [[:bar :b]]})))) :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}}))