parent
e6d1abf3ec
commit
9ed335dc8d
6 changed files with 82 additions and 29 deletions
|
|
@ -4,6 +4,7 @@ Only accretive/fixative changes will be made from now on.
|
||||||
|
|
||||||
* 1.3.next in progress
|
* 1.3.next in progress
|
||||||
* Address [#295](https://github.com/seancorfield/next-jdbc/issues/295) by providing a way to tell `next.jdbc` that certain options should be passed "as-is" in the `Properties` object when creating a `Connection`.
|
* Address [#295](https://github.com/seancorfield/next-jdbc/issues/295) by providing a way to tell `next.jdbc` that certain options should be passed "as-is" in the `Properties` object when creating a `Connection`.
|
||||||
|
* Fix [#181](https://github.com/seancorfield/next-jdbc/issues/181) (again!) by adding `Wrapped` protocol as a way for `DefaultOptions` and `SQLLogging` to consistently expose the underlying connectable, even when nested.
|
||||||
|
|
||||||
* 1.3.994 -- 2025-01-28
|
* 1.3.994 -- 2025-01-28
|
||||||
* Fix [#293](https://github.com/seancorfield/next-jdbc/issues/293) by no longer `locking` on the `Connection` retrieved from a `DataSource`.
|
* Fix [#293](https://github.com/seancorfield/next-jdbc/issues/293) by no longer `locking` on the `Connection` retrieved from a `DataSource`.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
;; copyright (c) 2018-2024 Sean Corfield, all rights reserved
|
;; copyright (c) 2018-2025 Sean Corfield, all rights reserved
|
||||||
|
|
||||||
(ns next.jdbc
|
(ns next.jdbc
|
||||||
"The public API of the next generation java.jdbc library.
|
"The public API of the next generation java.jdbc library.
|
||||||
|
|
@ -336,13 +336,14 @@
|
||||||
result))))
|
result))))
|
||||||
params)))
|
params)))
|
||||||
([connectable sql param-groups opts]
|
([connectable sql param-groups opts]
|
||||||
(if (or (instance? java.sql.Connection connectable)
|
(let [conn (p/unwrap connectable)]
|
||||||
(and (satisfies? p/Connectable connectable)
|
(if (instance? java.sql.Connection conn)
|
||||||
(instance? java.sql.Connection (:connectable connectable))))
|
(with-open [ps (prepare conn [sql] (if-let [opts' (:options connectable)]
|
||||||
(with-open [ps (prepare connectable [sql] opts)]
|
(merge opts' opts)
|
||||||
|
opts))]
|
||||||
(execute-batch! ps param-groups opts))
|
(execute-batch! ps param-groups opts))
|
||||||
(with-open [con (get-connection connectable)]
|
(with-open [con (get-connection connectable)]
|
||||||
(execute-batch! con sql param-groups opts)))))
|
(execute-batch! con sql param-groups opts))))))
|
||||||
|
|
||||||
(defmacro on-connection
|
(defmacro on-connection
|
||||||
"Given a connectable object, gets a connection and binds it to `sym`,
|
"Given a connectable object, gets a connection and binds it to `sym`,
|
||||||
|
|
@ -365,13 +366,10 @@
|
||||||
executes the body, and automatically closes it for you."
|
executes the body, and automatically closes it for you."
|
||||||
[[sym connectable] & body]
|
[[sym connectable] & body]
|
||||||
(let [con-sym (vary-meta sym assoc :tag 'java.sql.Connection)]
|
(let [con-sym (vary-meta sym assoc :tag 'java.sql.Connection)]
|
||||||
`(let [con-obj# ~connectable]
|
`(let [con-obj# ~connectable
|
||||||
(cond (instance? java.sql.Connection con-obj#)
|
bare-con# (p/unwrap con-obj#)]
|
||||||
((^{:once true} fn* [~con-sym] ~@body) con-obj#)
|
(if (instance? java.sql.Connection bare-con#)
|
||||||
(and (satisfies? p/Connectable con-obj#)
|
((^{:once true} fn* [~con-sym] ~@body) bare-con#)
|
||||||
(instance? java.sql.Connection (:connectable con-obj#)))
|
|
||||||
((^{:once true} fn* [~con-sym] ~@body) (:connectable con-obj#))
|
|
||||||
:else
|
|
||||||
(with-open [con# (get-connection con-obj#)]
|
(with-open [con# (get-connection con-obj#)]
|
||||||
((^{:once true} fn* [~con-sym] ~@body) con#))))))
|
((^{:once true} fn* [~con-sym] ~@body) con#))))))
|
||||||
|
|
||||||
|
|
@ -403,12 +401,8 @@
|
||||||
with `on-connection`."
|
with `on-connection`."
|
||||||
[[sym connectable] & body]
|
[[sym connectable] & body]
|
||||||
`(let [con-obj# ~connectable]
|
`(let [con-obj# ~connectable]
|
||||||
(cond (instance? java.sql.Connection con-obj#)
|
(if (instance? java.sql.Connection (p/unwrap con-obj#))
|
||||||
((^{:once true} fn* [~sym] ~@body) con-obj#)
|
((^{:once true} fn* [~sym] ~@body) con-obj#)
|
||||||
(and (satisfies? p/Connectable con-obj#)
|
|
||||||
(instance? java.sql.Connection (:connectable con-obj#)))
|
|
||||||
((^{:once true} fn* [~sym] ~@body) con-obj#)
|
|
||||||
:else
|
|
||||||
(with-open [con# (get-connection con-obj#)]
|
(with-open [con# (get-connection con-obj#)]
|
||||||
((^{:once true} fn* [~sym] ~@body)
|
((^{:once true} fn* [~sym] ~@body)
|
||||||
(with-options con# (:options con-obj# {})))))))
|
(with-options con# (:options con-obj# {})))))))
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
;; copyright (c) 2020-2024 Sean Corfield, all rights reserved
|
;; copyright (c) 2020-2025 Sean Corfield, all rights reserved
|
||||||
|
|
||||||
(ns ^:no-doc next.jdbc.default-options
|
(ns ^:no-doc next.jdbc.default-options
|
||||||
"Implementation of default options logic."
|
"Implementation of default options logic."
|
||||||
|
|
@ -8,6 +8,10 @@
|
||||||
|
|
||||||
(defrecord DefaultOptions [connectable options])
|
(defrecord DefaultOptions [connectable options])
|
||||||
|
|
||||||
|
(extend-protocol p/Wrapped
|
||||||
|
DefaultOptions
|
||||||
|
(unwrap [this] (p/unwrap (:connectable this))))
|
||||||
|
|
||||||
(extend-protocol p/Sourceable
|
(extend-protocol p/Sourceable
|
||||||
DefaultOptions
|
DefaultOptions
|
||||||
(get-datasource [this]
|
(get-datasource [this]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
;; copyright (c) 2018-2024 Sean Corfield, all rights reserved
|
;; copyright (c) 2018-2025 Sean Corfield, all rights reserved
|
||||||
|
|
||||||
(ns next.jdbc.protocols
|
(ns next.jdbc.protocols
|
||||||
"This is the extensible core of the next generation java.jdbc library.
|
"This is the extensible core of the next generation java.jdbc library.
|
||||||
|
|
@ -63,3 +63,15 @@
|
||||||
:extend-via-metadata true
|
:extend-via-metadata true
|
||||||
(-transact [this body-fn opts]
|
(-transact [this body-fn opts]
|
||||||
"Run the `body-fn` inside a transaction."))
|
"Run the `body-fn` inside a transaction."))
|
||||||
|
|
||||||
|
(defprotocol Wrapped
|
||||||
|
"Protocol for (un)wrapping a `next.jdbc` connectable.
|
||||||
|
|
||||||
|
Implementations are provided for `Object` (identity) and `DefaultOptions`
|
||||||
|
and SQLLogging."
|
||||||
|
(unwrap [this]
|
||||||
|
"Unwrap the connectable to get the underlying connectable."))
|
||||||
|
|
||||||
|
(extend-protocol Wrapped
|
||||||
|
Object
|
||||||
|
(unwrap [this] this))
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
;; copyright (c) 2021-2024 Sean Corfield, all rights reserved
|
;; copyright (c) 2021-2025 Sean Corfield, all rights reserved
|
||||||
|
|
||||||
(ns ^:no-doc next.jdbc.sql-logging
|
(ns ^:no-doc next.jdbc.sql-logging
|
||||||
"Implementation of sql-logging logic."
|
"Implementation of sql-logging logic."
|
||||||
|
|
@ -8,6 +8,10 @@
|
||||||
|
|
||||||
(defrecord SQLLogging [connectable sql-logger result-logger options])
|
(defrecord SQLLogging [connectable sql-logger result-logger options])
|
||||||
|
|
||||||
|
(extend-protocol p/Wrapped
|
||||||
|
SQLLogging
|
||||||
|
(unwrap [this] (p/unwrap (:connectable this))))
|
||||||
|
|
||||||
(extend-protocol p/Sourceable
|
(extend-protocol p/Sourceable
|
||||||
SQLLogging
|
SQLLogging
|
||||||
(get-datasource [this]
|
(get-datasource [this]
|
||||||
|
|
|
||||||
|
|
@ -749,6 +749,44 @@ INSERT INTO fruit (name, appearance) VALUES (?,?)
|
||||||
(conj result (count (jdbc/execute! (ds) ["select * from fruit"]))))
|
(conj result (count (jdbc/execute! (ds) ["select * from fruit"]))))
|
||||||
(finally
|
(finally
|
||||||
(jdbc/execute-one! (ds) [(str "delete from fruit where " (index) " > 4")])))))
|
(jdbc/execute-one! (ds) [(str "delete from fruit where " (index) " > 4")])))))
|
||||||
|
(is (= [1 1 1 1 1 1 1 1 1 13]
|
||||||
|
(try
|
||||||
|
(let [result (jdbc/execute-batch! (jdbc/with-options
|
||||||
|
(jdbc/with-logging (ds) println println)
|
||||||
|
{:ignore "me"})
|
||||||
|
"INSERT INTO fruit (name, appearance) VALUES (?,?)"
|
||||||
|
[["fruit1" "one"]
|
||||||
|
["fruit2" "two"]
|
||||||
|
["fruit3" "three"]
|
||||||
|
["fruit4" "four"]
|
||||||
|
["fruit5" "five"]
|
||||||
|
["fruit6" "six"]
|
||||||
|
["fruit7" "seven"]
|
||||||
|
["fruit8" "eight"]
|
||||||
|
["fruit9" "nine"]]
|
||||||
|
{})]
|
||||||
|
(conj result (count (jdbc/execute! (ds) ["select * from fruit"]))))
|
||||||
|
(finally
|
||||||
|
(jdbc/execute-one! (ds) [(str "delete from fruit where " (index) " > 4")])))))
|
||||||
|
(is (= [1 1 1 1 1 1 1 1 1 13]
|
||||||
|
(try
|
||||||
|
(let [result (jdbc/execute-batch! (jdbc/with-logging
|
||||||
|
(jdbc/with-options (ds) {:ignore "me"})
|
||||||
|
println println)
|
||||||
|
"INSERT INTO fruit (name, appearance) VALUES (?,?)"
|
||||||
|
[["fruit1" "one"]
|
||||||
|
["fruit2" "two"]
|
||||||
|
["fruit3" "three"]
|
||||||
|
["fruit4" "four"]
|
||||||
|
["fruit5" "five"]
|
||||||
|
["fruit6" "six"]
|
||||||
|
["fruit7" "seven"]
|
||||||
|
["fruit8" "eight"]
|
||||||
|
["fruit9" "nine"]]
|
||||||
|
{})]
|
||||||
|
(conj result (count (jdbc/execute! (ds) ["select * from fruit"]))))
|
||||||
|
(finally
|
||||||
|
(jdbc/execute-one! (ds) [(str "delete from fruit where " (index) " > 4")])))))
|
||||||
(is (= 4 (count (jdbc/execute! (ds) ["select * from fruit"])))))
|
(is (= 4 (count (jdbc/execute! (ds) ["select * from fruit"])))))
|
||||||
(testing "small batch insert"
|
(testing "small batch insert"
|
||||||
(is (= [1 1 1 1 1 1 1 1 1 13]
|
(is (= [1 1 1 1 1 1 1 1 1 13]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue