Oracle support.

Omit AS in JOIN, FROM, etc. because Oracle does not support it.
This commit is contained in:
Chris Perkins 2013-09-06 16:29:41 -06:00
parent 730706fca8
commit a4e9f0ff46
4 changed files with 21 additions and 8 deletions

View file

@ -1,4 +1,4 @@
(defproject honeysql "0.4.2"
(defproject honeysql "0.4.3-SNAPSHOT"
:description "SQL as Clojure data structures"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}

View file

@ -53,4 +53,4 @@
(if (empty? base)
base
(apply build (apply concat base)))
(partition 2 clauses))))
(partition 2 clauses))))

View file

@ -17,6 +17,10 @@
(defn paren-wrap [x]
(str "(" x ")"))
(def ^:dynamic *clause*
"During formatting, *clause* is bound to :select, :from, :where, etc."
nil)
(def ^:dynamic *params*
"Will be bound to an atom-vector that accumulates SQL parameters across
possibly-recursive function calls"
@ -31,7 +35,8 @@
(def ^:private quote-fns
{:ansi #(str \" % \")
:mysql #(str \` % \`)
:sqlserver #(str \[ % \])})
:sqlserver #(str \[ % \])
:oracle #(str \" % \")})
(def ^:dynamic *quote-identifier-fn* nil)
@ -162,7 +167,7 @@
Instead of passing parameters, you can use keyword arguments:
:params - input parameters
: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]
(let [opts (when (keyword? (first params-or-opts))
(apply hash-map params-or-opts))
@ -191,7 +196,7 @@
(defprotocol ToSql
(-to-sql [x]))
(declare format-clause)
(declare -format-clause)
(extend-protocol ToSql
clojure.lang.Keyword
@ -213,7 +218,10 @@
(paren-wrap (comma-join (map to-sql x)))
;; alias
(str (to-sql (first x))
" AS "
; Omit AS in FROM, JOIN, etc. - Oracle doesn't allow it
(if (= :select *clause*)
" AS "
" ")
(if (string? (second x))
(quote-identifier (second x))
(to-sql (second x))))))
@ -231,7 +239,7 @@
sql-str (binding [*subquery?* true
*fn-context?* false]
(space-join
(map (comp #(format-clause % x) #(find x %))
(map (comp #(-format-clause % x) #(find x %))
clause-ops)))]
(if *subquery?*
(paren-wrap sql-str)
@ -274,6 +282,11 @@
"Takes a map entry representing a clause and returns an SQL string"
(fn [clause _] (key clause)))
(defn- -format-clause
[clause _]
(binding [*clause* (key clause)]
(format-clause clause _)))
(defmethod format-clause :default [& _]
"")

View file

@ -51,7 +51,7 @@
(is (= m1 m3)))
(testing "SQL data formats correctly"
(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])))
(testing "SQL data prints and reads correctly"
(is (= m1 (read-string (pr-str m1)))))))