Refactored parameterizer to use mutimethods

It was briefly mentioned in #honeysql on clojurians.slack.com that this
mechanism of extension uses a register method and an atom to support
extension when multimethods are used elsewhere.
This commit is contained in:
Chris Targett 2018-05-15 21:22:32 +01:00
parent 524887a9cd
commit f778419cb9
2 changed files with 18 additions and 21 deletions

View file

@ -51,22 +51,18 @@
:sqlserver #(str \[ (string/replace % "]" "]]") \])
:oracle #(str \" (string/replace % "\"" "\"\"") \")})
(def ^:private parameterizers
(atom
{:postgresql #(str "$" (swap! *all-param-counter* inc))
:jdbc (constantly "?")
:none #(str (last @*params*))}))
(defn register-parameterizer
"Register f as a customized parameterizer.
E.g.:
(register-parameterizer :single-quote #(str \"'\" % \"'\"))
(format sql-map :parameterizer :single-quote)"
[k f]
(swap!
parameterizers
(fn [m]
(assoc m k #(f (last @*params*))))))
(defmulti parameterize (fn [parameterizer & args] parameterizer))
(defmethod parameterize :postgresql [_ value pname]
(str "$" (swap! *all-param-counter* inc)))
(defmethod parameterize :jdbc [_ value pname]
"?")
(defmethod parameterize :none [_ value pname]
(str (last @*params*)))
(def ^:dynamic *quote-identifier-fn* nil)
(def ^:dynamic *parameterizer* nil)
@ -266,7 +262,7 @@
*param-names* (atom [])
*input-params* (atom params)
*quote-identifier-fn* (quote-fns (:quoting opts))
*parameterizer* (@parameterizers (or (:parameterizer opts) :jdbc))
*parameterizer* (or (:parameterizer opts) :jdbc)
*allow-dashed-names?* (:allow-dashed-names? opts)]
(let [sql-str (to-sql sql-map)]
(if (and (seq @*params*) (not= :none (:parameterizer opts)))
@ -284,7 +280,7 @@
(defn to-params-default [value pname]
(swap! *params* conj value)
(swap! *param-names* conj pname)
(*parameterizer*))
(parameterize *parameterizer* value pname))
(extend-protocol Parameterizable
#?@(:clj
@ -300,7 +296,7 @@
(to-params [value pname]
(swap! *params* conj value)
(swap! *param-names* conj pname)
(*parameterizer*))
(parameterize *parameterizer* value pname))
#?(:clj Object :cljs default)
(to-params [value pname]
#?(:clj

View file

@ -5,7 +5,7 @@
[honeysql.types :as sql]
[honeysql.format :refer
[*allow-dashed-names?* quote-identifier format-clause format
register-parameterizer]]))
parameterize]]))
(deftest test-quote
(are
@ -176,8 +176,9 @@
:parameterizer :postgresql)
["WHERE (foo = $1 AND bar = $2)" "foo" "bar"]))))
(register-parameterizer :single-quote #(str \' % \'))
(register-parameterizer :mysql-fill (constantly "?"))
(defmethod parameterize :single-quote [_ value pname] (str \' value \'))
(defmethod parameterize :mysql-fill [_ value pname] "?")
(deftest customized-parameterizer
(testing "should fill param with single quote"