Merge pull request #55 from MichaelBlume/params-merge

support postgres-native parameters
This commit is contained in:
Michael Blume 2015-03-15 22:29:50 -07:00
commit 4add0b49e2
2 changed files with 17 additions and 3 deletions

View file

@ -30,6 +30,8 @@
(def ^:dynamic *param-counter* nil) (def ^:dynamic *param-counter* nil)
(def ^:dynamic *all-param-counter* nil)
(def ^:dynamic *input-params* nil) (def ^:dynamic *input-params* nil)
(def ^:dynamic *fn-context?* false) (def ^:dynamic *fn-context?* false)
@ -42,7 +44,12 @@
:sqlserver #(str \[ % \]) :sqlserver #(str \[ % \])
:oracle #(str \" % \")}) :oracle #(str \" % \")})
(def ^:private parameterizers
{:postgresql #(str "$" (swap! *all-param-counter* inc))
:jdbc (constantly "?")})
(def ^:dynamic *quote-identifier-fn* nil) (def ^:dynamic *quote-identifier-fn* nil)
(def ^:dynamic *parameterizer* nil)
(defn- undasherize [s] (defn- undasherize [s]
(string/replace s "-" "_")) (string/replace s "-" "_"))
@ -204,6 +211,7 @@
: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.
:parameterizer - style of parameter naming, one of :postgresql or :jdbc, defaults to :jdbc
:return-param-names - when true, returns a vector of :return-param-names - when true, returns a vector of
[sql-str param-values param-names]" [sql-str param-values param-names]"
[sql-map & params-or-opts] [sql-map & params-or-opts]
@ -214,9 +222,11 @@
(:params opts))] (:params opts))]
(binding [*params* (atom []) (binding [*params* (atom [])
*param-counter* (atom 0) *param-counter* (atom 0)
*all-param-counter* (atom 0)
*param-names* (atom []) *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))
*parameterizer* (parameterizers (or (:parameterizer opts) :jdbc))]
(let [sql-str (to-sql sql-map)] (let [sql-str (to-sql sql-map)]
(if (seq @*params*) (if (seq @*params*)
(if (:return-param-names opts) (if (:return-param-names opts)
@ -306,7 +316,7 @@
[x (keyword (str "_" (swap! *param-counter* inc)))])] [x (keyword (str "_" (swap! *param-counter* inc)))])]
(swap! *param-names* conj pname) (swap! *param-names* conj pname)
(swap! *params* conj x) (swap! *params* conj x)
"?"))) (*parameterizer*))))
(defn sqlable? [x] (defn sqlable? [x]
(satisfies? ToSql x)) (satisfies? ToSql x))

View file

@ -56,7 +56,11 @@
"bort" "gabba" 2] "bort" "gabba" 2]
(sql/format m1 {:param1 "gabba" :param2 2})))) (sql/format m1 {:param1 "gabba" :param2 2}))))
(testing "SQL data prints and reads correctly" (testing "SQL data prints and reads correctly"
(is (= m1 (read-string (pr-str m1))))))) (is (= m1 (read-string (pr-str m1)))))
(testing "SQL data formats correctly with alternate param naming"
(is (= (sql/format m1 :params {:param1 "gabba" :param2 2} :parameterizer :postgresql)
["SELECT DISTINCT f.*, b.baz, c.quux, b.bla AS bla_bla, now(), @x := 10 FROM foo f, baz b INNER JOIN draq ON f.b = draq.x LEFT JOIN clod c ON f.a = c.d RIGHT JOIN bock ON bock.z = c.e FULL JOIN beck ON beck.x = c.y WHERE ((f.a = $1 AND b.baz <> $2) OR (1 < 2 AND 2 < 3) OR (f.e in (1, $3, 3)) OR f.e BETWEEN 10 AND 20) GROUP BY f.a HAVING 0 < f.e ORDER BY b.baz DESC, c.quux LIMIT 50 OFFSET 10 "
"bort" "gabba" 2])))))
(deftest test-cast (deftest test-cast
(is (= ["SELECT foo, CAST(bar AS integer)"] (is (= ["SELECT foo, CAST(bar AS integer)"]