Fix #9 by combining ->factory and create again

This commit is contained in:
Sean Corfield 2019-04-10 21:46:38 -07:00
parent e5e580846f
commit d2f0afa973
4 changed files with 66 additions and 81 deletions

View file

@ -6,7 +6,7 @@
The basic building blocks are the java.sql/javax.sql classes:
* DataSource -- something to get connections from,
* Connection -- an active connection to the database,
* PreparedStatement -- SQL and parameters combined, from a connection
* PreparedStatement -- SQL and parameters combined, from a connection,
and the following two functions and a macro:
* reducible! -- given a connectable and SQL + parameters or a statement,
return a reducible that, when reduced will execute the SQL and consume

View file

@ -69,13 +69,14 @@
[return-keys]
(into-array String return-keys))
(defn ->factory
"Given a some options, return a statement factory -- a function that will
accept a connection and a SQL string and parameters, and return a
PreparedStatement representing that."
[{:keys [return-keys result-type concurrency cursors
(defn create
"Given a connection, a SQL string, some parameters, and some options,
return a PreparedStatement representing that."
^java.sql.PreparedStatement
[^Connection con ^String sql params
{:keys [return-keys result-type concurrency cursors
fetch-size max-rows timeout]}]
(cond->
(let [^PreparedStatement ps
(cond
return-keys
(do
@ -85,7 +86,6 @@
"may not be specified with :return-keys."))))
(if (vector? return-keys)
(let [key-names (string-array return-keys)]
(fn [^Connection con ^String sql]
(try
(try
(.prepareStatement con sql key-names)
@ -94,53 +94,38 @@
(.prepareStatement con sql Statement/RETURN_GENERATED_KEYS)))
(catch Exception _
;; assume it is unsupported and try basic PreparedStatement:
(.prepareStatement con sql)))))
(fn [^Connection con ^String sql]
(.prepareStatement con sql))))
(try
(.prepareStatement con sql Statement/RETURN_GENERATED_KEYS)
(catch Exception _
;; assume it is unsupported and try basic PreparedStatement:
(.prepareStatement con sql))))))
(.prepareStatement con sql)))))
(and result-type concurrency)
(if cursors
(fn [^Connection con ^String sql]
(.prepareStatement con sql
(get result-set-type result-type result-type)
(get result-set-concurrency concurrency concurrency)
(get result-set-holdability cursors cursors)))
(fn [^Connection con ^String sql]
(get result-set-holdability cursors cursors))
(.prepareStatement con sql
(get result-set-type result-type result-type)
(get result-set-concurrency concurrency concurrency))))
(get result-set-concurrency concurrency concurrency)))
(or result-type concurrency cursors)
(throw (IllegalArgumentException.
(str ":concurrency, :cursors, and :result-type "
"may not be specified independently.")))
:else
(fn [^Connection con ^String sql]
(.prepareStatement con sql)))
fetch-size (as-> f
(fn [^Connection con ^String sql]
(.setFetchSize ^PreparedStatement (f con sql) fetch-size)))
max-rows (as-> f
(fn [^Connection con ^String sql]
(.setMaxRows ^PreparedStatement (f con sql) max-rows)))
timeout (as-> f
(fn [^Connection con ^String sql]
(.setQueryTimeout ^PreparedStatement (f con sql) timeout)))))
(defn create
"Given a connection, a SQL statement, its parameters, and a statement factory,
return a PreparedStatement representing that."
^java.sql.PreparedStatement
[con sql params factory]
(set-parameters (factory con sql) params))
(.prepareStatement con sql))]
(when fetch-size
(.setFetchSize ps fetch-size))
(when max-rows
(.setMaxRows ps max-rows))
(when timeout
(.setQueryTimeout ps timeout))
(set-parameters ps params)))
(extend-protocol p/Preparable
java.sql.Connection
(prepare [this sql-params opts]
(let [[sql & params] sql-params
factory (->factory opts)]
(set-parameters (factory this sql) params))))
(create this (first sql-params) (rest sql-params) opts)))

View file

@ -161,25 +161,23 @@
(extend-protocol p/Executable
java.sql.Connection
(-execute [this sql-params opts]
(let [factory (prepare/->factory opts)]
(reify clojure.lang.IReduceInit
(reduce [_ f init]
(with-open [stmt (prepare/create this
(first sql-params)
(rest sql-params)
factory)]
(reduce-stmt stmt f init opts))))))
opts)]
(reduce-stmt stmt f init opts)))))
javax.sql.DataSource
(-execute [this sql-params opts]
(let [factory (prepare/->factory opts)]
(reify clojure.lang.IReduceInit
(reduce [_ f init]
(with-open [con (p/get-connection this opts)]
(with-open [stmt (prepare/create con
(first sql-params)
(rest sql-params)
factory)]
(reduce-stmt stmt f init opts)))))))
opts)]
(reduce-stmt stmt f init opts))))))
java.sql.PreparedStatement
(-execute [this _ opts]
(reify clojure.lang.IReduceInit

View file

@ -113,6 +113,8 @@
nil
(reducible! ps))]))
(require '[next.jdbc.prepare :as prepare])
;; same as above but setting parameters inside the benchmark
(with-open [ps (prepare con ["select * from fruit where appearance = ?"] {})]
(quick-bench