diff --git a/README.md b/README.md index 6bdb88f..44edf1f 100644 --- a/README.md +++ b/README.md @@ -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"] ``` -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 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)"] ``` +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 are supported: diff --git a/doc/general-reference.md b/doc/general-reference.md index 69c69db..70005a1 100644 --- a/doc/general-reference.md +++ b/doc/general-reference.md @@ -100,6 +100,26 @@ these tuples: 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! As questions arise about the use of HoneySQL 2.x, I will add new sections here. diff --git a/doc/postgresql.md b/doc/postgresql.md index 567c798..d709832 100644 --- a/doc/postgresql.md +++ b/doc/postgresql.md @@ -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 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 Upserting data is relatively easy in PostgreSQL