From a4e9f0ff4697fde03a55a75f4cd5fa2017178204 Mon Sep 17 00:00:00 2001 From: Chris Perkins Date: Fri, 6 Sep 2013 16:29:41 -0600 Subject: [PATCH] Oracle support. Omit AS in JOIN, FROM, etc. because Oracle does not support it. --- project.clj | 2 +- src/honeysql/core.clj | 2 +- src/honeysql/format.clj | 23 ++++++++++++++++++----- test/honeysql/core_test.clj | 2 +- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/project.clj b/project.clj index a071f94..1618b68 100644 --- a/project.clj +++ b/project.clj @@ -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"} diff --git a/src/honeysql/core.clj b/src/honeysql/core.clj index afa0fd0..da99666 100644 --- a/src/honeysql/core.clj +++ b/src/honeysql/core.clj @@ -53,4 +53,4 @@ (if (empty? base) base (apply build (apply concat base))) - (partition 2 clauses)))) \ No newline at end of file + (partition 2 clauses)))) diff --git a/src/honeysql/format.clj b/src/honeysql/format.clj index c1fd554..88377ac 100644 --- a/src/honeysql/format.clj +++ b/src/honeysql/format.clj @@ -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 [& _] "") diff --git a/test/honeysql/core_test.clj b/test/honeysql/core_test.clj index ec6e3eb..161b52f 100644 --- a/test/honeysql/core_test.clj +++ b/test/honeysql/core_test.clj @@ -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)))))))