Fixes #303 by adding ON DUPLICATE KEY UPDATE

This commit is contained in:
Sean Corfield 2021-03-12 16:13:52 -08:00
parent d35d9141bc
commit dc6a3662f0
5 changed files with 36 additions and 3 deletions

View file

@ -4,6 +4,7 @@
* Support much richer range of syntax on `CREATE`/`DROP` statements in general, including columns, `TABLESPACE`, `CASCADE`, `WITH [NO] DATA`, etc.
* Fix #306 by supporting `CREATE TABLE .. AS ..`.
* Fix #305 by supporting more complex join clauses.
* Fix #303 by supporting MySQL's `ON DUPLICATE KEY UPDATE`.
* Fix #301 by adding support for `CREATE`/`DROP`/`REFRESH` on `MATERIALIZED VIEW`.
* Add tests to confirm #299 does not affect v2.
* Confirm the whole of the [nilenso/honeysql-postgres](https://github.com/nilenso/honeysql-postgres) is implemented out-of-the-box (#293).

View file

@ -715,6 +715,10 @@ user=> (sql/format {:insert-into :companies
["INSERT INTO companies (name) VALUES (?) ON CONFLICT ON CONSTRAINT name_idx DO NOTHING" "Microsoft"]
```
## on-duplicate-key-update
This is the MySQL equivalent of `on-update-set` described above.
## returning
`:returning` accepts a single sequence argument that lists

View file

@ -54,7 +54,7 @@
:where :group-by :having
:window :partition-by
:order-by :limit :offset :for :values
:on-conflict :on-constraint :do-nothing :do-update-set
:on-conflict :on-constraint :do-nothing :do-update-set :on-duplicate-key-update
:returning
:with-data])
@ -754,6 +754,8 @@
:on-constraint #'format-selector
:do-nothing (fn [k _] (vector (sql-kw k)))
:do-update-set #'format-do-update-set
;; MySQL-specific but might as well be always enabled:
:on-duplicate-key-update #'format-do-update-set
:returning #'format-selects
:with-data #'format-with-data}))

View file

@ -569,6 +569,10 @@
[& args]
(generic :do-update-set args))
(defn on-duplicate-key-update
[& args]
(generic :on-duplicate-key-update args))
(defn returning
"Accepts any number of column names to return from an
insert operation:

View file

@ -10,8 +10,9 @@
create-materialized-view drop-view drop-materialized-view
cross-join do-update-set drop-column drop-index drop-table from full-join
group-by having insert-into
join-by join left-join limit offset on-conflict order-by
over partition-by refresh-materialized-view
join-by join left-join limit offset on-conflict
on-duplicate-key-update
order-by over partition-by refresh-materialized-view
rename-column rename-table returning right-join
select select-distinct values where window with with-columns
with-data]]))
@ -649,3 +650,24 @@
(f {k [:and [:a] [:b]]}
:or
[:x] [:y]))))))))
(deftest mysql-on-duplicate-key-update
(testing "From https://www.mysqltutorial.org/mysql-insert-or-update-on-duplicate-key-update"
(is (= (sql/format (-> (insert-into :device)
(columns :name)
(values [["Printer"]])
(on-duplicate-key-update {:name "Printer"})))
["INSERT INTO device (name) VALUES (?) ON DUPLICATE KEY UPDATE name = ?"
"Printer" "Printer"]))
(is (= (sql/format (-> (insert-into :device)
(columns :id :name)
(values [[4 "Printer"]])
(on-duplicate-key-update {:name "Central Printer"})))
["INSERT INTO device (id, name) VALUES (?, ?) ON DUPLICATE KEY UPDATE name = ?"
4 "Printer" "Central Printer"]))
(is (= (sql/format (-> (insert-into :table)
(columns :c1)
(values [[42]])
(on-duplicate-key-update {:c1 [:+ [:values :c1] 1]})))
["INSERT INTO table (c1) VALUES (?) ON DUPLICATE KEY UPDATE c1 = VALUES(c1) + ?"
42 1]))))