commit
79553697ef
4 changed files with 21 additions and 8 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
(defproject honeysql "0.4.2"
|
(defproject honeysql "0.4.3-SNAPSHOT"
|
||||||
:description "SQL as Clojure data structures"
|
:description "SQL as Clojure data structures"
|
||||||
:license {:name "Eclipse Public License"
|
:license {:name "Eclipse Public License"
|
||||||
:url "http://www.eclipse.org/legal/epl-v10.html"}
|
:url "http://www.eclipse.org/legal/epl-v10.html"}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,10 @@
|
||||||
(defn paren-wrap [x]
|
(defn paren-wrap [x]
|
||||||
(str "(" x ")"))
|
(str "(" x ")"))
|
||||||
|
|
||||||
|
(def ^:dynamic *clause*
|
||||||
|
"During formatting, *clause* is bound to :select, :from, :where, etc."
|
||||||
|
nil)
|
||||||
|
|
||||||
(def ^:dynamic *params*
|
(def ^:dynamic *params*
|
||||||
"Will be bound to an atom-vector that accumulates SQL parameters across
|
"Will be bound to an atom-vector that accumulates SQL parameters across
|
||||||
possibly-recursive function calls"
|
possibly-recursive function calls"
|
||||||
|
|
@ -31,7 +35,8 @@
|
||||||
(def ^:private quote-fns
|
(def ^:private quote-fns
|
||||||
{:ansi #(str \" % \")
|
{:ansi #(str \" % \")
|
||||||
:mysql #(str \` % \`)
|
:mysql #(str \` % \`)
|
||||||
:sqlserver #(str \[ % \])})
|
:sqlserver #(str \[ % \])
|
||||||
|
:oracle #(str \" % \")})
|
||||||
|
|
||||||
(def ^:dynamic *quote-identifier-fn* nil)
|
(def ^:dynamic *quote-identifier-fn* nil)
|
||||||
|
|
||||||
|
|
@ -162,7 +167,7 @@
|
||||||
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, or :sqlserver. Defaults to no quoting."
|
:mysql, :sqlserver, or :oracle. Defaults to no quoting."
|
||||||
[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))
|
||||||
|
|
@ -191,7 +196,7 @@
|
||||||
(defprotocol ToSql
|
(defprotocol ToSql
|
||||||
(-to-sql [x]))
|
(-to-sql [x]))
|
||||||
|
|
||||||
(declare format-clause)
|
(declare -format-clause)
|
||||||
|
|
||||||
(extend-protocol ToSql
|
(extend-protocol ToSql
|
||||||
clojure.lang.Keyword
|
clojure.lang.Keyword
|
||||||
|
|
@ -213,7 +218,10 @@
|
||||||
(paren-wrap (comma-join (map to-sql x)))
|
(paren-wrap (comma-join (map to-sql x)))
|
||||||
;; alias
|
;; alias
|
||||||
(str (to-sql (first x))
|
(str (to-sql (first x))
|
||||||
|
; Omit AS in FROM, JOIN, etc. - Oracle doesn't allow it
|
||||||
|
(if (= :select *clause*)
|
||||||
" AS "
|
" AS "
|
||||||
|
" ")
|
||||||
(if (string? (second x))
|
(if (string? (second x))
|
||||||
(quote-identifier (second x))
|
(quote-identifier (second x))
|
||||||
(to-sql (second x))))))
|
(to-sql (second x))))))
|
||||||
|
|
@ -231,7 +239,7 @@
|
||||||
sql-str (binding [*subquery?* true
|
sql-str (binding [*subquery?* true
|
||||||
*fn-context?* false]
|
*fn-context?* false]
|
||||||
(space-join
|
(space-join
|
||||||
(map (comp #(format-clause % x) #(find x %))
|
(map (comp #(-format-clause % x) #(find x %))
|
||||||
clause-ops)))]
|
clause-ops)))]
|
||||||
(if *subquery?*
|
(if *subquery?*
|
||||||
(paren-wrap sql-str)
|
(paren-wrap sql-str)
|
||||||
|
|
@ -274,6 +282,11 @@
|
||||||
"Takes a map entry representing a clause and returns an SQL string"
|
"Takes a map entry representing a clause and returns an SQL string"
|
||||||
(fn [clause _] (key clause)))
|
(fn [clause _] (key clause)))
|
||||||
|
|
||||||
|
(defn- -format-clause
|
||||||
|
[clause _]
|
||||||
|
(binding [*clause* (key clause)]
|
||||||
|
(format-clause clause _)))
|
||||||
|
|
||||||
(defmethod format-clause :default [& _]
|
(defmethod format-clause :default [& _]
|
||||||
"")
|
"")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
(is (= m1 m3)))
|
(is (= m1 m3)))
|
||||||
(testing "SQL data formats correctly"
|
(testing "SQL data formats correctly"
|
||||||
(is (= (sql/format m1 {:param1 "gabba" :param2 2})
|
(is (= (sql/format m1 {:param1 "gabba" :param2 2})
|
||||||
["SELECT DISTINCT f.*, b.baz, c.quux, b.bla AS bla_bla, now(), @x := 10 FROM foo AS f, baz AS b INNER JOIN draq ON f.b = draq.x LEFT JOIN clod AS c ON f.a = c.d RIGHT JOIN bock ON bock.z = c.e WHERE ((f.a = ? AND b.baz <> ?) OR (1 < 2 AND 2 < 3) OR (f.e in (1, ?, 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 "
|
["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 WHERE ((f.a = ? AND b.baz <> ?) OR (1 < 2 AND 2 < 3) OR (f.e in (1, ?, 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])))
|
"bort" "gabba" 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)))))))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue