option for format to return names of params (with more dynamic vars - boo)

This commit is contained in:
Justin Kramer 2013-12-13 12:32:08 -05:00
parent 5aa351ab48
commit c8fbc16ec3

View file

@ -26,6 +26,10 @@
possibly-recursive function calls" possibly-recursive function calls"
nil) nil)
(def ^:dynamic *param-names* nil)
(def ^:dynamic *param-counter* nil)
(def ^:dynamic *input-params* nil) (def ^:dynamic *input-params* nil)
(def ^:dynamic *fn-context?* false) (def ^:dynamic *fn-context?* false)
@ -168,7 +172,9 @@
Instead of passing parameters, you can use keyword arguments: Instead of passing parameters, you can use keyword arguments:
:params - input parameters :params - input parameters
:quoting - quote style to use for identifiers; one of :ansi (PostgreSQL), :quoting - quote style to use for identifiers; one of :ansi (PostgreSQL),
:mysql, :sqlserver, or :oracle. Defaults to no quoting." :mysql, :sqlserver, or :oracle. Defaults to no quoting.
:return-param-names - when true, returns a vector of
[sql-str param-values param-names]"
[sql-map & params-or-opts] [sql-map & params-or-opts]
(let [opts (when (keyword? (first params-or-opts)) (let [opts (when (keyword? (first params-or-opts))
(apply hash-map params-or-opts)) (apply hash-map params-or-opts))
@ -176,17 +182,23 @@
(first params-or-opts) (first params-or-opts)
(:params opts))] (:params opts))]
(binding [*params* (atom []) (binding [*params* (atom [])
*param-counter* (atom 0)
*param-names* (atom [])
*input-params* (atom params) *input-params* (atom params)
*quote-identifier-fn* (quote-fns (:quoting opts))] *quote-identifier-fn* (quote-fns (:quoting opts))]
(let [sql-str (to-sql sql-map)] (let [sql-str (to-sql sql-map)]
(if (seq @*params*) (if (seq @*params*)
(into [sql-str] @*params*) (if (:return-param-names opts)
[sql-str @*params* @*param-names*]
(into [sql-str] @*params*))
[sql-str]))))) [sql-str])))))
(defn format-predicate (defn format-predicate
"Formats a predicate (e.g., for WHERE, JOIN, or HAVING) as a string." "Formats a predicate (e.g., for WHERE, JOIN, or HAVING) as a string."
[pred & {:keys [quoting]}] [pred & {:keys [quoting]}]
(binding [*params* (atom []) (binding [*params* (atom [])
*param-counter* (atom 0)
*param-names* (atom [])
*quote-identifier-fn* (or (quote-fns quoting) *quote-identifier-fn* (or (quote-fns quoting)
*quote-identifier-fn*)] *quote-identifier-fn*)]
(let [sql-str (format-predicate* pred)] (let [sql-str (format-predicate* pred)]
@ -254,13 +266,16 @@
(defn to-sql [x] (defn to-sql [x]
(if (satisfies? ToSql x) (if (satisfies? ToSql x)
(-to-sql x) (-to-sql x)
(let [x (if (instance? SqlParam x) (let [[x pname] (if (instance? SqlParam x)
(if (map? @*input-params*) (let [pname (param-name x)]
(get @*input-params* (param-name x)) (if (map? @*input-params*)
(let [x (first @*input-params*)] [(get @*input-params* pname) pname]
(swap! *input-params* rest) (let [x (first @*input-params*)]
x)) (swap! *input-params* rest)
x)] [x pname])))
;; Anonymous param name -- :_1, :_2, etc.
[x (keyword (str "_" (swap! *param-counter* inc)))])]
(swap! *param-names* conj pname)
(swap! *params* conj x) (swap! *params* conj x)
"?"))) "?")))