add on-connection+options #256
This commit is contained in:
parent
cd214cb17e
commit
9ea5b172bb
4 changed files with 88 additions and 15 deletions
|
|
@ -3,7 +3,7 @@
|
|||
Only accretive/fixative changes will be made from now on.
|
||||
|
||||
* 1.3.next in progress
|
||||
* Address [#256](https://github.com/seancorfield/next-jdbc/issues/256) by adding `with-transaction+options`. Documentation TBD.
|
||||
* Address [#256](https://github.com/seancorfield/next-jdbc/issues/256) by adding `with-transaction+options` and `on-connection+options`. Documentation TBD.
|
||||
|
||||
* 1.3.883 -- 2023-06-25
|
||||
* Address [#254](https://github.com/seancorfield/next-jdbc/issues/254) by adding `next.jdbc/active-tx?` and adding more explanation to [**Transactions**](https://cljdoc.org/d/com.github.seancorfield/next.jdbc/CURRENT/doc/getting-started/transactions) about the conventions behind transactions and the limitations of thread-local tracking of active transactions in `next.jdbc`.
|
||||
|
|
|
|||
|
|
@ -4,4 +4,5 @@
|
|||
hooks.com.github.seancorfield.next-jdbc/with-transaction
|
||||
next.jdbc/with-transaction+options
|
||||
hooks.com.github.seancorfield.next-jdbc/with-transaction+options}}
|
||||
:lint-as {next.jdbc/on-connection clojure.core/with-open}}
|
||||
:lint-as {next.jdbc/on-connection clojure.core/with-open
|
||||
next.jdbc/on-connection+options clojure.core/with-open}}
|
||||
|
|
|
|||
|
|
@ -360,16 +360,50 @@
|
|||
Otherwise, creates a new `Connection` object from the connectable,
|
||||
executes the body, and automatically closes it for you."
|
||||
[[sym connectable] & body]
|
||||
(let [con-sym (vary-meta sym assoc :tag 'java.sql.Connection)
|
||||
con-obj connectable]
|
||||
`(cond (instance? java.sql.Connection ~con-obj)
|
||||
((^{:once true} fn* [~con-sym] ~@body) ~con-obj)
|
||||
(and (satisfies? p/Connectable ~con-obj)
|
||||
(instance? java.sql.Connection (:connectable ~con-obj)))
|
||||
((^{:once true} fn* [~con-sym] ~@body) (:connectable ~con-obj))
|
||||
(let [con-sym (vary-meta sym assoc :tag 'java.sql.Connection)]
|
||||
`(let [con-obj# ~connectable]
|
||||
(cond (instance? java.sql.Connection con-obj#)
|
||||
((^{:once true} fn* [~con-sym] ~@body) con-obj#)
|
||||
(and (satisfies? p/Connectable con-obj#)
|
||||
(instance? java.sql.Connection (:connectable con-obj#)))
|
||||
((^{:once true} fn* [~con-sym] ~@body) (:connectable con-obj#))
|
||||
:else
|
||||
(with-open [con# (get-connection con-obj#)]
|
||||
((^{:once true} fn* [~con-sym] ~@body) con#))))))
|
||||
|
||||
(defmacro on-connection+options
|
||||
"Given a connectable object, assumed to be wrapped with options, gets
|
||||
a connection, rewraps it with those options, and binds it to `sym`,
|
||||
then executes the `body` in that context.
|
||||
|
||||
This allows you to write generic, **wrapped** connectable code without
|
||||
needing to know the exact type of an incoming datasource:
|
||||
|
||||
```clojure
|
||||
(on-connection+options [conn datasource]
|
||||
(execute! conn some-insert-sql)
|
||||
(execute! conn some-update-sql))
|
||||
```
|
||||
|
||||
If passed a `Connection` then that `Connection` is used as-is.
|
||||
|
||||
If passed a `Connectable` that wraps a `Connection`, then that
|
||||
`Connectable` is used as-is.
|
||||
|
||||
Otherwise, creates a new `Connection` object from the connectable,
|
||||
wraps that with options, executes the body, and automatically closes
|
||||
the new `Connection` for you."
|
||||
[[sym connectable] & body]
|
||||
`(let [con-obj# ~connectable]
|
||||
(cond (instance? java.sql.Connection 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)]
|
||||
((^{:once true} fn* [~con-sym] ~@body) con#)))))
|
||||
(with-open [con# (get-connection con-obj#)]
|
||||
((^{:once true} fn* [~sym] ~@body)
|
||||
(with-options con# (:options con-obj# {})))))))
|
||||
|
||||
(defn transact
|
||||
"Given a transactable object and a function (taking a `Connection`),
|
||||
|
|
|
|||
|
|
@ -944,11 +944,49 @@ INSERT INTO fruit (name, appearance) VALUES (?,?)
|
|||
(deftest issue-204
|
||||
(testing "against a Connection"
|
||||
(is (seq (with-open [con (jdbc/get-connection (ds))]
|
||||
(jdbc/on-connection [x con] (jdbc/execute! x ["select * from fruit"]))))))
|
||||
(jdbc/on-connection
|
||||
[x con]
|
||||
(jdbc/execute! x ["select * from fruit"]))))))
|
||||
(testing "against a wrapped Connection"
|
||||
(is (seq (with-open [con (jdbc/get-connection (ds))]
|
||||
(jdbc/on-connection [x (jdbc/with-options con {})] (jdbc/execute! x ["select * from fruit"]))))))
|
||||
(jdbc/on-connection
|
||||
[x (jdbc/with-options con {})]
|
||||
(jdbc/execute! x ["select * from fruit"]))))))
|
||||
(testing "against a wrapped Datasource"
|
||||
(is (seq (jdbc/on-connection [x (jdbc/with-options (ds) {})] (jdbc/execute! x ["select * from fruit"])))))
|
||||
(is (seq (jdbc/on-connection
|
||||
[x (jdbc/with-options (ds) {})]
|
||||
(jdbc/execute! x ["select * from fruit"])))))
|
||||
(testing "against a Datasource"
|
||||
(is (seq (jdbc/on-connection [x (ds)] (jdbc/execute! x ["select * from fruit"]))))))
|
||||
(is (seq (jdbc/on-connection
|
||||
[x (ds)]
|
||||
(jdbc/execute! x ["select * from fruit"]))))))
|
||||
|
||||
(deftest issue-256
|
||||
(testing "against a Connection"
|
||||
(is (seq (with-open [con (jdbc/get-connection (ds))]
|
||||
(jdbc/on-connection+options
|
||||
[x con] ; raw connection stays raw
|
||||
(is (instance? java.sql.Connection x))
|
||||
(jdbc/execute! x ["select * from fruit"]))))))
|
||||
(testing "against a wrapped Connection"
|
||||
(is (seq (with-open [con (jdbc/get-connection (ds))]
|
||||
(jdbc/on-connection+options
|
||||
[x (jdbc/with-options con {:test-option 42})]
|
||||
;; ensure we get the same wrapped connection
|
||||
(is (instance? java.sql.Connection (:connectable x)))
|
||||
(is (= {:test-option 42} (:options x)))
|
||||
(jdbc/execute! x ["select * from fruit"]))))))
|
||||
(testing "against a wrapped Datasource"
|
||||
(is (seq (jdbc/on-connection+options
|
||||
[x (jdbc/with-options (ds) {:test-option 42})]
|
||||
;; ensure we get a wrapped connection
|
||||
(is (instance? java.sql.Connection (:connectable x)))
|
||||
(is (= {:test-option 42} (:options x)))
|
||||
(jdbc/execute! x ["select * from fruit"])))))
|
||||
(testing "against a Datasource"
|
||||
(is (seq (jdbc/on-connection+options
|
||||
[x (ds)] ; unwrapped datasource has no options
|
||||
;; ensure we get a wrapped connection (empty options)
|
||||
(is (instance? java.sql.Connection (:connectable x)))
|
||||
(is (= {} (:options x)))
|
||||
(jdbc/execute! x ["select * from fruit"]))))))
|
||||
|
|
|
|||
Loading…
Reference in a new issue