fix #494 by supporting expressions in on conflict
This commit is contained in:
parent
3ec884f881
commit
290537c581
4 changed files with 23 additions and 18 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
* 2.4.next in progress
|
* 2.4.next in progress
|
||||||
|
* Fix [#494](https://github.com/seancorfield/honeysql/issues/494) by supporting expressions in `:on-conflict` instead of just entities.
|
||||||
* Address [#493](https://github.com/seancorfield/honeysql/issues/493) by clarifying use of `:values` in CTEs (using `:with`).
|
* Address [#493](https://github.com/seancorfield/honeysql/issues/493) by clarifying use of `:values` in CTEs (using `:with`).
|
||||||
* Address [#489](https://github.com/seancorfield/honeysql/issues/489) by adding more examples around `:update`.
|
* Address [#489](https://github.com/seancorfield/honeysql/issues/489) by adding more examples around `:update`.
|
||||||
* Update dev/test dependencies.
|
* Update dev/test dependencies.
|
||||||
|
|
|
||||||
|
|
@ -1099,10 +1099,11 @@ as if they are separate clauses but they will appear
|
||||||
in pairs: `ON ... DO ...`.
|
in pairs: `ON ... DO ...`.
|
||||||
|
|
||||||
`:on-conflict` accepts a sequence of zero or more
|
`:on-conflict` accepts a sequence of zero or more
|
||||||
SQL entities (keywords or symbols), optionally
|
SQL expressions, optionally
|
||||||
followed by a single SQL clause (hash map). It can also
|
followed by a single SQL clause (hash map). It can also
|
||||||
accept either a single SQL entity or a single SQL clause.
|
accept either a single SQL entity or a single SQL clause.
|
||||||
The SQL entities are column names and the SQL clause can be an
|
The SQL expressions can be just column names or function calls etc,
|
||||||
|
and the SQL clause can be an
|
||||||
`:on-constraint` clause or a`:where` clause.
|
`: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]_
|
_[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]_
|
||||||
|
|
|
||||||
|
|
@ -881,23 +881,26 @@
|
||||||
|
|
||||||
(defn- format-on-conflict [k x]
|
(defn- format-on-conflict [k x]
|
||||||
(if (sequential? x)
|
(if (sequential? x)
|
||||||
(let [entities (take-while ident? x)
|
(let [exprs (take-while (complement map?) x)
|
||||||
n (count entities)
|
n (count exprs)
|
||||||
[clause & more] (drop n x)
|
[clause & more] (drop n x)
|
||||||
_ (when (or (seq more)
|
_ (when (seq more)
|
||||||
(and clause (not (map? clause))))
|
|
||||||
(throw (ex-info "unsupported :on-conflict format"
|
(throw (ex-info "unsupported :on-conflict format"
|
||||||
{:clause x})))
|
{:clause x})))
|
||||||
[sql & params] (when clause
|
[sqls expr-params]
|
||||||
(format-dsl clause))]
|
(when (seq exprs)
|
||||||
(into [(str (sql-kw k)
|
(format-expr-list exprs))
|
||||||
(when (pos? n)
|
[sql & clause-params]
|
||||||
(str " ("
|
(when clause
|
||||||
(str/join ", " (map #'format-entity entities))
|
(format-dsl clause))]
|
||||||
")"))
|
|
||||||
(when sql
|
(-> [(str (sql-kw k)
|
||||||
(str " " sql)))]
|
(when (pos? n)
|
||||||
params))
|
(str " (" (str/join ", " sqls) ")"))
|
||||||
|
(when sql
|
||||||
|
(str " " sql)))]
|
||||||
|
(into expr-params)
|
||||||
|
(into clause-params)))
|
||||||
(format-on-conflict k [x])))
|
(format-on-conflict k [x])))
|
||||||
|
|
||||||
(defn- format-do-update-set [k x]
|
(defn- format-do-update-set [k x]
|
||||||
|
|
|
||||||
|
|
@ -772,13 +772,13 @@ DO NOTHING
|
||||||
INSERT INTO customers
|
INSERT INTO customers
|
||||||
(name, email)
|
(name, email)
|
||||||
VALUES ('Microsoft', 'hotline@microsoft.com')
|
VALUES ('Microsoft', 'hotline@microsoft.com')
|
||||||
ON CONFLICT (name, email)
|
ON CONFLICT (name, TRIM(email))
|
||||||
DO NOTHING
|
DO NOTHING
|
||||||
"]
|
"]
|
||||||
(format {:insert-into :customers
|
(format {:insert-into :customers
|
||||||
:columns [:name :email]
|
:columns [:name :email]
|
||||||
:values [[[:inline "Microsoft"], [:inline "hotline@microsoft.com"]]]
|
:values [[[:inline "Microsoft"], [:inline "hotline@microsoft.com"]]]
|
||||||
:on-conflict [:name :email]
|
:on-conflict [:name [:trim :email]]
|
||||||
:do-nothing true}
|
:do-nothing true}
|
||||||
{:pretty true})))
|
{:pretty true})))
|
||||||
(is (= ["
|
(is (= ["
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue