diff --git a/src/next/jdbc.clj b/src/next/jdbc.clj index f3efe51..6f45740 100644 --- a/src/next/jdbc.clj +++ b/src/next/jdbc.clj @@ -468,37 +468,42 @@ ([connectable sql-params & [opts]] (-execute connectable sql-params opts))) -(defn query - "" - [connectable sql-params & [opts]] - (into [] - (map (or (:row-fn opts) (partial into {}))) - (execute! connectable sql-params opts))) +(defn- into-map [row] (into {} row)) -(defn query-one +(defn execute! "" - [connectable sql-params & [opts]] - (reduce (fn [_ row] (reduced ((or (:row-fn opts) (partial into {})) row))) - nil - (execute! connectable sql-params opts))) + ([connectable sql-params] (execute! connectable sql-params {})) + ([connectable sql-params opts] + (into [] + (map (:row-fn opts into-map)) + (reducible! connectable sql-params opts)))) -(defn command! +(defn execute-one! "" - [connectable sql-params & [opts]] - (reduce + 0 (execute! connectable sql-params opts))) + ([connectable sql-params] (execute-one! connectable sql-params {})) + ([connectable sql-params opts] + (reduce (fn [_ row] (reduced ((:row-fn opts into-map) row))) + nil + (reducible! connectable sql-params opts)))) (comment (def db-spec {:dbtype "h2:mem" :dbname "perf"}) + (def db-spec {:dbtype "derby" :dbname "perf" :create true}) + (def db-spec {:dbtype "mysql" :dbname "worldsingles" :user "root" :password "visual"}) (def con db-spec) (def con (get-datasource db-spec)) (get-connection con {}) (def con (get-connection (get-datasource db-spec) {})) (def con (get-connection db-spec {})) - (command! con ["DROP TABLE fruit"]) - (command! con ["CREATE TABLE fruit (id int default 0, name varchar(32) primary key, appearance varchar(32), cost int, grade real)"]) - (command! con ["INSERT INTO fruit (id,name,appearance,cost,grade) VALUES (1,'Apple','red',59,87), (2,'Banana','yellow',29,92.2), (3,'Peach','fuzzy',139,90.0), (4,'Orange','juicy',89,88.6)"]) + (execute! con ["DROP TABLE fruit"]) + ;; h2 + (execute! con ["CREATE TABLE fruit (id int default 0, name varchar(32) primary key, appearance varchar(32), cost int, grade real)"]) + ;; mysql + (execute! con ["CREATE TABLE fruit (id int auto_increment, name varchar(32), appearance varchar(32), cost int, grade real, primary key (id))"]) + (execute! con ["INSERT INTO fruit (id,name,appearance,cost,grade) VALUES (1,'Apple','red',59,87), (2,'Banana','yellow',29,92.2), (3,'Peach','fuzzy',139,90.0), (4,'Orange','juicy',89,88.6)"]) + (execute! con ["INSERT INTO fruit (id,name,appearance,cost,grade) VALUES (1,'Apple','red',59,87), (2,'Banana','yellow',29,92.2), (3,'Peach','fuzzy',139,90.0), (4,'Orange','juicy',89,88.6)"] + {:return-keys true}) - (println con) (.close con) (require '[criterium.core :refer [bench quick-bench]]) @@ -509,7 +514,7 @@ ;; raw java (defn select* [^Connection con] (let [ps (doto (.prepareStatement con "SELECT * FROM fruit WHERE appearance = ?") - (.setObject 1 "red")) + (.setObject 1 "red")) rs (.executeQuery ps) _ (.next rs) value (.getObject rs "name")] @@ -521,59 +526,59 @@ (quick-bench (reduce (fn [rs m] (reduced (:name m))) nil - (execute! con ["select * from fruit where appearance = ?" "red"]))) + (reducible! con ["select * from fruit where appearance = ?" "red"]))) (quick-bench - (query-one con - ["select * from fruit where appearance = ?" "red"] - {:row-fn :name})) + (execute-one! con + ["select * from fruit where appearance = ?" "red"] + {:row-fn :name})) ;; simple query (quick-bench - (query con ["select * from fruit where appearance = ?" "red"])) + (execute! con ["select * from fruit where appearance = ?" "red"])) ;; with a prepopulated prepared statement (with-open [ps (prepare con ["select * from fruit where appearance = ?" "red"] {})] (quick-bench [(reduce (fn [_ row] (reduced (:name row))) nil - (execute! ps))])) + (reducible! ps))])) ;; same as above but setting parameters inside the benchmark (with-open [ps (prepare con ["select * from fruit where appearance = ?"] {})] (quick-bench [(reduce (fn [_ row] (reduced (:name row))) nil - (execute! (set-parameters ps ["red"])))])) + (reducible! (set-parameters ps ["red"])))])) ;; this takes more than twice the time of the one above which seems strange (with-open [ps (prepare con ["select * from fruit where appearance = ?"] {})] (quick-bench [(reduce (fn [_ row] (reduced (:name row))) nil - (execute! (set-parameters ps ["red"]))) + (reducible! (set-parameters ps ["red"]))) (reduce (fn [_ row] (reduced (:name row))) nil - (execute! (set-parameters ps ["fuzzy"])))])) + (reducible! (set-parameters ps ["fuzzy"])))])) ;; full first row (quick-bench - (query-one con ["select * from fruit where appearance = ?" "red"])) + (execute-one! con ["select * from fruit where appearance = ?" "red"])) ;; test assoc works - (query-one con - ["select * from fruit where appearance = ?" "red"] - {:row-fn #(assoc % :test :value)}) + (execute-one! con + ["select * from fruit where appearance = ?" "red"] + {:row-fn #(assoc % :test :value)}) ;; test assoc works - (query con - ["select * from fruit where appearance = ?" "red"] - {:row-fn #(assoc % :test :value)}) + (execute! con + ["select * from fruit where appearance = ?" "red"] + {:row-fn #(assoc % :test :value)}) - (in-transaction [t con {:rollback-only? true}] - (command! t ["INSERT INTO fruit (id,name,appearance,cost,grade) VALUES (5,'Pear','green',49,47)"]) - (query t ["select * from fruit where name = ?" "Pear"])) - (query con ["select * from fruit where name = ?" "Pear"]) + (with-transaction [t con {:rollback-only? true}] + (execute! t ["INSERT INTO fruit (id,name,appearance,cost,grade) VALUES (5,'Pear','green',49,47)"]) + (execute! t ["select * from fruit where name = ?" "Pear"])) + (execute! con ["select * from fruit where name = ?" "Pear"]) - (in-transaction [t con {:rollback-only? false}] - (command! t ["INSERT INTO fruit (id,name,appearance,cost,grade) VALUES (5,'Pear','green',49,47)"]) - (query t ["select * from fruit where name = ?" "Pear"])) - (query con ["select * from fruit where name = ?" "Pear"])) + + (require '[clojure.java.jdbc :as j]) + (j/insert! db-spec :fruit {:id 6, :name "Kiwi", :appearance "Hairy", :cost 99, :grade 66.6}) + (require '[compliment.core]))