diff options
author | Carlo Zancanaro <carlo@clearboxsystems.com.au> | 2013-05-14 12:55:28 +1000 |
---|---|---|
committer | Carlo Zancanaro <carlo@clearboxsystems.com.au> | 2013-05-14 12:55:28 +1000 |
commit | a9c32acfd2a160d82a1c0c0f8484ddd202126b95 (patch) | |
tree | 23a3c1a392a2eb1195dae3312e403977e7ec5ebd | |
parent | 1c5a0359f7b048ad01a25607661229e13b5a6be7 (diff) |
Parametrise deref behaviour, add two small tests.
Now a user can decide what the query's behaviour on deref should be. This means
a user using jdbc can plug in with
(set-query-deref-behaviour! #(... jdbc-query-code-here ...))
if they want, but if a user wants to use the code for something else then they
can do so without needing to import jdbc stuff. (I'll admit I'm not sure what
else they'd do with it, but that's slightly beside the point.) Still left to do
is to provide a helper for the common case (performing an SQL query with jdbc).
-rw-r--r-- | src/clojure_sql/core.clj | 45 | ||||
-rw-r--r-- | test/clojure_sql/core_test.clj | 11 |
2 files changed, 35 insertions, 21 deletions
diff --git a/src/clojure_sql/core.clj b/src/clojure_sql/core.clj index e1dfb90..0032bb6 100644 --- a/src/clojure_sql/core.clj +++ b/src/clojure_sql/core.clj @@ -5,6 +5,24 @@ [clojure-sql.util :as u] [clojure.walk])) +(declare compile-query) + + +(def ^:dynamic *database-type* nil) +(defn set-database-type! [new-type] + (alter-var-root #'*database-type* (constantly new-type))) + +(def ^:dynamic *query-deref-behaviour* #(compile-query *database-type* %)) +(defn set-query-deref-behaviour! [f] + (alter-var-root #'*query-deref-behaviour* (constantly f))) + +(defrecord ^:private Query [] + clojure.lang.IDeref + (deref [this] (*query-deref-behaviour* this))) + + + + (defn add-parentheses [s] (str \( s \))) @@ -16,14 +34,10 @@ (defmethod table-name :default [_ table] (str \" (name table) \")) -(defmulti sql-string (fn [db _] db)) -(defmethod sql-string :default [_ string] - (str \' (string/replace string "'" "''") \')) - ;; compile-* multimethods are of the signature: -;; (db, expr) -> (SQL, replacements) +;; (db, expr) -> [SQL & replacements] (def is-unary? (comp boolean '#{not})) (def is-predicate? (comp boolean '#{= < > <= >= is in})) @@ -145,9 +159,6 @@ (defmethod table-name :mysql [_ table] (str \` (name table) \`)) -(defmethod sql-string :mysql [_ string] - (str \" (string/replace string "\"" "\\\"") \")) - @@ -163,18 +174,12 @@ ;; table: tablename -> table_alias ;; fields: (table_alias, fieldname) -> field_alias -;; joins: [(tablename -> table_alias, type, on)] +;; joins: [(tablename -> type, table_alias, on)] ;; where: expression -;; group-by: [field] -;; having: expression - -(def ^:dynamic *database-type* nil) -(defrecord Table [] - clojure.lang.IDeref - (deref [this] (compile-query *database-type* this))) +;; sort-by: [[field direction]] (defn table [arg] - (into (->Table) + (into (->Query) (if (map? arg) {:table arg} {:table {arg arg}}))) @@ -290,7 +295,7 @@ (project [:id :fname :sname]) (select '(= :deleted false))) uid-pid-match '(= :uid :pid) - is-carlo `(= :fname "Carlo") + is-carlo `(= :fname "Carlo'; SELECT * FROM users --") query (-> (join (-> users (rename {:id :uid})) (join (-> people @@ -304,14 +309,13 @@ @query)) (-> (table :users) - (project [:username]) (join (table :something-else-with-a-username) true) (select '(or (= :username "john") (not (= :username "carlo")))) + (project [:username]) deref) - (-> (table {:nodes :child}) (project [:parent-id, :name]) (rename {:name :child.name}) @@ -322,7 +326,6 @@ (project [:child.name :parent.name]) deref #_println) - (deref (-> (table :anotherStack) (project [:anotherNumber]) (join (-> (table :collection) diff --git a/test/clojure_sql/core_test.clj b/test/clojure_sql/core_test.clj new file mode 100644 index 0000000..1161ece --- /dev/null +++ b/test/clojure_sql/core_test.clj @@ -0,0 +1,11 @@ +(ns clojure-sql.core-test + (:refer-clojure :exclude [sort-by]) + (:require [clojure-sql.core :refer :all] + [midje.sweet :refer :all])) + +(fact + (compile-query nil (table :user)) + => ["SELECT * FROM \"user\""] + + (compile-query nil (-> (table :user) (select '(= :username "george")))) + => ["SELECT * FROM \"user\" WHERE (\"user\".\"username\" = ?)" "george"]) |