fix #381 by adding generic helpers; prep for 2.2.861

This commit is contained in:
Sean Corfield 2022-01-30 22:31:37 -08:00
parent 8a2f447676
commit 1d22086fce
7 changed files with 62 additions and 6 deletions

View file

@ -1,7 +1,8 @@
# Changes # Changes
* 2.2.next in progress * 2.2.861 -- 2022-01-30
* Address [#382](https://github.com/seancorfield/honeysql/issues/382) by adding `:case-expr` for BigQuery support. * Address [#382](https://github.com/seancorfield/honeysql/issues/382) by adding `:case-expr` for BigQuery support.
* Address [#381](https://github.com/seancorfield/honeysql/issues/381) by adding `generic-helper-variadic` and `generic-helper-unary` to `honey.sql.helpers`.
* Fix [#380](https://github.com/seancorfield/honeysql/issues/380) by correcting test for function type in `register-clause!` and `register-fn!`. * Fix [#380](https://github.com/seancorfield/honeysql/issues/380) by correcting test for function type in `register-clause!` and `register-fn!`.
* 2.2.858 -- 2022-01-20 * 2.2.858 -- 2022-01-20

View file

@ -4,7 +4,7 @@ SQL as Clojure data structures. Build queries programmatically -- even at runtim
## Build ## Build
[![Clojars Project](https://clojars.org/com.github.seancorfield/honeysql/latest-version.svg)](https://clojars.org/com.github.seancorfield/honeysql) [![cljdoc badge](https://cljdoc.org/badge/com.github.seancorfield/honeysql?2.2.858)](https://cljdoc.org/d/com.github.seancorfield/honeysql/CURRENT) [![Clojars Project](https://clojars.org/com.github.seancorfield/honeysql/latest-version.svg)](https://clojars.org/com.github.seancorfield/honeysql) [![cljdoc badge](https://cljdoc.org/badge/com.github.seancorfield/honeysql?2.2.861)](https://cljdoc.org/d/com.github.seancorfield/honeysql/CURRENT)
This project follows the version scheme MAJOR.MINOR.COMMITS where MAJOR and MINOR provide some relative indication of the size of the change, but do not follow semantic versioning. In general, all changes endeavor to be non-breaking (by moving to new names rather than by breaking existing names). COMMITS is an ever-increasing counter of commits since the beginning of this repository. This project follows the version scheme MAJOR.MINOR.COMMITS where MAJOR and MINOR provide some relative indication of the size of the change, but do not follow semantic versioning. In general, all changes endeavor to be non-breaking (by moving to new names rather than by breaking existing names). COMMITS is an ever-increasing counter of commits since the beginning of this repository.

View file

@ -63,7 +63,7 @@ Supported Clojure versions: 1.7 and later.
In `deps.edn`: In `deps.edn`:
<!-- :test-doc-blocks/skip --> <!-- :test-doc-blocks/skip -->
```clojure ```clojure
com.github.seancorfield/honeysql {:mvn/version "2.2.858"} com.github.seancorfield/honeysql {:mvn/version "2.2.861"}
``` ```
Required as: Required as:

View file

@ -38,6 +38,28 @@ current ordering of clauses is.
> Note: if you call `register-clause!` more than once for the same clause, the last call "wins". This allows you to correct an incorrect clause order insertion by simply calling `register-clause!` again with a different third argument. > Note: if you call `register-clause!` more than once for the same clause, the last call "wins". This allows you to correct an incorrect clause order insertion by simply calling `register-clause!` again with a different third argument.
## Defining a Helper Function for a New Clause
Having registered a new clause, you might also want a helper function
for it, just as the built-in clauses have helpers in `honey.sql.helpers`.
Two functions exist in that namespace to make it easier for you to
define your own helpers:
* `generic-helper-variadic` -- most clauses accept an arbitrary number of items in a sequence and multiple calls in a DSL expression will merge so this is the helper you will use for most clauses,
* `generic-helper-unary` -- a handful of clauses only accept a single item and cannot be merged (they behave as "last one wins"), so this helper supports that semantic.
Each of these helper support functions should be called with the keyword that
identifies your new clause and the sequence of arguments passed to it. See
the docstrings for more detail.
You might have:
<!-- :test-doc-blocks/skip -->
```clojure
(sql/register-clause! :my-clause my-formatter :where)
(defn my-clause [& args] (h/generic-helper-variadic :my-clause args))
```
## Registering a New Operator ## Registering a New Operator
`honey.sql/register-op!` accepts a keyword (or a symbol) that `honey.sql/register-op!` accepts a keyword (or a symbol) that

View file

@ -10,14 +10,14 @@ For the Clojure CLI, add the following dependency to your `deps.edn` file:
<!-- :test-doc-blocks/skip --> <!-- :test-doc-blocks/skip -->
```clojure ```clojure
com.github.seancorfield/honeysql {:mvn/version "2.2.858"} com.github.seancorfield/honeysql {:mvn/version "2.2.861"}
``` ```
For Leiningen, add the following dependency to your `project.clj` file: For Leiningen, add the following dependency to your `project.clj` file:
<!-- :test-doc-blocks/skip --> <!-- :test-doc-blocks/skip -->
```clojure ```clojure
[com.github.seancorfield/honeysql "2.2.858"] [com.github.seancorfield/honeysql "2.2.861"]
``` ```
HoneySQL produces SQL statements but does not execute them. HoneySQL produces SQL statements but does not execute them.

View file

@ -995,6 +995,26 @@
:where where} :where where}
do-update-set)))))) do-update-set))))))
(defn generic-helper-variadic
"Most clauses that accept a sequence of items can be implemented
using this helper, as:
(defn my-helper [& args] (generic-helper-variadic :my-clause args))"
[k args]
(generic k args))
(defn generic-helper-unary
"Clauses that accept only a single item can be implemented
using this helper, as:
(defn my-helper [& args] (generic-helper-unary :my-clause args))
Even though your helper is designed for clauses that accept
only a single item, you should still define it as variadic,
because that is the convention all helpers use here."
[k args]
(generic-1 k args))
#?(:clj #?(:clj
(do (do
;; ensure #295 stays true (all public functions have docstring): ;; ensure #295 stays true (all public functions have docstring):
@ -1002,6 +1022,7 @@
;; ensure all public functions match clauses: ;; ensure all public functions match clauses:
(assert (= (clojure.core/set (conj @@#'honey.sql/base-clause-order (assert (= (clojure.core/set (conj @@#'honey.sql/base-clause-order
:composite :filter :lateral :over :within-group :composite :filter :lateral :over :within-group
:upsert)) :upsert
:generic-helper-variadic :generic-helper-unary))
(clojure.core/set (conj (map keyword (keys (ns-publics *ns*))) (clojure.core/set (conj (map keyword (keys (ns-publics *ns*)))
:nest :raw)))))) :nest :raw))))))

View file

@ -369,6 +369,18 @@
(join :x [:using :id] :y [:using :foo :bar]) (join :x [:using :id] :y [:using :foo :bar])
sql/format))))) sql/format)))))
(defn my-update [& args] (h/generic-helper-unary :update args))
(defn my-set [& args] (h/generic-helper-unary :set args))
(defn my-where [& args] (h/generic-helper-variadic :where args))
(deftest custom-helpers-test
(testing "nil join"
(is (= ["UPDATE foo SET bar = ? WHERE quux = ?" 1 2]
(-> (my-update :foo)
(my-set {:bar 1})
(my-where (sql/map= {:quux 2}))
sql/format)))))
(deftest inline-test (deftest inline-test
(is (= ["SELECT * FROM foo WHERE id = 5"] (is (= ["SELECT * FROM foo WHERE id = 5"]
(-> (select :*) (-> (select :*)