Dispatch execute! on a protocol

Improves performance. Handles the connect-with-connection problem.
Clean up formatting.
This commit is contained in:
Sean Corfield 2019-01-10 19:23:35 -08:00
parent 362dd5aac0
commit eaffa2fd74

View file

@ -38,11 +38,21 @@
(get-datasource ^DataSource [this opts])) (get-datasource ^DataSource [this opts]))
(defprotocol Connectable (defprotocol Connectable
(get-connection ^AutoCloseable [this])) (get-connection ^AutoCloseable [this]))
(defprotocol Executable
(-execute ^clojure.lang.IReduceInit [this sql-params opts]))
(defprotocol Preparable (defprotocol Preparable
(prepare ^PreparedStatement [this sql-params opts])) (prepare ^PreparedStatement [this sql-params opts]))
(defprotocol WithOptions (defprotocol WithOptions
(get-options [this])) (get-options [this]))
(defn execute!
"General SQL execution function.
Returns a reducible that, when reduced, runs the SQL and yields the result."
([stmt] (-execute stmt [] {}))
([connectable sql-params & [opts]]
(-execute connectable sql-params opts)))
(extend-protocol (extend-protocol
WithOptions WithOptions
Object Object
@ -280,8 +290,7 @@
(defn- url+etc->datasource (defn- url+etc->datasource
"" ""
[[url etc] opts] [[url etc] opts]
(reify (reify DataSource
DataSource
(getConnection [_] (getConnection [_]
(get-driver-connection url etc)) (get-driver-connection url etc))
(getConnection [_ username password] (getConnection [_ username password]
@ -292,53 +301,41 @@
WithOptions WithOptions
(get-options [_] opts))) (get-options [_] opts)))
(extend-protocol (extend-protocol Sourceable
Sourceable clojure.lang.Associative
clojure.lang.Associative (get-datasource [this opts]
(get-datasource [this opts] (url+etc->datasource (spec->url+etc this) opts)) (url+etc->datasource (spec->url+etc this) opts))
DataSource DataSource
(get-datasource [this opts] (get-datasource [this opts]
(reify (reify DataSource
DataSource (getConnection [_]
(getConnection [_] (.getConnection this))
(.getConnection this)) (getConnection [_ username password]
(getConnection [_ username password] (.getConnection this username password))
(.getConnection this username password)) WithOptions
WithOptions (get-options [_] opts)))
(get-options [_] opts))) String
String (get-datasource [this opts]
(get-datasource [this opts] (url+etc->datasource (string->url+etc this) opts))) (url+etc->datasource (string->url+etc this) opts)))
(extend-protocol (extend-protocol Connectable
Connectable DataSource
clojure.lang.Associative (get-connection [this] (.getConnection this))
(get-connection [this] (get-connection (get-datasource this {}))) Object
Connection (get-connection [this] (get-connection (get-datasource this {}))))
(get-connection [this] (reify
AutoCloseable
(close [_])
Connectable
(get-connection [_] this)
Preparable
(prepare [_ sql-params opts]
(prepare this sql-params opts))))
DataSource
(get-connection [this] (.getConnection this))
Object
(get-connection [this] (get-connection (get-datasource this {}))))
(extend-protocol (extend-protocol Preparable
Preparable Connection
Connection (prepare [this sql-params opts]
(prepare [this sql-params opts] (prepare* this sql-params opts)) (prepare* this sql-params opts))
DataSource DataSource
(prepare [this sql-params opts] (prepare (get-connection this) sql-params opts)) (prepare [this sql-params opts]
Object (prepare (.getConnection this)
(prepare [this sql-params opts] (prepare (get-datasource this opts) sql-params opts))) sql-params
(merge (get-options this) opts)))
(comment Object
(get-connection {:dbtype "derby" :dbname "clojure_test" :create true} {}) (prepare [this sql-params opts]
(-> "jdbc:some:stuff" (get-connection {}) (get-connection {}))) (prepare (get-datasource this opts) sql-params opts)))
(defn- get-column-names (defn- get-column-names
"" ""
@ -357,7 +354,7 @@
Supports ILookup (keywords are treated as strings). Supports ILookup (keywords are treated as strings).
Supports Associative for lookup only (again, keywords are treated as strings). Supports Associative (again, keywords are treated as strings).
Supports Seqable which realizes a full row of the data. Supports Seqable which realizes a full row of the data.
@ -414,25 +411,28 @@
init'))) init')))
(.getUpdateCount stmt))) (.getUpdateCount stmt)))
(defn execute! (extend-protocol Executable
"General SQL execution function. Connection
(-execute [this sql-params opts]
Returns a reducible that, when reduced, runs the SQL and yields the result." (reify clojure.lang.IReduceInit
([stmt] (reduce [_ f init]
(reify clojure.lang.IReduceInit (with-open [stmt (prepare this sql-params opts)]
(reduce [this f init] (reduce-stmt stmt f init)))) (reduce-stmt stmt f init)))))
([connectable sql-params & [opts]] DataSource
(let [opts (merge (get-options connectable) opts)] (-execute [this sql-params opts]
(if (instance? Connection connectable) (let [opts (merge (get-options this) opts)]
(reify clojure.lang.IReduceInit (reify clojure.lang.IReduceInit
(reduce [this f init] (reduce [_ f init]
(with-open [stmt (prepare connectable sql-params opts)] (with-open [con (get-connection this)]
(reduce-stmt stmt f init)))) (with-open [stmt (prepare con sql-params opts)]
(reify clojure.lang.IReduceInit (reduce-stmt stmt f init)))))))
(reduce [this f init] PreparedStatement
(with-open [con (get-connection connectable)] (-execute [this _ _]
(with-open [stmt (prepare con sql-params opts)] (reify clojure.lang.IReduceInit
(reduce-stmt stmt f init))))))))) (reduce [_ f init] (reduce-stmt this f init))))
Object
(-execute [this sql-params opts]
(-execute (get-datasource this opts) sql-params opts)))
(defn query (defn query
"" ""