The rules for determining which connection to use are as follows. These are tried in order until one returns non-nil:
The connectable specified in the function arguments.
The toucan2.connection/*current-connectable*
, if bound. This is bound automatically when
using with-connection
or with-transaction
The toucan2.model/default-connectable
for the model resolved from the modelable
in the function arguments;
The :default
implementation of toucan2.connection/do-with-connection
You can define a 'named' connectable such as ::db
by adding an implementation
of toucan2.connection/do-with-connection
, or use things like JDBC URL connection strings or [[clojure.java.jdbc]]
connection properties maps directly.
IMPORTANT CAVEAT! Positional connectables will be used in preference to *current-connectable*
, even when it was
bound by with-transaction
-- this means your query will run OUTSIDE of the current transaction! Sometimes, this is
what you want, because maybe a certain query is meant to run against a different database! Usually, however, it is
not! So in that case you can either do something like
(t2/query (or conn/*current-connectable* ::my-db) ...)
to use the current connection if it exists, or define your named connectable method like
(m/defmethod conn/do-with-connection ::my-db
[_connectable f]
(conn/do-with-connection
(if (and conn/*current-connectable*
(not= conn/*current-connectable* ::my-db))
conn/*current-connectable*
"jdbc:postgresql://...")
f))
This, however, is super annoying! So I might reconsider this behavior in the future.
For reducible queries, the connection is not resolved until the query is executed, so you may create a reducible query
with no default connection available and execute it later with one bound. (This also means
that toucan2.execute/reducible-query
does not capture dynamic bindings such
as toucan2.connection/*current-connectable*
-- you probably wouldn't want it to, anyway, since we have no
guarantees and open connection will be around when we go to use the reducible query later.)
#### Connection Resolution The rules for determining which connection to use are as follows. These are tried in order until one returns non-nil: 1. The connectable specified in the function arguments. 2. The [[toucan2.connection/*current-connectable*]], if bound. This is bound automatically when using [[with-connection]] or [[with-transaction]] 3. The [[toucan2.model/default-connectable]] for the model resolved from the `modelable` in the function arguments; 4. The `:default` implementation of [[toucan2.connection/do-with-connection]] You can define a 'named' connectable such as `::db` by adding an implementation of [[toucan2.connection/do-with-connection]], or use things like JDBC URL connection strings or [[clojure.java.jdbc]] connection properties maps directly. IMPORTANT CAVEAT! Positional connectables will be used in preference to [[*current-connectable*]], even when it was bound by [[with-transaction]] -- this means your query will run OUTSIDE of the current transaction! Sometimes, this is what you want, because maybe a certain query is meant to run against a different database! Usually, however, it is not! So in that case you can either do something like ```clj (t2/query (or conn/*current-connectable* ::my-db) ...) ``` to use the current connection if it exists, or define your named connectable method like ```clj (m/defmethod conn/do-with-connection ::my-db [_connectable f] (conn/do-with-connection (if (and conn/*current-connectable* (not= conn/*current-connectable* ::my-db)) conn/*current-connectable* "jdbc:postgresql://...") f)) ``` This, however, is super annoying! So I might reconsider this behavior in the future. For reducible queries, the connection is not resolved until the query is executed, so you may create a reducible query with no default connection available and execute it later with one bound. (This also means that [[toucan2.execute/reducible-query]] does not capture dynamic bindings such as [[toucan2.connection/*current-connectable*]] -- you probably wouldn't want it to, anyway, since we have no guarantees and open connection will be around when we go to use the reducible query later.)
The current connectable or connection. If you get a connection with with-connection
or with-transaction
, it
will be bound here. You can also bind this yourself to a connectable or connection, and Toucan methods called without
an explicit will connectable will use it rather than the :default
connection.
The current connectable or connection. If you get a connection with [[with-connection]] or [[with-transaction]], it will be bound here. You can also bind this yourself to a connectable or connection, and Toucan methods called without an explicit will connectable will use it rather than the `:default` connection.
(connection-string-protocol connection-string)
Extract the protocol part of a connection-string
.
(connection-string-protocol "jdbc:postgresql:...")
=>
"jdbc"
Extract the protocol part of a `connection-string`. ```clj (connection-string-protocol "jdbc:postgresql:...") => "jdbc" ```
(do-with-connection connectable₁ f)
Take a connectable, get a connection of some sort from it, and execute (f connection)
with an open connection. A
normal implementation might look something like:
(m/defmethod t2.conn/do-with-connection ::my-connectable
[_connectable f]
(with-open [conn (get-connection)]
(f conn)))
Another common use case is to define a 'named' connectable that acts as an alias for another more complicated connectable, such as a JDBC connection string URL. You can do that like this:
(m/defmethod t2.conn/do-with-connection ::a-connectable
[_connectable f]
(t2.conn/do-with-connection
"jdbc:postgresql://localhost:5432/toucan2?user=cam&password=cam"
f))
do-with-connection is defined in toucan2.connection
(toucan2/connection.clj:70).
It caches methods using a methodical.impl.cache.watching.WatchingCache
.
It uses the method combination methodical.impl.combo.threaded.ThreadingMethodCombination
with the threading strategy :thread-last
.
It uses the dispatcher methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher
with hierarchy #'clojure.core/global-hierarchy
and prefs {javax.sql.DataSource #{clojure.lang.IPersistentMap}}
.
The default value is :toucan2.connection/default
.
It uses the method table methodical.impl.method_table.standard.StandardMethodTable
.
These primary methods are known:
:toucan2.connection/default
, defined in toucan2.connection
(toucan2/connection.clj:174)
:default
, defined in toucan2.connection
(toucan2/connection.clj:184)
nil
, defined in toucan2.connection
(toucan2/connection.clj:194)
It has the following documentation:
nil
means use the current connection.
The difference between nil
and using *current-connectable*
directly is that this waits until it gets resolved
by do-with-connection
to get the value for *current-connectable*
. For a reducible query this means you'll get
the value at the time you reduce the query rather than at the time you build the reducible query.
java.sql.Connection
, defined in toucan2.connection
(toucan2/connection.clj:206)
javax.sql.DataSource
, defined in toucan2.connection
(toucan2/connection.clj:210)
clojure.lang.IPersistentMap
, defined in toucan2.connection
(toucan2/connection.clj:215)
It has the following documentation:
Implementation for map connectables. Treats them as a clojure.java.jdbc
-style connection spec map, converting them to
a java.sql.DataSource
with [[next.jdbc/get-datasource]].
java.lang.String
, defined in toucan2.connection
(toucan2/connection.clj:245)
It has the following documentation:
Implementation for Strings. Hands off to do-with-connection-string
.
These aux methods are known:
:around
methods:
:toucan2.connection/default
, defined in toucan2.connection
(toucan2/connection.clj:106)
It has the following documentation:
Do some debug logging/context capture. Bind *current-connectable*
to the connection f
is called with inside of
f
.
Take a *connectable*, get a connection of some sort from it, and execute `(f connection)` with an open connection. A normal implementation might look something like: ```clj (m/defmethod t2.conn/do-with-connection ::my-connectable [_connectable f] (with-open [conn (get-connection)] (f conn))) ``` Another common use case is to define a 'named' connectable that acts as an alias for another more complicated connectable, such as a JDBC connection string URL. You can do that like this: ```clj (m/defmethod t2.conn/do-with-connection ::a-connectable [_connectable f] (t2.conn/do-with-connection "jdbc:postgresql://localhost:5432/toucan2?user=cam&password=cam" f)) ``` do-with-connection is defined in [[toucan2.connection]] (toucan2/connection.clj:70). It caches methods using a `methodical.impl.cache.watching.WatchingCache`. It uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination` with the threading strategy `:thread-last`. It uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher` with hierarchy `#'clojure.core/global-hierarchy` and prefs `{javax.sql.DataSource #{clojure.lang.IPersistentMap}}`. The default value is `:toucan2.connection/default`. It uses the method table `methodical.impl.method_table.standard.StandardMethodTable`. These primary methods are known: * `:toucan2.connection/default`, defined in [[toucan2.connection]] (toucan2/connection.clj:174) * `:default`, defined in [[toucan2.connection]] (toucan2/connection.clj:184) * `nil`, defined in [[toucan2.connection]] (toucan2/connection.clj:194) It has the following documentation: `nil` means use the current connection. The difference between `nil` and using [[*current-connectable*]] directly is that this waits until it gets resolved by [[do-with-connection]] to get the value for [[*current-connectable*]]. For a reducible query this means you'll get the value at the time you reduce the query rather than at the time you build the reducible query. * `java.sql.Connection`, defined in [[toucan2.connection]] (toucan2/connection.clj:206) * `javax.sql.DataSource`, defined in [[toucan2.connection]] (toucan2/connection.clj:210) * `clojure.lang.IPersistentMap`, defined in [[toucan2.connection]] (toucan2/connection.clj:215) It has the following documentation: Implementation for map connectables. Treats them as a `clojure.java.jdbc`-style connection spec map, converting them to a `java.sql.DataSource` with [[next.jdbc/get-datasource]]. * `java.lang.String`, defined in [[toucan2.connection]] (toucan2/connection.clj:245) It has the following documentation: Implementation for Strings. Hands off to [[do-with-connection-string]]. These aux methods are known: `:around` methods: * `:toucan2.connection/default`, defined in [[toucan2.connection]] (toucan2/connection.clj:106) It has the following documentation: Do some debug logging/context capture. Bind [[*current-connectable*]] to the connection `f` is called with inside of `f`.
(do-with-connection-string connection-string f)
Implementation of do-with-connection
for strings. Dispatches on the connection-string-protocol
of the string,
e.g. "jdbc"
for "jdbc:postgresql://localhost:3000/toucan"
.
do-with-connection-string is defined in toucan2.connection
(toucan2/connection.clj:238).
It caches methods using a methodical.impl.cache.watching.WatchingCache
.
It uses the method combination methodical.impl.combo.threaded.ThreadingMethodCombination
with the threading strategy :thread-last
.
It uses the dispatcher methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher
with hierarchy #'clojure.core/global-hierarchy
and prefs {}
.
The default value is :default
.
It uses the method table methodical.impl.method_table.standard.StandardMethodTable
.
These primary methods are known:
"jdbc"
, defined in toucan2.connection
(toucan2/connection.clj:250)
It has the following documentation:
Implementation of do-with-connection-string
(and thus do-with-connection
) for all strings starting with jdbc:
.
Calls java.sql.DriverManager/getConnection
on the connection string.
Implementation of [[do-with-connection]] for strings. Dispatches on the [[connection-string-protocol]] of the string, e.g. `"jdbc"` for `"jdbc:postgresql://localhost:3000/toucan"`. do-with-connection-string is defined in [[toucan2.connection]] (toucan2/connection.clj:238). It caches methods using a `methodical.impl.cache.watching.WatchingCache`. It uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination` with the threading strategy `:thread-last`. It uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher` with hierarchy `#'clojure.core/global-hierarchy` and prefs `{}`. The default value is `:default`. It uses the method table `methodical.impl.method_table.standard.StandardMethodTable`. These primary methods are known: * `"jdbc"`, defined in [[toucan2.connection]] (toucan2/connection.clj:250) It has the following documentation: Implementation of `do-with-connection-string` (and thus [[do-with-connection]]) for all strings starting with `jdbc:`. Calls `java.sql.DriverManager/getConnection` on the connection string.
(do-with-transaction connection₁ options f)
options
are options for determining what type of transaction we'll get. See dox for with-transaction
for more
information.
do-with-transaction is defined in toucan2.connection
(toucan2/connection.clj:257).
It caches methods using a methodical.impl.cache.watching.WatchingCache
.
It uses the method combination methodical.impl.combo.threaded.ThreadingMethodCombination
with the threading strategy :thread-last
.
It uses the dispatcher methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher
with hierarchy #'clojure.core/global-hierarchy
and prefs {}
.
The default value is :toucan2.connection/default
.
It uses the method table methodical.impl.method_table.standard.StandardMethodTable
.
These primary methods are known:
java.sql.Connection
, defined in toucan2.connection
(toucan2/connection.clj:270)These aux methods are known:
:around
methods:
:toucan2.connection/default
, defined in toucan2.connection
(toucan2/connection.clj:264)
It has the following documentation:
Bind *current-connectable*
to the connection f
is called with inside of f
.
`options` are options for determining what type of transaction we'll get. See dox for [[with-transaction]] for more information. do-with-transaction is defined in [[toucan2.connection]] (toucan2/connection.clj:257). It caches methods using a `methodical.impl.cache.watching.WatchingCache`. It uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination` with the threading strategy `:thread-last`. It uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher` with hierarchy `#'clojure.core/global-hierarchy` and prefs `{}`. The default value is `:toucan2.connection/default`. It uses the method table `methodical.impl.method_table.standard.StandardMethodTable`. These primary methods are known: * `java.sql.Connection`, defined in [[toucan2.connection]] (toucan2/connection.clj:270) These aux methods are known: `:around` methods: * `:toucan2.connection/default`, defined in [[toucan2.connection]] (toucan2/connection.clj:264) It has the following documentation: Bind [[*current-connectable*]] to the connection `f` is called with inside of `f`.
(with-connection [connection-binding] & body)
(with-connection [connection-binding connectable] & body)
Execute body
with an open connection. There are three ways to use this.
With no args in the bindings vector, with-connection
will use the current connection -- *current-connectable*
if one is bound, or the default connectable if not. See docstring for toucan2.connection
for more information.
(t2/with-connection []
...)
With one arg, with-connection
still uses the current connection, but binds it to something (conn
in the example
below):
(t2/with-connection [conn]
...)
If you're using the default JDBC backend, conn
will be an instance of java.sql.Connection
. Since Toucan 2 is also
written to work with other backend besides JDBC, conn
does not include java.sql.Connection
:tag
metadata! If
you're doing Java interop with conn
, make sure to tag it yourself:
(t2/with-connection [^java.sql.Connection conn]
(let [metadata (.getMetaData conn)]
...))
With a connection binding and a connectable:
(t2/with-connection [conn ::my-connectable]
...)
This example gets a connection by calling do-with-connection
with ::my-connectable
, ignoring the current
connection.
Execute `body` with an open connection. There are three ways to use this. With no args in the bindings vector, `with-connection` will use the *current connection* -- [[*current-connectable*]] if one is bound, or the *default connectable* if not. See docstring for [[toucan2.connection]] for more information. ```clj (t2/with-connection [] ...) ``` With one arg, `with-connection` still uses the *current connection*, but binds it to something (`conn` in the example below): ```clj (t2/with-connection [conn] ...) ``` If you're using the default JDBC backend, `conn` will be an instance of `java.sql.Connection`. Since Toucan 2 is also written to work with other backend besides JDBC, `conn` does *not* include `java.sql.Connection` `:tag` metadata! If you're doing Java interop with `conn`, make sure to tag it yourself: ```clj (t2/with-connection [^java.sql.Connection conn] (let [metadata (.getMetaData conn)] ...)) ``` With a connection binding *and* a connectable: ```clj (t2/with-connection [conn ::my-connectable] ...) ``` This example gets a connection by calling [[do-with-connection]] with `::my-connectable`, ignoring the *current connection*.
(with-transaction [conn-binding connectable options?] & body)
Gets a connection with with-connection
, and executes body
within that transaction.
An options
map, if specified, determine what sort of transaction we're asking for (stuff like the read isolation
level and what not). One key, :nested-transaction-rule
, is handled directly in Toucan 2; other options are passed
directly to the underlying implementation, such as [[next.jdbc.transaction]].
:nested-transaction-rule
must be one of #{:allow :ignore :prohibit}
, a set of possibilities borrowed from
next.jdbc
. For non-JDBC implementations, you should treat :allow
as the default behavior if unspecified.
Gets a connection with [[with-connection]], and executes `body` within that transaction. An `options` map, if specified, determine what sort of transaction we're asking for (stuff like the read isolation level and what not). One key, `:nested-transaction-rule`, is handled directly in Toucan 2; other options are passed directly to the underlying implementation, such as [[next.jdbc.transaction]]. `:nested-transaction-rule` must be one of `#{:allow :ignore :prohibit}`, a set of possibilities borrowed from `next.jdbc`. For non-JDBC implementations, you should treat `:allow` as the default behavior if unspecified.
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close