basic numbered parameter support

This commit is contained in:
Sean Corfield 2022-12-16 23:11:45 -08:00
parent 0faf611855
commit 359d9de668

View file

@ -140,6 +140,7 @@
(def ^:private ^:dynamic *dsl* nil) (def ^:private ^:dynamic *dsl* nil)
;; caching data to detect expressions that cannot be cached: ;; caching data to detect expressions that cannot be cached:
(def ^:private ^:dynamic *caching* nil) (def ^:private ^:dynamic *caching* nil)
(def ^:private ^:dynamic *numbered* nil)
;; clause helpers ;; clause helpers
@ -321,6 +322,18 @@
{::wrapper {::wrapper
(fn [fk _] (param-value (fk)))})) (fn [fk _] (param-value (fk)))}))
(defn ->numbered [v]
(let [n (count (swap! *numbered* conj v))]
[(str "$" n) (with-meta (constantly (dec n))
{::wrapper
(fn [fk _] (get *numbered* (fk)))})]))
(defn ->numbered-param [k]
(let [n (count (swap! *numbered* conj k))]
[(str "$" n) (with-meta (constantly k)
{::wrapper
(fn [fk _] (param-value (get *numbered* (fk))))})]))
(def ^:private ^:dynamic *formatted-column* (atom false)) (def ^:private ^:dynamic *formatted-column* (atom false))
(defn- format-var [x & [opts]] (defn- format-var [x & [opts]]
@ -335,9 +348,12 @@
"(" (str/join ", " quoted-args) ")")]) "(" (str/join ", " quoted-args) ")")])
(= \? (first c)) (= \? (first c))
(let [k (keyword (subs c 1))] (let [k (keyword (subs c 1))]
(if *inline* (cond *inline*
[(sqlize-value (param-value k))] [(sqlize-value (param-value k))]
["?" (->param k)])) *numbered*
(->numbered-param k)
:else
["?" (->param k)]))
(= \' (first c)) (= \' (first c))
(do (do
(reset! *formatted-column* true) (reset! *formatted-column* true)
@ -1295,7 +1311,10 @@
(and (sequential? values) (some nil? values)))) (and (sequential? values) (some nil? values))))
(throw (ex-info "IN (NULL) does not match" (throw (ex-info "IN (NULL) does not match"
{:clause [in x y]})))) {:clause [in x y]}))))
(if (and (= "?" sql-y) (= 1 (count params-y)) (coll? values)) ;; TODO: numbered params!?!?
(if (and (= "?" sql-y)
(= 1 (count params-y))
(coll? values))
(let [sql (str "(" (str/join ", " (repeat (count values) "?")) ")")] (let [sql (str "(" (str/join ", " (repeat (count values) "?")) ")")]
(-> [(str sql-x " " (sql-kw in) " " sql)] (-> [(str sql-x " " (sql-kw in) " " sql)]
(into params-x) (into params-x)
@ -1465,13 +1484,16 @@
(into [(str "LATERAL " sql)] params)))) (into [(str "LATERAL " sql)] params))))
:lift :lift
(fn [_ [x]] (fn [_ [x]]
(if *inline* (cond *inline*
;; this is pretty much always going to be wrong, ;; this is pretty much always going to be wrong,
;; but it could produce a valid result so we just ;; but it could produce a valid result so we just
;; assume that the user knows what they are doing: ;; assume that the user knows what they are doing:
[(sqlize-value x)] [(sqlize-value x)]
["?" (with-meta (constantly x) *numbered*
{::wrapper (fn [fx _] (fx))})])) (->numbered x)
:else
["?" (with-meta (constantly x)
{::wrapper (fn [fx _] (fx))})]))
:nest :nest
(fn [_ [x]] (fn [_ [x]]
(let [[sql & params] (format-expr x)] (let [[sql & params] (format-expr x)]
@ -1503,9 +1525,12 @@
(into [(str/join ", " sqls)] params))) (into [(str/join ", " sqls)] params)))
:param :param
(fn [_ [k]] (fn [_ [k]]
(if *inline* (cond *inline*
[(sqlize-value (param-value k))] [(sqlize-value (param-value k))]
["?" (->param k)])) *numbered*
(->numbered-param k)
:else
["?" (->param k)]))
:raw :raw
(fn [_ [xs]] (fn [_ [xs]]
(raw-render xs)) (raw-render xs))
@ -1586,9 +1611,12 @@
["NULL"] ["NULL"]
:else :else
(if *inline* (cond *inline*
[(sqlize-value expr)] [(sqlize-value expr)]
["?" expr]))) *numbered*
(->numbered expr)
:else
["?" expr])))
(defn- check-dialect [dialect] (defn- check-dialect [dialect]
(when-not (contains? @dialects dialect) (when-not (contains? @dialects dialect)
@ -1642,6 +1670,8 @@
*inline* (if (contains? opts :inline) *inline* (if (contains? opts :inline)
(:inline opts) (:inline opts)
@default-inline) @default-inline)
*numbered* (when (:numbered opts)
(atom []))
*quoted* (cond (contains? opts :quoted) *quoted* (cond (contains? opts :quoted)
(:quoted opts) (:quoted opts)
dialect? dialect?