Support :inline option

This is similar to `:parameterizer :none` (but better).
This commit is contained in:
Sean Corfield 2020-10-09 21:52:18 -07:00
parent 0c7ce43381
commit 97a3782112
2 changed files with 38 additions and 28 deletions

View file

@ -64,6 +64,7 @@
;; functions harder than necessary:
(def ^:private ^:dynamic *clause-order* default-clause-order)
(def ^:private ^:dynamic *quoted* nil)
(def ^:private ^:dynamic *inline* nil)
;; clause helpers
@ -613,9 +614,9 @@
(str " " (first sqls))
(str "(" (str/join ", " sqls) ")")))]
params)))
(into [(str "(" (str/join ", "
(repeat (count x) "?")) ")")]
x)))
(if *inline*
[(str "(" (str/join ", " (map #'sqlize-value x)) ")")]
(into [(str "(" (str/join ", " (repeat (count x) "?")) ")")] x))))
(or (true? x) (false? x)) ; because (boolean? x) requires Clojure 1.9+
[(upper-case (str x))]
@ -624,7 +625,9 @@
["NULL"]
:else
["?" x]))
(if *inline*
[(sqlize-value x)]
["?" x])))
(defn- check-dialect [dialect]
(when-not (contains? dialects dialect)
@ -652,6 +655,8 @@
(f @base-clause-order)
@current-clause-order)
@current-clause-order)
*inline* (when (contains? opts :inline)
(:inline opts))
*quoted* (if (contains? opts :quoted)
(:quoted opts)
dialect?)]
@ -736,11 +741,18 @@
(format {:select [:*] :from [:table] :group-by [:foo :bar]} {})
(format {:select [:*] :from [:table] :group-by [[:date :bar]]} {})
(format {:select [:*] :from [:table] :order-by [[:foo :desc] :bar]} {})
(format {:select [:*] :from [:table] :order-by [[[:date :expiry] :desc] :bar]} {})
(println (format {:select [:*] :from [:table] :order-by [[[:date :expiry] :desc] :bar]} {:pretty? true}))
(format {:select [:*] :from [:table] :where [:< [:date_add :expiry [:interval 30 :days]] [:now]]} {})
(format {:select [:*] :from [:table]
:order-by [[[:date :expiry] :desc] :bar]} {})
(println (format {:select [:*] :from [:table]
:order-by [[[:date :expiry] :desc] :bar]} {:pretty? true}))
(format {:select [:*] :from [:table]
:where [:< [:date_add :expiry [:interval 30 :days]] [:now]]} {})
(format-expr [:interval 30 :days])
(format {:select [:*] :from [:table] :where [:= :id (int 1)]} {:dialect :mysql})
(map fn? (format {:select [:*] :from [:table] :where [:= :id (with-meta (constantly 42) {:foo true})]} {:dialect :mysql}))
(println (format {:select [:*] :from [:table] :where [:in :id [1 2 3 4]]} {:pretty? true}))
(format {:select [:*] :from [:table]
:where [:= :id (int 1)]} {:dialect :mysql})
(map fn? (format {:select [:*] :from [:table]
:where [:= :id (with-meta (constantly 42) {:foo true})]}
{:dialect :mysql}))
(println (format {:select [:*] :from [:table]
:where [:in :id [1 2 3 4]]} {:pretty? true}))
,)

View file

@ -248,11 +248,11 @@
["WITH bar (spam, eggs) AS (VALUES (?, ?), (?, ?), (?, ?)) (SELECT foo FROM bar1) UNION ALL (SELECT foo FROM bar2)" 1 2 3 4 5 6])))
(deftest parameterizer-none
(testing "array parameter -- fail: parameterizer"
(testing "array parameter"
(is (= (format {:insert-into :foo
:columns [:baz]
:values [[[:array [1 2 3 4]]]]}
{:parameterizer :none})
{:inline true})
["INSERT INTO foo (baz) VALUES (ARRAY[1, 2, 3, 4])"])))
(testing "union complex values -- fail: parameterizer"
@ -260,7 +260,7 @@
{:select [:foo] :from [:bar2]}]
:with [[[:bar {:columns [:spam :eggs]}]
{:values [[1 2] [3 4] [5 6]]}]]}
{:parameterizer :none})
{:inline true})
["WITH bar (spam, eggs) AS (VALUES (1, 2), (3, 4), (5, 6)) (SELECT foo FROM bar1) UNION (SELECT foo FROM bar2)"]))))
(deftest inline-was-parameterizer-none
@ -280,27 +280,25 @@
[[1 2] [3 4] [5 6]])}]]})
["WITH bar (spam, eggs) AS (VALUES (1, 2), (3, 4), (5, 6)) (SELECT foo FROM bar1) UNION (SELECT foo FROM bar2)"]))))
#_(defmethod parameterize :single-quote [_ value pname] (str \' value \'))
#_(defmethod parameterize :mysql-fill [_ value pname] "?")
(deftest former-parameterizer-tests-where-and
(testing "should ignore a nil predicate -- fail: postgresql parameterizer"
(is (= (format {:where [:and
[:= :foo "foo"]
[:= :bar "bar"]
nil
[:= :quux "quux"]]}
{:parameterizer :postgresql})
["WHERE (foo = ?) AND (bar = $2) AND (quux = $3)" "foo" "bar" "quux"])))
;; this is _almost_ what :inline should be doing:
#_(testing "should fill param with single quote"
;; I have no plans for positional parameters -- I just don't see the point
#_(testing "should ignore a nil predicate -- fail: postgresql parameterizer"
(is (= (format {:where [:and
[:= :foo "foo"]
[:= :bar "bar"]
nil
[:= :quux "quux"]]}
{:parameterizer :single-quote})
["WHERE (foo = 'foo') AND (bar = 'bar') AND (quux = 'quux')" "foo" "bar" "quux"])))
{:parameterizer :postgresql})
["WHERE (foo = ?) AND (bar = $2) AND (quux = $3)" "foo" "bar" "quux"])))
;; new :inline option is similar to :parameterizer :none in 1.0
(testing "should fill param with single quote"
(is (= (format {:where [:and
[:= :foo "foo"]
[:= :bar "bar"]
nil
[:= :quux "quux"]]}
{:inline true})
["WHERE (foo = 'foo') AND (bar = 'bar') AND (quux = 'quux')"])))
(testing "should inline params with single quote"
(is (= (format {:where [:and
[:= :foo [:inline "foo"]]