fix #419 by adding InlineValue protocol
This commit is contained in:
parent
e6654f7a22
commit
99e955f420
5 changed files with 48 additions and 11 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
* 2.3.next in progress
|
* 2.3.next in progress
|
||||||
|
* Address [#419](https://github.com/seancorfield/honeysql/issues/419) by adding `honey.sql.protocols` and `InlineValue` with a `sqlize` function.
|
||||||
* Address [#413](https://github.com/seancorfield/honeysql/issues/413) by flagging a lack of `WHERE` clause for `DELETE`, `DELETE FROM`, and `UPDATE` when `:checking :basic` (or `:checking :strict`).
|
* Address [#413](https://github.com/seancorfield/honeysql/issues/413) by flagging a lack of `WHERE` clause for `DELETE`, `DELETE FROM`, and `UPDATE` when `:checking :basic` (or `:checking :strict`).
|
||||||
|
|
||||||
* 2.3.911 -- 2022-07-29
|
* 2.3.911 -- 2022-07-29
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,23 @@ many more. Built in operators include: `:=`, `:+`, `:mod`.
|
||||||
Built in functions (special syntax) include: `:array`, `:case`,
|
Built in functions (special syntax) include: `:array`, `:case`,
|
||||||
`:cast`, `:inline`, `:raw` and many more.
|
`:cast`, `:inline`, `:raw` and many more.
|
||||||
|
|
||||||
|
## Extending what `:inline` can do
|
||||||
|
|
||||||
|
By default, the `:inline` option can convert a fairly
|
||||||
|
basic set of values/types to SQL strings:
|
||||||
|
* `nil`
|
||||||
|
* strings
|
||||||
|
* keywords and symbols
|
||||||
|
* vectors
|
||||||
|
* UUIDs (Clojure only)
|
||||||
|
|
||||||
|
Everything is naively converted by calling `str`.
|
||||||
|
|
||||||
|
You can extend `honey.sql.protocols/InlineValue` to
|
||||||
|
other types and defining how the `sqlize` function
|
||||||
|
should behave. It takes a single argument, the value
|
||||||
|
to be inlined (converted to a SQL string).
|
||||||
|
|
||||||
## Registering a New Clause Formatter
|
## Registering a New Clause Formatter
|
||||||
|
|
||||||
`honey.sql/register-clause!` accepts a keyword (or a symbol)
|
`honey.sql/register-clause!` accepts a keyword (or a symbol)
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,8 @@ was wrapped in `[:inline `..`]`:
|
||||||
* keywords and symbols become SQL keywords (uppercase, with `-` replaced by a space),
|
* keywords and symbols become SQL keywords (uppercase, with `-` replaced by a space),
|
||||||
* everything else is just turned into a string (by calling `str`) and added to the SQL string.
|
* everything else is just turned into a string (by calling `str`) and added to the SQL string.
|
||||||
|
|
||||||
|
> Note: you can provide additional inline formatting by extending the `InlineValue` protocol from `honey.sql.protocols` to new types.
|
||||||
|
|
||||||
## `:params`
|
## `:params`
|
||||||
|
|
||||||
The `:params` option provides a mapping from named parameters
|
The `:params` option provides a mapping from named parameters
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@
|
||||||
* `sql-kw` -- turns a Clojure keyword (or symbol) into SQL code (makes
|
* `sql-kw` -- turns a Clojure keyword (or symbol) into SQL code (makes
|
||||||
it uppercase and replaces - with space). "
|
it uppercase and replaces - with space). "
|
||||||
(:refer-clojure :exclude [format])
|
(:refer-clojure :exclude [format])
|
||||||
(:require [clojure.string :as str]))
|
(:require [clojure.string :as str]
|
||||||
|
[honey.sql.protocols :as p]))
|
||||||
|
|
||||||
;; default formatting for known clauses
|
;; default formatting for known clauses
|
||||||
|
|
||||||
|
|
@ -263,16 +264,24 @@
|
||||||
(keyword (name s)))
|
(keyword (name s)))
|
||||||
s))
|
s))
|
||||||
|
|
||||||
(defn- sqlize-value [x]
|
(extend-protocol p/InlineValue
|
||||||
(cond
|
nil
|
||||||
(nil? x) "NULL"
|
(sqlize [_] "NULL")
|
||||||
(string? x) (str \' (str/replace x "'" "''") \')
|
String
|
||||||
(ident? x) (sql-kw x)
|
(sqlize [x] (str \' (str/replace x "'" "''") \'))
|
||||||
(vector? x) (str "[" (str/join ", " (map #'sqlize-value x)) "]")
|
#?(:clj clojure.lang.Keyword :cljs Keyword)
|
||||||
;; issue 385: quoted UUIDs for PostgreSQL/ANSI
|
(sqlize [x] (sql-kw x))
|
||||||
#?(:clj (instance? java.util.UUID x) :cljs false)
|
#?(:clj clojure.lang.Symbol :cljs Symbol)
|
||||||
(str \' x \') ; UUID cannot contain quotes
|
(sqlize [x] (sql-kw x))
|
||||||
:else (str x)))
|
#?(:clj clojure.lang.IPersistentVector :cljs PersistentVector)
|
||||||
|
(sqlize [x] (str "[" (str/join ", " (map p/sqlize x)) "]"))
|
||||||
|
#?@(:clj [java.util.UUID
|
||||||
|
;; issue 385: quoted UUIDs for PostgreSQL/ANSI
|
||||||
|
(sqlize [x] (str \' x \'))])
|
||||||
|
Object
|
||||||
|
(sqlize [x] (str x)))
|
||||||
|
|
||||||
|
(defn- sqlize-value [x] (p/sqlize x))
|
||||||
|
|
||||||
(defn- param-value [k]
|
(defn- param-value [k]
|
||||||
(if (contains? *params* k)
|
(if (contains? *params* k)
|
||||||
|
|
|
||||||
8
src/honey/sql/protocols.clj
Normal file
8
src/honey/sql/protocols.clj
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
;; copyright (c) 2022 sean corfield, all rights reserved
|
||||||
|
|
||||||
|
(ns honey.sql.protocols
|
||||||
|
"InlineValue -- a protocol that defines how to inline
|
||||||
|
values; (sqlize x) produces a SQL string for x.")
|
||||||
|
|
||||||
|
(defprotocol InlineValue :extend-via-metadata true
|
||||||
|
(sqlize [this] "Render value inline in a SQL string."))
|
||||||
Loading…
Reference in a new issue