summaryrefslogtreecommitdiff
path: root/src/clojure_sql
diff options
context:
space:
mode:
authorCarlo Zancanaro <carlo@clearboxsystems.com.au>2013-06-20 17:33:11 +1000
committerCarlo Zancanaro <carlo@clearboxsystems.com.au>2013-06-20 17:33:11 +1000
commitb7669002c55b2615abef4239887d70fb09a3075b (patch)
treeac6135865bac9bcf3d1c758115181829af9f8223 /src/clojure_sql
parent42864b332fe75ca4fe01d61a579a8bc50e0d2862 (diff)
Clean up the query deref, make insert!, update! and delete! work
Diffstat (limited to 'src/clojure_sql')
-rw-r--r--src/clojure_sql/compiler.clj104
-rw-r--r--src/clojure_sql/core.clj44
2 files changed, 121 insertions, 27 deletions
diff --git a/src/clojure_sql/compiler.clj b/src/clojure_sql/compiler.clj
index b35abce..a3666dd 100644
--- a/src/clojure_sql/compiler.clj
+++ b/src/clojure_sql/compiler.clj
@@ -240,6 +240,87 @@
(vec (cons sql vars))))
+
+;; Utility functions
+
+(defn ^:private build-insertion [db fields record]
+ )
+
+(defn insert! [db {:keys [fields tables joins]} & records]
+ (assert (= (count tables) 1) "Cannot insert into a multiple-table query")
+ (let [fields-order (map key fields)
+ wrap #(str "INSERT INTO "
+ (table-name db (val (first tables)))
+ " ("
+ (->> fields
+ (map (comp (partial table-name db) second val))
+ (string/join ","))
+ ") VALUES (" (string/join "),(" %) ")")
+ build-insertion #(->> (for [field fields-order]
+ (compile-expression db (get % field)))
+ (apply sequence)
+ ((p-lift string/join ",")))
+ insertions (->> (for [record records]
+ (build-insertion record))
+ (apply sequence))
+ [sql vars] (-> ((p-lift wrap) insertions)
+ (u/funcall []))]
+ (vec (cons sql vars))))
+
+;; (insert! nil
+;; (-> (table :users)
+;; (project {:id :uid, :username :name}))
+;; {:uid 10, :name :carlo, :other :stuff}
+;; {:uid 1, :name :carl, :other :stuf})
+
+(defn update! [db {:keys [tables fields where joins]} partial-record]
+ (assert (= (count tables) 1) "Cannot delete from a multiple-table query")
+ (let [table-name (-> tables first val)
+ where-expression (if where
+ ($str (return " WHERE ")
+ (compile-expression db where))
+ (return nil))
+ updates (->> (for [[alias value] partial-record
+ :when (fields alias)]
+ ($str (compile-expression db (fields alias))
+ (return " = ")
+ (compile-expression db value)))
+ (apply sequence))
+ table (compile-tables db joins tables)
+ combined ($str (return "UPDATE ")
+ table
+ (return " SET ")
+ ((p-lift string/join ", ") updates)
+ where-expression)
+ [sql vars] (combined [])]
+ (vec (cons sql vars))))
+
+;; (update! nil
+;; (-> (table :users)
+;; (project {:username :blah})
+;; (select `(= :id 10)))
+;; {:username "carlozancnaro"
+;; :blah "blah"})
+
+(defn delete! [db {:keys [tables where joins]}]
+ (assert (= (count tables) 1) "Cannot delete from a multiple-table query")
+ (let [table (compile-tables db joins tables)
+ where-expression (if where
+ ($str (return " WHERE ")
+ (compile-expression db where))
+ (return nil))
+ combined ($str (return "DELETE FROM ")
+ table
+ where-expression)
+ [sql vars] (combined [])]
+ (vec (cons sql vars))))
+
+;; (delete! nil (-> (table :users)
+;; (select `(= :id 10))))
+
+
+
+
;; ==============================================================
;; A few DB specific overrides
;; ==============================================================
@@ -258,26 +339,3 @@
(defmethod table-name :mysql [_ table]
(str \` (name table) \`))
-
-
-;;(compile nil {:table {:u :u}, :fields {[:v :x] :w}})
-
-
-
-
-;; Utility functions
-
-(defn insert! [db query & records]
- {:pre [(empty? (:joins query))]}
- ;; some code here
- )
-
-(defn update! [db query & partial-records]
- {:pre [(empty? (:joins query))]}
- ;; some code here
- )
-
-(defn delete! [db query]
- {:pre [(empty? (:joins query))]}
- ;; some code here
- )
diff --git a/src/clojure_sql/core.clj b/src/clojure_sql/core.clj
index bd4b431..5380c08 100644
--- a/src/clojure_sql/core.clj
+++ b/src/clojure_sql/core.clj
@@ -12,10 +12,19 @@
(alter-var-root #'*database-type* (constantly new-type))
nil)
-(q/set-query-deref-behaviour! #(c/compile *database-type* %))
+(def ^:private ^:dynamic *query-executor* nil)
+(defn set-query-executor! [exec-fn]
+ (alter-var-root #'*query-executor* (constantly exec-fn))
+ nil)
+
+(q/set-query-deref-behaviour! #(let [compiled (c/compile *database-type* %)]
+ (if *query-executor*
+ (*query-executor* compiled)
+ compiled)))
+
(defmethod print-method clojure_sql.query.Query [query writer]
(binding [*out* writer]
- (pr (c/compile nil query))))
+ (pr (c/compile *database-type* query))))
(def table #'d/table)
@@ -27,6 +36,33 @@
(def having #'d/having)
(def sort #'d/sort)
+;(def take #'d/take)
+;(def drop #'d/drop)
+
+
+(def insert! (fn [query & records]
+ (let [compiled (apply c/insert! *database-type* query records)]
+ (if *query-executor*
+ (*query-executor* compiled)
+ compiled))))
+
+(def update! (fn [query partial-record]
+ (let [compiled (c/update! *database-type* query partial-record)]
+ (if *query-executor*
+ (*query-executor* compiled)
+ compiled))))
+
+(def delete! (fn [query]
+ (let [compiled (c/delete! *database-type* query)]
+ (if *query-executor*
+ (*query-executor* compiled)
+ compiled))))
+
+(let [users (-> (table :users)
+ (project [:id :username :password-hash]))]
+ (insert! (-> users
+ (project [:username]))
+ {:username "john"}
+ {:username "not-john"}
+ {:username "bleep bloop"}))
-(-> (table :x)
- (select `($ (- :a) #"bloo")))