Fixes #339 by calling out param/lift for JSON usage

This commit is contained in:
Sean Corfield 2021-07-18 16:36:11 -07:00
parent 01c3a555ba
commit 904af73505
3 changed files with 38 additions and 1 deletions

View file

@ -66,7 +66,7 @@ Column names can be provided as keywords or symbols (but not strings -- HoneySQL
=> ["SELECT a, b, c FROM foo WHERE f.a = ?" "baz"] => ["SELECT a, b, c FROM foo WHERE f.a = ?" "baz"]
``` ```
HoneySQL is a relatively "pure" library, it does not manage your sql connection HoneySQL is a relatively "pure" library, it does not manage your JDBC connection
or run queries for you, it simply generates SQL strings. You can then pass them or run queries for you, it simply generates SQL strings. You can then pass them
to a JDBC library, such as [`next.jdbc`](https://github.com/seancorfield/next-jdbc): to a JDBC library, such as [`next.jdbc`](https://github.com/seancorfield/next-jdbc):
@ -299,6 +299,15 @@ INSERT INTO user_profile_to_role
=> ["SELECT * FROM foo WHERE foo.a IN (SELECT a FROM bar)"] => ["SELECT * FROM foo WHERE foo.a IN (SELECT a FROM bar)"]
``` ```
Because values can be nested queries -- and also because values can be function calls --
whenever you are working with values that are, themselves, structured data, you will
need to tell HoneySQL not to interpret that structured data as part of the DSL. This
especially affects using JSON values with HoneySQL (e.g., targeting PostgreSQL). There
are two possible approaches:
1. Use named parameters instead of having the values directly in the DSL structure (see `:param` under **Miscellaneous** below), or
2. Use `[:lift ..]` wrapped around any structured values which tells HoneySQL not to interpret the vector or hash map value as a DSL.
### Composite types ### Composite types
Composite types are supported: Composite types are supported:

View file

@ -100,6 +100,26 @@ these tuples:
There is also a `composite` helper function. There is also a `composite` helper function.
## Working with JSON/JSONB (PostgreSQL)
It is increasingly common for PostgreSQL users to be working with JSON columns
in their databases these days. PostgreSQL has really good support for JSON types.
When using HoneySQL to generate SQL that manipulates JSON, you need to be careful
because it is common to use regular Clojure data structures to represent the JSON
and rely on protocol extensions for the JDBC libraries to handle automatic
conversion of Clojure data structures to JSON (e.g., see
[Tips & Tricks > Working with JSON and JSONB](https://cljdoc.org/d/com.github.seancorfield/next.jdbc/CURRENT/doc/getting-started/tips-tricks#working-with-json-and-jsonb) in the `next.jdbc`
documentation).
HoneySQL also uses Clojure data structures, to represent function calls (vectors) and
SQL statements (hash maps), so if you are also using Clojure data structures for your
JSON, you need to tell HoneySQL not to interpret those values. There
are two possible approaches:
1. Use named parameters (e.g., `[:param :myval]`) instead of having the values directly in the DSL structure and then pass `{:params {:myval some-json}}` as part of the options in the call to `format`, or
2. Use `[:lift ..]` wrapped around any structured values which tells HoneySQL not to interpret the vector or hash map value as a DSL: `[:lift some-json]`.
## Other Sections Will Be Added! ## Other Sections Will Be Added!
As questions arise about the use of HoneySQL 2.x, I will add new sections here. As questions arise about the use of HoneySQL 2.x, I will add new sections here.

View file

@ -10,6 +10,14 @@ Everything that the nilenso library provided (in 0.4.112) is implemented
directly in HoneySQL 2.x although a few things have a directly in HoneySQL 2.x although a few things have a
slightly different syntax. slightly different syntax.
If you are using JSON with PostgreSQL, you will probably try to pass Clojure
data structures as values into your HoneySQL DSL -- but HoneySQL will see those
vectors as function calls and hash maps as SQL statements, so you need to tell
HoneySQL not to do that. There are two possible approaches:
1. Use named parameters (e.g., `[:param :myval]`) instead of having the values directly in the DSL structure and then pass `{:params {:myval some-json}}` as part of the options in the call to `format`, or
2. Use `[:lift ..]` wrapped around any structured values which tells HoneySQL not to interpret the vector or hash map value as a DSL: `[:lift some-json]`.
## Upsert ## Upsert
Upserting data is relatively easy in PostgreSQL Upserting data is relatively easy in PostgreSQL