From b7669002c55b2615abef4239887d70fb09a3075b Mon Sep 17 00:00:00 2001 From: Carlo Zancanaro Date: Thu, 20 Jun 2013 17:33:11 +1000 Subject: Clean up the query deref, make insert!, update! and delete! work --- src/clojure_sql/compiler.clj | 104 +++++++++++++++++++++++++++++++++---------- src/clojure_sql/core.clj | 44 ++++++++++++++++-- 2 files changed, 121 insertions(+), 27 deletions(-) (limited to 'src/clojure_sql') 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"))) -- cgit v1.2.3