From f778419cb9b8e21d4d16d01269da92831d007002 Mon Sep 17 00:00:00 2001 From: Chris Targett Date: Tue, 15 May 2018 21:22:32 +0100 Subject: [PATCH] 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. --- src/honeysql/format.cljc | 32 ++++++++++++++------------------ test/honeysql/format_test.cljc | 7 ++++--- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/src/honeysql/format.cljc b/src/honeysql/format.cljc index 5b20861..12d201b 100644 --- a/src/honeysql/format.cljc +++ b/src/honeysql/format.cljc @@ -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 diff --git a/test/honeysql/format_test.cljc b/test/honeysql/format_test.cljc index 8d315eb..1dce993 100644 --- a/test/honeysql/format_test.cljc +++ b/test/honeysql/format_test.cljc @@ -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"