add records support #532

still need to add record/object special syntax

Signed-off-by: Sean Corfield <sean@corfield.org>
This commit is contained in:
Sean Corfield 2024-11-23 11:59:12 -08:00
parent b64ab9b0b0
commit 1bac4352e3
No known key found for this signature in database
4 changed files with 42 additions and 1 deletions

View file

@ -5,7 +5,7 @@
* Fix [#552](https://github.com/seancorfield/honeysql/issues/552) by changing the assert-on-load behavior into an explicit test in the test suite. * Fix [#552](https://github.com/seancorfield/honeysql/issues/552) by changing the assert-on-load behavior into an explicit test in the test suite.
* Fix [#551](https://github.com/seancorfield/honeysql/issues/551) by supporting multiple `WINDOW` clauses. * Fix [#551](https://github.com/seancorfield/honeysql/issues/551) by supporting multiple `WINDOW` clauses.
* Fix [#549](https://github.com/seancorfield/honeysql/issues/549) by using `:bb` conditionals to support Babashka (and still support Clojure 1.9.0), and add testing against Babashka so it is fully-supported as a target via PR [#550](https://github.com/seancorfield/honeysql/pull/550) [@borkdude](https://github.com/borkdude) * Fix [#549](https://github.com/seancorfield/honeysql/issues/549) by using `:bb` conditionals to support Babashka (and still support Clojure 1.9.0), and add testing against Babashka so it is fully-supported as a target via PR [#550](https://github.com/seancorfield/honeysql/pull/550) [@borkdude](https://github.com/borkdude)
* Address [#532](https://github.com/seancorfield/honeysql/issues/532) by adding support for `EXCLUDE` and `RENAME` and starting to write tests for XTDB compatibility. * Address [#532](https://github.com/seancorfield/honeysql/issues/532) by adding support for XTDB SQL extensions `ERASE`, `EXCLUDE`, `RECORDS`, and `RENAME` and starting to write tests for XTDB compatibility.
* 2.6.1203 -- 2024-10-22 * 2.6.1203 -- 2024-10-22
* Fix [#548](https://github.com/seancorfield/honeysql/issues/548) which was a regression introduced in [#526](https://github.com/seancorfield/honeysql/issues/526) (in 2.6.1161). * Fix [#548](https://github.com/seancorfield/honeysql/issues/548) which was a regression introduced in [#526](https://github.com/seancorfield/honeysql/issues/526) (in 2.6.1161).

View file

@ -58,6 +58,7 @@
:raw :nest :with :with-recursive :intersect :union :union-all :except :except-all :raw :nest :with :with-recursive :intersect :union :union-all :except :except-all
:table :table
:select :select-distinct :select-distinct-on :select-top :select-distinct-top :select :select-distinct :select-distinct-on :select-top :select-distinct-top
:records
:distinct :expr :exclude :rename :distinct :expr :exclude :rename
:into :bulk-collect-into :into :bulk-collect-into
:insert-into :replace-into :update :delete :delete-from :erase-from :truncate :insert-into :replace-into :update :delete :delete-from :erase-from :truncate
@ -1572,6 +1573,21 @@
(let [[sql & params] (format-expr n)] (let [[sql & params] (format-expr n)]
(into [(str (sql-kw k) " " sql)] params))))) (into [(str (sql-kw k) " " sql)] params)))))
[(str (sql-kw k) " " (sql-kw args))])) [(str (sql-kw k) " " (sql-kw args))]))
(defn- format-records
"Records can take a single map or a sequence of maps.
A map will be inherently treated as a lifted parameter.
Records can be inlined [:inline some-map]"
[k args]
(if (sequential? args)
(let [args (if (every? map? args)
(map #(vector :lift %) args)
args)
[sqls params] (format-expr-list args)]
(into [(str (sql-kw k) " " (join ", " sqls))] params))
(format-records k [args])))
(defn- check-where (defn- check-where
"Given a formatter function, performs a pre-flight check that there is "Given a formatter function, performs a pre-flight check that there is
a non-empty where clause if at least basic checking is enabled." a non-empty where clause if at least basic checking is enabled."
@ -1642,6 +1658,7 @@
:select-distinct-on #'format-selects-on :select-distinct-on #'format-selects-on
:select-top #'format-select-top :select-top #'format-select-top
:select-distinct-top #'format-select-top :select-distinct-top #'format-select-top
:records #'format-records
:exclude #'format-selects :exclude #'format-selects
:rename #'format-selects :rename #'format-selects
:distinct (fn [k xs] (format-selects k [[xs]])) :distinct (fn [k xs] (format-selects k [[xs]]))

View file

@ -498,6 +498,11 @@
[& args] [& args]
(generic :select-distinct-top args)) (generic :select-distinct-top args))
(defn records
"Produces RECORDS {...}, {...}, ..."
[& args]
(generic :records args))
(defn distinct (defn distinct
"Like `select-distinct` but produces DISTINCT..." "Like `select-distinct` but produces DISTINCT..."
[& args] [& args]

View file

@ -74,3 +74,22 @@
(sql/format [:inline {:_id 1 :name "foo" (sql/format [:inline {:_id 1 :name "foo"
:info {:contact [{:loc "home" :tel "123"} :info {:contact [{:loc "home" :tel "123"}
{:loc "work" :tel "456"}]}}])))) {:loc "work" :tel "456"}]}}]))))
(deftest records-statement
(testing "auto-lift maps"
(is (= ["RECORDS ?, ?" {:_id 1 :name "cat"} {:_id 2 :name "dog"}]
(sql/format {:records [{:_id 1 :name "cat"}
{:_id 2 :name "dog"}]}))))
(testing "explicit inline"
(is (= ["RECORDS {_id: 1, name: 'cat'}, {_id: 2, name: 'dog'}"]
(sql/format {:records [[:inline {:_id 1 :name "cat"}]
[:inline {:_id 2 :name "dog"}]]}))))
(testing "insert with records"
(is (= ["INSERT INTO foo RECORDS {_id: 1, name: 'cat'}, {_id: 2, name: 'dog'}"]
(sql/format {:insert-into [:foo
{:records [[:inline {:_id 1 :name "cat"}]
[:inline {:_id 2 :name "dog"}]]}]})))
(is (= ["INSERT INTO foo RECORDS ?, ?" {:_id 1 :name "cat"} {:_id 2 :name "dog"}]
(sql/format {:insert-into [:foo
{:records [{:_id 1 :name "cat"}
{:_id 2 :name "dog"}]}]})))))