Allow execute! on a PreparedStatement

Refactors reduce of prepared statement so it can be reused.
Remove options from `mapify-result-set` until option handling is figured out.
This commit is contained in:
Sean Corfield 2019-01-10 11:35:17 -08:00
parent a99b4542ca
commit 4ae5b44a52

View file

@ -344,7 +344,7 @@
Later we may realize a new hash map when assoc (and other, future, operations Later we may realize a new hash map when assoc (and other, future, operations
are performed on the result set row)." are performed on the result set row)."
[^ResultSet rs opts] [^ResultSet rs]
(let [cols (delay (get-column-names rs))] (let [cols (delay (get-column-names rs))]
(reify (reify
@ -380,18 +380,12 @@
(.getObject rs i))) (.getObject rs i)))
(range 1 (inc (count @cols))))))))) (range 1 (inc (count @cols)))))))))
(defn execute! (defn- reduce-stmt
"General SQL execution function. Returns a reducible that, when reduced, ""
runs the SQL and yields the result." [^PreparedStatement stmt f init]
[db-spec sql-params & [opts]]
(let [opts (merge (when (map? db-spec) db-spec) opts)]
(reify clojure.lang.IReduceInit
(reduce [this f init]
(with-open [con (get-connection db-spec)]
(with-open [stmt (prepare con sql-params opts)]
(if (.execute stmt) (if (.execute stmt)
(let [rs (.getResultSet stmt) (let [rs (.getResultSet stmt)
rs-map (mapify-result-set rs opts)] rs-map (mapify-result-set rs)]
(loop [init' init] (loop [init' init]
(if (.next rs) (if (.next rs)
(let [result (f init' rs-map)] (let [result (f init' rs-map)]
@ -399,10 +393,24 @@
@result @result
(recur result))) (recur result)))
init'))) init')))
(.getUpdateCount stmt)))))))) (.getUpdateCount stmt)))
(defn execute!
"General SQL execution function.
Returns a reducible that, when reduced, runs the SQL and yields the result."
([stmt]
(reify clojure.lang.IReduceInit
(reduce [this f init] (reduce-stmt stmt f init))))
([connectable sql-params & [opts]]
(let [opts (merge (when (map? connectable) connectable) opts)]
(reify clojure.lang.IReduceInit
(reduce [this f init]
(with-open [con (get-connection connectable)]
(with-open [stmt (prepare con sql-params opts)]
(reduce-stmt stmt f init))))))))
(comment (comment
(def db-spec {:dbtype "mysql" :dbname "worldsingles" :user "root" :password "visual" :useSSL false})
(def db-spec {:dbtype "h2:mem" :dbname "perf"}) (def db-spec {:dbtype "h2:mem" :dbname "perf"})
(def con db-spec) (def con db-spec)
(def con (get-connection db-spec)) (def con (get-connection db-spec))
@ -416,6 +424,19 @@
(require '[criterium.core :refer [bench quick-bench]]) (require '[criterium.core :refer [bench quick-bench]])
;; calibrate ;; calibrate
(quick-bench (reduce + (take 10e6 (range)))) (quick-bench (reduce + (take 10e6 (range))))
(with-open [ps (prepare con ["select * from fruit where appearance = ?"] {})]
(quick-bench
(reduce (fn [_ row] (reduced (:name row)))
nil
(execute! (set-parameters ps ["red"])))))
(with-open [ps (prepare con ["select * from fruit where appearance = ?"] {})]
(quick-bench
[(reduce (fn [_ row] (reduced (:name row)))
nil
(execute! (set-parameters ps ["red"])))
(reduce (fn [_ row] (reduced (:name row)))
nil
(execute! (set-parameters ps ["fuzzy"])))]))
(quick-bench (quick-bench
(reduce (fn [_ row] (reduced (:name row))) (reduce (fn [_ row] (reduced (:name row)))
nil nil