make numbered params work with 'in'
This commit is contained in:
parent
4ea630ed90
commit
c62f5da3f8
2 changed files with 39 additions and 18 deletions
|
|
@ -330,7 +330,7 @@
|
||||||
|
|
||||||
(defn ->numbered-param [k]
|
(defn ->numbered-param [k]
|
||||||
(let [n (count (swap! *numbered* conj k))]
|
(let [n (count (swap! *numbered* conj k))]
|
||||||
[(str "$" n) (with-meta (constantly k)
|
[(str "$" n) (with-meta (constantly (dec n))
|
||||||
{::wrapper
|
{::wrapper
|
||||||
(fn [fk _] (param-value (get @*numbered* (fk))))})]))
|
(fn [fk _] (param-value (get @*numbered* (fk))))})]))
|
||||||
|
|
||||||
|
|
@ -1295,33 +1295,44 @@
|
||||||
(defn- format-in [in [x y]]
|
(defn- format-in [in [x y]]
|
||||||
(let [[sql-x & params-x] (format-expr x {:nested true})
|
(let [[sql-x & params-x] (format-expr x {:nested true})
|
||||||
[sql-y & params-y] (format-expr y {:nested true})
|
[sql-y & params-y] (format-expr y {:nested true})
|
||||||
values (unwrap (first params-y) {})]
|
[v1 :as values] (map #(unwrap % {}) params-y)]
|
||||||
;; #396: prevent caching IN () when named parameter is used:
|
;; #396: prevent caching IN () when named parameter is used:
|
||||||
(when (and (meta (first params-y))
|
(when (and (meta (first params-y))
|
||||||
(::wrapper (meta (first params-y)))
|
(::wrapper (meta (first params-y)))
|
||||||
*caching*)
|
*caching*)
|
||||||
(throw (ex-info "SQL that includes IN () expressions cannot be cached" {})))
|
(throw (ex-info "SQL that includes IN () expressions cannot be cached" {})))
|
||||||
(when-not (= :none *checking*)
|
(when-not (= :none *checking*)
|
||||||
(when (or (and (sequential? y) (empty? y))
|
(when (or (and (sequential? y) (empty? y))
|
||||||
(and (sequential? values) (empty? values)))
|
(and (sequential? v1) (empty? v1)))
|
||||||
(throw (ex-info "IN () empty collection is illegal"
|
(throw (ex-info "IN () empty collection is illegal"
|
||||||
{:clause [in x y]})))
|
{:clause [in x y]})))
|
||||||
(when (and (= :strict *checking*)
|
(when (and (= :strict *checking*)
|
||||||
(or (and (sequential? y) (some nil? y))
|
(or (and (sequential? y) (some nil? y))
|
||||||
(and (sequential? values) (some nil? values))))
|
(and (sequential? v1) (some nil? v1))))
|
||||||
(throw (ex-info "IN (NULL) does not match"
|
(throw (ex-info "IN (NULL) does not match"
|
||||||
{:clause [in x y]}))))
|
{:clause [in x y]}))))
|
||||||
;; TODO: numbered params!?!?
|
(cond (and (not *numbered*)
|
||||||
(if (and (= "?" sql-y)
|
(= "?" sql-y)
|
||||||
(= 1 (count params-y))
|
(= 1 (count params-y))
|
||||||
(coll? values))
|
(coll? v1))
|
||||||
(let [sql (str "(" (str/join ", " (repeat (count values) "?")) ")")]
|
(let [sql (str "(" (str/join ", " (repeat (count v1) "?")) ")")]
|
||||||
(-> [(str sql-x " " (sql-kw in) " " sql)]
|
(-> [(str sql-x " " (sql-kw in) " " sql)]
|
||||||
(into params-x)
|
(into params-x)
|
||||||
(into values)))
|
(into v1)))
|
||||||
(-> [(str sql-x " " (sql-kw in) " " sql-y)]
|
(and *numbered*
|
||||||
(into params-x)
|
(= (str "$" (count @*numbered*)) sql-y)
|
||||||
(into params-y)))))
|
(= 1 (count params-y))
|
||||||
|
(coll? v1))
|
||||||
|
(let [vs (for [v v1] (->numbered v))
|
||||||
|
sql (str "(" (str/join ", " (map first vs)) ")")]
|
||||||
|
(-> [(str sql-x " " (sql-kw in) " " sql)]
|
||||||
|
(into params-x)
|
||||||
|
(conj nil)
|
||||||
|
(into (map second vs))))
|
||||||
|
:else
|
||||||
|
(-> [(str sql-x " " (sql-kw in) " " sql-y)]
|
||||||
|
(into params-x)
|
||||||
|
(into (if *numbered* values params-y))))))
|
||||||
|
|
||||||
(defn- function-0 [k xs]
|
(defn- function-0 [k xs]
|
||||||
[(str (sql-kw k)
|
[(str (sql-kw k)
|
||||||
|
|
|
||||||
|
|
@ -322,7 +322,17 @@
|
||||||
(sql/format {:select [:*]
|
(sql/format {:select [:*]
|
||||||
:from [:customers]
|
:from [:customers]
|
||||||
:where [:in :id :?ids]}
|
:where [:in :id :?ids]}
|
||||||
{:params {:ids values}})))))))
|
{:params {:ids values}})))
|
||||||
|
(is (= ["SELECT * FROM customers WHERE id IN ($1, $2)" "1" "2"]
|
||||||
|
(sql/format {:select [:*]
|
||||||
|
:from [:customers]
|
||||||
|
:where [:in :id values]}
|
||||||
|
{:numbered true})))
|
||||||
|
(is (= ["SELECT * FROM customers WHERE id IN ($2, $3)" nil "1" "2"]
|
||||||
|
(sql/format {:select [:*]
|
||||||
|
:from [:customers]
|
||||||
|
:where [:in :id :?ids]}
|
||||||
|
{:params {:ids values} :numbered true})))))))
|
||||||
|
|
||||||
(deftest test-case
|
(deftest test-case
|
||||||
(is (= ["SELECT CASE WHEN foo < ? THEN ? WHEN (foo > ?) AND ((foo MOD ?) = ?) THEN foo / ? ELSE ? END FROM bar"
|
(is (= ["SELECT CASE WHEN foo < ? THEN ? WHEN (foo > ?) AND ((foo MOD ?) = ?) THEN foo / ? ELSE ? END FROM bar"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue