fix #481 by adding more examples

This commit is contained in:
Sean Corfield 2023-03-23 19:22:59 -07:00
parent 18ed03985d
commit 7e67caaf0c
3 changed files with 74 additions and 0 deletions

View file

@ -1,5 +1,8 @@
# Changes
* 2.4.next in progress
* Address [#481](https://github.com/seancorfield/honeysql/issues/481) by adding more examples around `:do-update-set`.
* 2.4.1006 -- 2023-03-17
* Fix [#478](https://github.com/seancorfield/honeysql/issues/478) by handling `:do-update-set` correctly in the `upsert` helper and by handling parameters correctly in the `:do-update-set` formatter.
* Fix [#476](https://github.com/seancorfield/honeysql/issues/476) by adding support for multiple arguments to `:raw`, essentially restoring 1.x functionality (while still allowing for embedded vectors as expressions, introduced in 2.x).

View file

@ -1124,6 +1124,12 @@ user=> (sql/format {:insert-into :companies
:do-update-set {:fields [:name]
:where [:<> :name nil]}})
["INSERT INTO companies (name) VALUES (?) ON CONFLICT (name) DO UPDATE SET name = EXCLUDED.name WHERE name IS NOT NULL" "Microsoft"]
user=> (sql/format {:insert-into :companies
:values [{:name "Microsoft"}]
:on-conflict :name
:do-update-set {:fields {:name [:+ :table.name 1]}
:where [:<> :name nil]}})
["INSERT INTO companies (name) VALUES (?) ON CONFLICT (name) DO UPDATE SET name = table.name + ? WHERE name IS NOT NULL" "Microsoft" 1]
user=> (sql/format {:insert-into :companies
:values [{:name "Microsoft"}]
:on-conflict {:on-constraint :name-idx}

View file

@ -255,6 +255,71 @@ By comparison, this is the DSL structure that nilenso would have required:
:where [:= :user.active false]}}}
```
All of the examples for `:do-update-set` so far provide one or
more columns and generated `SET` clauses using `EXCLUDED` columns.
You can also perform regular `SET` operations, where the right-hand
side is a full SQL expression by specifying a hash map of column /
expression pairs, like you would for a regular `:set` clause:
```clojure
user=> (-> (insert-into :table)
(values [{:id "id" :counter 1}])
(on-conflict :id)
(do-update-set {:counter [:+ :table.counter 1]})
(sql/format {:pretty true}))
["
INSERT INTO table
(id, counter) VALUES (?, ?)
ON CONFLICT (id)
DO UPDATE SET counter = table.counter + ?
" "id" 1 1]
;; using the DSL directly:
user=> (-> {:insert-into :table
:values [{:id "id" :counter 1}]
:on-conflict :id
:do-update-set {:counter [:+ :table.counter 1]}}
(sql/format {:pretty true}))
["
INSERT INTO table
(id, counter) VALUES (?, ?)
ON CONFLICT (id)
DO UPDATE SET counter = table.counter + ?
" "id" 1 1]
```
If you need to combine a `DO UPDATE SET` hash map expression
with a `WHERE` clause, you need to explicitly use the `:fields` /
`:where` format explained above. Here's how those two examples
look with a `WHERE` clause added:
```clojure
user=> (-> (insert-into :table)
(values [{:id "id" :counter 1}])
(on-conflict :id)
(do-update-set {:fields {:counter [:+ :table.counter 1]}
:where [:> :table.counter 1]})
(sql/format {:pretty true}))
["
INSERT INTO table
(id, counter) VALUES (?, ?)
ON CONFLICT (id)
DO UPDATE SET counter = table.counter + ? WHERE table.counter > ?
" "id" 1 1 1]
;; using the DSL directly:
user=> (-> {:insert-into :table
:values [{:id "id" :counter 1}]
:on-conflict :id
:do-update-set {:fields {:counter [:+ :table.counter 1]}
:where [:> :table.counter 1]}}
(sql/format {:pretty true}))
["
INSERT INTO table
(id, counter) VALUES (?, ?)
ON CONFLICT (id)
DO UPDATE SET counter = table.counter + ? WHERE table.counter > ?
" "id" 1 1 1]
```
## INSERT INTO AS
HoneySQL supports aliases directly in `:insert-into` so no special