Big docstring cleanup

This commit is contained in:
Sean Corfield 2019-04-21 16:13:52 -07:00
parent 8c51fc20e6
commit 2badd9f835
9 changed files with 207 additions and 201 deletions

View file

@ -42,7 +42,7 @@ In addition, there are API functions to create `PreparedStatement`s (`prepare`)
Since `next.jdbc` uses raw Java JDBC types, you can use `with-open` directly to reuse connections and ensure they are cleaned up correctly: Since `next.jdbc` uses raw Java JDBC types, you can use `with-open` directly to reuse connections and ensure they are cleaned up correctly:
``` ```clojure
(let [my-datasource (get-datasource {:dbtype "..." :dbname "..." ...})] (let [my-datasource (get-datasource {:dbtype "..." :dbname "..." ...})]
(with-open [connection (get-connection my-datasource)] (with-open [connection (get-connection my-datasource)]
(execute! connection [...]) (execute! connection [...])
@ -61,13 +61,13 @@ In addition, convenience functions -- "syntactic sugar" -- are provided to inser
## More Detailed Documentation ## More Detailed Documentation
* [Getting Started](https://github.com/seancorfield/next-jdbc/blob/master/doc/getting_started.md) * [Getting Started](https://cljdoc.org/d/seancorfield/next.jdbc/CURRENT/doc/getting-started)
* [Friendly SQL Functions](https://github.com/seancorfield/next-jdbc/blob/master/doc/friendly_sql_fns.md) * [Friendly SQL Functions](https://cljdoc.org/d/seancorfield/next.jdbc/CURRENT/doc/getting-started/friendly-sql-fns)
* [Row and Result Set Builders](https://github.com/seancorfield/next-jdbc/blob/master/doc/rs_builders.md) * [Row and Result Set Builders](https://cljdoc.org/d/seancorfield/next.jdbc/CURRENT/doc/getting-started/rs-builders)
* [Prepared Statements](https://github.com/seancorfield/next-jdbc/blob/master/doc/prepared_stmt.md) * [Prepared Statements](https://cljdoc.org/d/seancorfield/next.jdbc/CURRENT/doc/getting-started/prepared-stmt)
* [Transactions](https://github.com/seancorfield/next-jdbc/blob/master/doc/transactions.md) * [Transactions](https://cljdoc.org/d/seancorfield/next.jdbc/CURRENT/doc/getting-started/transactions)
* [All The Options](https://github.com/seancorfield/next-jdbc/blob/master/doc/options.md) * [All The Options](https://cljdoc.org/d/seancorfield/next.jdbc/CURRENT/doc/options)
* [Migration from `clojure.java.jdbc`](https://github.com/seancorfield/next-jdbc/blob/master/doc/differences.md) * [Migration from `clojure.java.jdbc`](https://cljdoc.org/d/seancorfield/next.jdbc/CURRENT/doc/differences)
## License ## License

View file

@ -22,14 +22,14 @@ If you used `:as-arrays? true`, you will need to use a `:gen-fn` option of `next
* `get-connection` -- overlaps with `clojure.java.jdbc` (and returns a `java.sql.Connection`) but accepts only a subset of the options (`:dbtype`/`:dbname` hash map, `String` JDBC URI); `clojure.java.jdbc/get-connection` accepts `{:datasource ds}` whereas `next.jdbc/get-connection` accepts the `javax.sql.DataSource` object directly, * `get-connection` -- overlaps with `clojure.java.jdbc` (and returns a `java.sql.Connection`) but accepts only a subset of the options (`:dbtype`/`:dbname` hash map, `String` JDBC URI); `clojure.java.jdbc/get-connection` accepts `{:datasource ds}` whereas `next.jdbc/get-connection` accepts the `javax.sql.DataSource` object directly,
* `prepare` -- somewhat similar to `clojure.java.jdbc/prepare-statement` but it accepts a vector of SQL and parameters (compared to just a raw SQL string), * `prepare` -- somewhat similar to `clojure.java.jdbc/prepare-statement` but it accepts a vector of SQL and parameters (compared to just a raw SQL string),
* `reducible!` -- somewhat similar to `clojure.java.jdbc/reducible-query` but accepts arbitrary SQL statements for execution, * `reducible!` -- somewhat similar to `clojure.java.jdbc/reducible-query` but accepts arbitrary SQL statements for execution,
* `execute!` -- has no equivalent in `clojure.java.jdbc`, * `execute!` -- has no direct equivalent in `clojure.java.jdbc` (but it can replace most uses of both `query` and `db-do-commands`),
* `execute-one!` -- has no equivant in `clojure.java.jdbc`, * `execute-one!` -- has no equivalent in `clojure.java.jdbc` (but it can replace most uses of `query` that currently use `:result-set-fn first`),
* `transact` -- similar to `clojure.java.jdbc/db-transaction*`, * `transact` -- similar to `clojure.java.jdbc/db-transaction*`,
* `with-transaction` -- similar to `clojure.java.jdbc/with-db-transaction`. * `with-transaction` -- similar to `clojure.java.jdbc/with-db-transaction`.
If you were using a bare `db-spec` hash map with `:dbtype`/`:dbname`, or a JDBC URI string everywhere, that should mostly work with `next.jdbc` since most functions accept a "connectable", but it would be better to create a datasource first, and then pass that around. If you were using a bare `db-spec` hash map with `:dbtype`/`:dbname`, or a JDBC URI string everywhere, that should mostly work with `next.jdbc` since most functions accept a "connectable", but it would be better to create a datasource first, and then pass that around.
If you were already creating a pooled connection datasource, as a `{:datasource ds}` hashmap, then passing `(:datasource db-spec)` to the `next.jdbc` functions is the simplest migration path. If you were already creating `db-spec` as a pooled connection datasource -- a `{:datasource ds}` hashmap -- then passing `(:datasource db-spec)` to the `next.jdbc` functions is the simplest migration path.
If you were using other forms of the `db-spec` hash map, you'll need to adjust to one of the three modes above, since those are the only ones supported in `next.jdbc`. If you were using other forms of the `db-spec` hash map, you'll need to adjust to one of the three modes above, since those are the only ones supported in `next.jdbc`.
@ -45,7 +45,7 @@ The `next.jdbc.sql` namespace contains several functions with similarities to `c
If you are using `:identifiers` and/or `:entities`, you will need to change to appropriate `:gen-fn` and/or `:table-fn`/`:column-fn` options. For the latter, instead of the `quoted` function, there is `next.jdbc.quoted` which contains functions for the common quoting strategies. If you are using `:identifiers` and/or `:entities`, you will need to change to appropriate `:gen-fn` and/or `:table-fn`/`:column-fn` options. For the latter, instead of the `quoted` function, there is `next.jdbc.quoted` which contains functions for the common quoting strategies.
If you are using `:result-set-fn` and/or `:row-fn`, you will need to change to explicit calls (to the result set function, or to `map` the row function), or to use the `reducible!` approach with `reduce` or various transducing functions. Note: this means that result sets are never exposed lazily in `next.jdbc` -- in `clojure.java.jdbc` you had to be careful that your `:result-set-fn` was eager, but in `next.jdbc` you either reduce the result set eagerly (via `reducible!`) or you get a fully-realized result set data structure back (from `execute!` and `execute-one!`). As with `clojure.java.jdbc` however, you can still stream result sets from the database and process them via reduction (was `reducible-query`, now `reducible!`). If you are using `:result-set-fn` and/or `:row-fn`, you will need to change to explicit calls (to the result set function, or to `map` the row function), or to use the `reducible!` approach with `reduce` or various transducing functions. Note: this means that result sets are never exposed lazily in `next.jdbc` -- in `clojure.java.jdbc` you had to be careful that your `:result-set-fn` was eager, but in `next.jdbc` you either reduce the result set eagerly (via `reducible!`) or you get a fully-realized result set data structure back (from `execute!` and `execute-one!`). As with `clojure.java.jdbc` however, you can still stream result sets from the database and process them via reduction (was `reducible-query`, now `reducible!`). Remember that you can terminate a reduction early by using the `reduced` function to wrap the final value you produce.
## Further Minor differences ## Further Minor differences

View file

@ -3,44 +3,45 @@
(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.
The basic building blocks are the java.sql/javax.sql classes: The basic building blocks are the `java.sql`/`javax.sql` classes:
* DataSource -- something to get connections from, * `DataSource` -- something to get connections from,
* Connection -- an active connection to the database, * `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 functions and a macro: and the following functions and a macro:
* reducible! -- given a connectable and SQL + parameters or a statement, * `reducible!` -- given a connectable and SQL + parameters or a statement,
return a reducible that, when reduced will execute the SQL and consume return a reducible that, when reduced will execute the SQL and consume
the ResultSet produced, the `ResultSet` produced,
* execute! -- given a connectable and SQL + parameters or a statement, * `execute!` -- given a connectable and SQL + parameters or a statement,
execute the SQL, consume the ResultSet produced, and return a vector execute the SQL, consume the `ResultSet` produced, and return a vector
of hash maps representing the rows (@1); this can be datafied to allow of hash maps representing the rows (@1); this can be datafied to allow
navigation of foreign keys into other tables (either by convention or navigation of foreign keys into other tables (either by convention or
via a schema definition), via a schema definition),
* execute-one! -- given a connectable and SQL + parameters or a statement, * `execute-one!` -- given a connectable and SQL + parameters or a statement,
execute the SQL, consume the first row of the ResultSet produced, and execute the SQL, consume the first row of the `ResultSet` produced, and
return a hash map representing that row; this can be datafied to allow return a hash map representing that row; this can be datafied to allow
navigation of foreign keys into other tables (either by convention or navigation of foreign keys into other tables (either by convention or
via a schema definition), via a schema definition),
* prepare -- given a Connection and SQL + parameters, construct a new * `prepare` -- given a `Connection` and SQL + parameters, construct a new
PreparedStatement; in general this should be used with `with-open`, `PreparedStatement`; in general this should be used with `with-open`,
* transact -- the functional implementation of `with-transaction`, * `transact` -- the functional implementation of `with-transaction`,
* with-transaction -- execute a series of SQL operations within a transaction. * `with-transaction` -- execute a series of SQL operations within a transaction.
@1 result sets are built, by default, as vectors of hash maps, containing @1 result sets are built, by default, as vectors of hash maps, containing
qualified keywords as column names, but the row builder and result set qualified keywords as column names, but the row builder and result set
builder machinery is open and alternatives are provided to produce builder machinery is open and alternatives are provided to produce
unqualified keywords as column names, and to produce a vector the unqualified keywords as column names, and to produce a vector the
column names followed by vectors of column values for each row. column names followed by vectors of column values for each row, and
lower-case variants of each.
The following options are supported wherever a PreparedStatement is created: The following options are supported wherever a `PreparedStatement` is created:
* :concurrency -- :read-only, :updatable, * `:concurrency` -- `:read-only`, `:updatable`,
* :cursors -- :close, :hold * `:cursors` -- `:close`, `:hold`
* :fetch-size -- the fetch size value, * `:fetch-size` -- the fetch size value,
* :max-rows -- the maximum number of rows to return, * `:max-rows` -- the maximum number of rows to return,
* :result-type -- :forward-only, :scroll-insensitive, :scroll-sensitive, * `:result-type` -- `:forward-only`, `:scroll-insensitive`, `:scroll-sensitive`,
* :return-keys -- either true or a vector of key names to return, * `:return-keys` -- either `true` or a vector of key names to return,
* :timeout -- the query timeout." * `:timeout` -- the query timeout."
(:require [next.jdbc.connection] ; used to extend protocols (:require [next.jdbc.connection] ; used to extend protocols
[next.jdbc.prepare] ; used to extend protocols [next.jdbc.prepare] ; used to extend protocols
[next.jdbc.protocols :as p] [next.jdbc.protocols :as p]
@ -50,58 +51,60 @@
(set! *warn-on-reflection* true) (set! *warn-on-reflection* true)
(defn get-datasource (defn get-datasource
"Given some sort of specification of a database, return a DataSource. "Given some sort of specification of a database, return a `DataSource`.
A specification can be a JDBC URL string (which is passed to the JDBC A specification can be a JDBC URL string (which is passed to the JDBC
driver as-is), or a hash map. For the hash map, these keys are required: driver as-is), or a hash map. For the hash map, these keys are required:
* :dbtype -- a string indicating the type of the database * `:dbtype` -- a string indicating the type of the database
* :dbname -- a string indicating the name of the database to be used * `:dbname` -- a string indicating the name of the database to be used
The following optional keys are commonly used: The following optional keys are commonly used:
* :user -- the username to authenticate with * `:user` -- the username to authenticate with
* :password -- the password to authenticate with * `:password` -- the password to authenticate with
* :host -- the hostname or IP address of the database (default: 127.0.0.1) * `:host` -- the hostname or IP address of the database (default: `127.0.0.1`)
* :port -- the port for the database connection (the default is database- * `:port` -- the port for the database connection (the default is database-
specific -- see below) specific -- see below)
* :classname -- if you need to override the default for the :dbtype * `:classname` -- if you need to override the default for the `:dbtype`
(or you want to use a database that next.jdbc does not know about!) (or you want to use a database that next.jdbc does not know about!)
Any additional options provided will be passed to the JDBC driver's Any additional options provided will be passed to the JDBC driver's
.getConnection call as a java.util.Properties structure. `.getConnection` call as a `java.util.Properties` structure.
Database types supported, and their defaults: Database types supported, and their defaults:
* derby -- org.apache.derby.jdbc.EmbeddedDriver -- also pass :create true * `derby` -- `org.apache.derby.jdbc.EmbeddedDriver` -- also pass `:create true`
if you want the database to be automatically created if you want the database to be automatically created
* h2 -- org.h2.Driver -- for an on-disk database * `h2` -- `org.h2.Driver` -- for an on-disk database
* h2:mem -- org.h2.Driver -- for an in-memory database * `h2:mem` -- `org.h2.Driver` -- for an in-memory database
* hsqldb, hsql -- org.hsqldb.jdbcDriver * `hsqldb`, `hsql` -- `org.hsqldb.jdbcDriver`
* jtds:sqlserver, jtds -- net.sourceforge.jtds.jdbc.Driver -- 1433 * `jtds:sqlserver`, `jtds` -- `net.sourceforge.jtds.jdbc.Driver` -- `1433`
* mysql -- com.mysql.cj.jdbc.Driver, com.mysql.jdbc.Driver -- 3306 * `mysql` -- `com.mysql.cj.jdbc.Driver`, `com.mysql.jdbc.Driver` -- `3306`
* oracle:oci -- oracle.jdbc.OracleDriver -- 1521 * `oracle:oci` -- `oracle.jdbc.OracleDriver` -- `1521`
* oracle:thin, oracle -- oracle.jdbc.OracleDriver -- 1521 * `oracle:thin`, `oracle` -- `oracle.jdbc.OracleDriver` -- `1521`
* oracle:sid -- oracle.jdbc.OracleDriver -- 1521 -- uses the legacy : * `oracle:sid` -- `oracle.jdbc.OracleDriver` -- `1521` -- uses the legacy `:`
separator for the database name but otherwise behaves like oracle:thin separator for the database name but otherwise behaves like `oracle:thin`
* postgresql, postgres -- org.postgresql.Driver -- 5432 * `postgresql`, `postgres` -- `org.postgresql.Driver` -- `5432`
* pgsql -- com.impossibl.postgres.jdbc.PGDriver -- no default port * `pgsql` -- `com.impossibl.postgres.jdbc.PGDriver` -- no default port
* redshift -- com.amazon.redshift.jdbc.Driver -- no default port * `redshift` -- `com.amazon.redshift.jdbc.Driver` -- no default port
* sqlite -- org.sqlite.JDBC * `sqlite` -- `org.sqlite.JDBC`
* sqlserver, mssql -- com.microsoft.sqlserver.jdbc.SQLServerDriver -- 1433" * `sqlserver`, `mssql` -- `com.microsoft.sqlserver.jdbc.SQLServerDriver` -- `1433`"
[spec] [spec]
(p/get-datasource spec)) (p/get-datasource spec))
(defn get-connection (defn get-connection
"Given some sort of specification of a database, return a new Connection. "Given some sort of specification of a database, return a new `Connection`.
In general, this should be used via with-open: In general, this should be used via `with-open`:
```clojure
(with-open [con (get-connection spec opts)] (with-open [con (get-connection spec opts)]
(run-some-ops con)) (run-some-ops con))
```
If you call get-connection on a DataSource, it just calls .getConnection If you call `get-connection` on a `DataSource`, it just calls `.getConnection`
and applies the :auto-commit and/or :read-only options, if provided. and applies the `:auto-commit` and/or `:read-only` options, if provided.
If you call get-connection on anything else, it will call get-datasource If you call `get-connection` on anything else, it will call `get-datasource`
first to try to get a DataSource, and then call get-connection on that." first to try to get a `DataSource`, and then call `get-connection` on that."
([spec] ([spec]
(p/get-connection spec {})) (p/get-connection spec {}))
([spec opts] ([spec opts]
@ -109,12 +112,14 @@
(defn prepare (defn prepare
"Given a connection to a database, and a vector containing SQL and any "Given a connection to a database, and a vector containing SQL and any
parameters it needs, return a new PreparedStatement. parameters it needs, return a new `PreparedStatement`.
In general, this should be used via with-open: In general, this should be used via `with-open`:
```clojure
(with-open [stmt (prepare spec sql-params opts)] (with-open [stmt (prepare spec sql-params opts)]
(run-some-ops stmt)) (run-some-ops stmt))
```
See the list of options above (in the namespace docstring) for what can See the list of options above (in the namespace docstring) for what can
be passed to prepare." be passed to prepare."
@ -128,8 +133,8 @@
Returns a reducible that, when reduced, runs the SQL and yields the result. Returns a reducible that, when reduced, runs the SQL and yields the result.
Can be called on a PreparedStatement, a Connection, or something that can Can be called on a `PreparedStatement`, a `Connection`, or something that can
produce a Connection via a DataSource." produce a `Connection` via a `DataSource`."
([stmt] ([stmt]
(p/-execute stmt [] {})) (p/-execute stmt [] {}))
([connectable sql-params] ([connectable sql-params]
@ -140,10 +145,10 @@
(defn execute! (defn execute!
"General SQL execution function. "General SQL execution function.
Invokes 'reducible!' and then reduces that into a vector of hash maps. Returns a fully-realized result set.
Can be called on a PreparedStatement, a Connection, or something that can Can be called on a `PreparedStatement`, a `Connection`, or something that can
produce a Connection via a DataSource." produce a `Connection` via a `DataSource`."
([stmt] ([stmt]
(p/-execute-all stmt [] {})) (p/-execute-all stmt [] {}))
([connectable sql-params] ([connectable sql-params]
@ -154,8 +159,8 @@
(defn execute-one! (defn execute-one!
"General SQL execution function that returns just the first row of a result. "General SQL execution function that returns just the first row of a result.
Can be called on a PreparedStatement, a Connection, or something that can Can be called on a `PreparedStatement`, a `Connection`, or something that can
produce a Connection via a DataSource." produce a `Connection` via a `DataSource`."
([stmt] ([stmt]
(p/-execute-one stmt [] {})) (p/-execute-one stmt [] {}))
([connectable sql-params] ([connectable sql-params]
@ -164,7 +169,7 @@
(p/-execute-one connectable sql-params opts))) (p/-execute-one connectable sql-params opts)))
(defn transact (defn transact
"Given a connectable object and a function (taking a Connection), "Given a connectable object and a function (taking a `Connection`),
execute the function on a new connection in a transactional manner. execute the function on a new connection in a transactional manner.
See `with-transaction` for supported options." See `with-transaction` for supported options."
@ -174,14 +179,14 @@
(p/-transact connectable f opts))) (p/-transact connectable f opts)))
(defmacro with-transaction (defmacro with-transaction
"Given a connectable object, gets a new connection and binds it to 'sym', "Given a connectable object, gets a new connection and binds it to `sym`,
then executes the 'body' in that context, committing any changes if the body then executes the `body` in that context, committing any changes if the body
completes successfully, otherwise rolling back any changes made. completes successfully, otherwise rolling back any changes made.
The options map supports: The options map supports:
* isolation -- :none, :read-committed, :read-uncommitted, :repeatable-read, * `:isolation` -- `:none`, `:read-committed`, `:read-uncommitted`,
:serializable, `:repeatable-read`, `:serializable`,
* :read-only -- true / false, * `:read-only` -- `true` / `false`,
* :rollback-only -- true / false." * `:rollback-only` -- `true` / `false`."
[[sym connectable opts] & body] [[sym connectable opts] & body]
`(transact ~connectable (^{:once true} fn* [~sym] ~@body) ~opts)) `(transact ~connectable (^{:once true} fn* [~sym] ~@body) ~opts))

View file

@ -1,7 +1,7 @@
;; copyright (c) 2018-2019 Sean Corfield, all rights reserved ;; copyright (c) 2018-2019 Sean Corfield, all rights reserved
(ns next.jdbc.connection (ns next.jdbc.connection
"Standard implementations of get-datasource and get-connection." "Standard implementations of `get-datasource` and `get-connection`."
(:require [next.jdbc.protocols :as p]) (:require [next.jdbc.protocols :as p])
(:import (java.sql Connection DriverManager) (:import (java.sql Connection DriverManager)
(javax.sql DataSource) (javax.sql DataSource)
@ -10,9 +10,9 @@
(set! *warn-on-reflection* true) (set! *warn-on-reflection* true)
(def ^:private classnames (def ^:private classnames
"Map of subprotocols to classnames. dbtype specifies one of these keys. "Map of subprotocols to classnames. `:dbtype` specifies one of these keys.
The subprotocols map below provides aliases for dbtype. The subprotocols map below provides aliases for `:dbtype`.
Most databases have just a single class name for their driver but we Most databases have just a single class name for their driver but we
support a sequence of class names to try in order to allow for drivers support a sequence of class names to try in order to allow for drivers
@ -33,7 +33,7 @@
"sqlserver" "com.microsoft.sqlserver.jdbc.SQLServerDriver"}) "sqlserver" "com.microsoft.sqlserver.jdbc.SQLServerDriver"})
(def ^:private aliases (def ^:private aliases
"Map of schemes to subprotocols. Used to provide aliases for dbtype." "Map of schemes to subprotocols. Used to provide aliases for `:dbtype`."
{"hsql" "hsqldb" {"hsql" "hsqldb"
"jtds" "jtds:sqlserver" "jtds" "jtds:sqlserver"
"mssql" "sqlserver" "mssql" "sqlserver"
@ -43,7 +43,7 @@
(def ^:private host-prefixes (def ^:private host-prefixes
"Map of subprotocols to non-standard host-prefixes. "Map of subprotocols to non-standard host-prefixes.
Anything not listed is assumed to use //." Anything not listed is assumed to use `//`."
{"oracle:oci" "@" {"oracle:oci" "@"
"oracle:thin" "@"}) "oracle:thin" "@"})
@ -58,14 +58,13 @@
"sqlserver" 1433}) "sqlserver" 1433})
(def ^:private dbname-separators (def ^:private dbname-separators
"Map of schemes to separators. The default is / but a couple are different." "Map of schemes to separators. The default is `/` but a couple are different."
{"mssql" ";DATABASENAME=" {"mssql" ";DATABASENAME="
"sqlserver" ";DATABASENAME=" "sqlserver" ";DATABASENAME="
"oracle:sid" ":"}) "oracle:sid" ":"})
(defn- ^Properties as-properties (defn- ^Properties as-properties
"Convert any seq of pairs to a java.util.Properties instance. "Convert any seq of pairs to a `java.util.Properties` instance."
Uses as-sql-name to convert both keys and values into strings."
[m] [m]
(let [p (Properties.)] (let [p (Properties.)]
(doseq [[k v] m] (doseq [[k v] m]
@ -73,8 +72,8 @@
p)) p))
(defn- get-driver-connection (defn- get-driver-connection
"Common logic for loading the DriverManager and the designed JDBC driver "Common logic for loading the `DriverManager` and the designed JDBC driver
class and obtaining the appropriate Connection object." class and obtaining the appropriate `Connection` object."
[url etc] [url etc]
;; force DriverManager to be loaded ;; force DriverManager to be loaded
(DriverManager/getLoginTimeout) (DriverManager/getLoginTimeout)
@ -130,7 +129,7 @@
[s {}]) [s {}])
(defn- url+etc->datasource (defn- url+etc->datasource
"Given a JDBC URL and a map of options, return a DataSource that can be "Given a JDBC URL and a map of options, return a `DataSource` that can be
used to obtain a new database connection." used to obtain a new database connection."
[[url etc]] [[url etc]]
(reify DataSource (reify DataSource
@ -143,13 +142,13 @@
:password password))))) :password password)))))
(defn- make-connection (defn- make-connection
"Given a DataSource and a map of options, get a connection and update it "Given a `DataSource` and a map of options, get a connection and update it
as specified by the options. as specified by the options.
The options supported are: The options supported are:
* :auto-commit -- whether the connection should be set to auto-commit or not; * `:auto-commit` -- whether the connection should be set to auto-commit or not;
without this option, the defaut is true -- connections will auto-commit, without this option, the defaut is `true` -- connections will auto-commit,
* :read-only -- whether the connection should be set to read-only mode." * `:read-only` -- whether the connection should be set to read-only mode."
^Connection ^Connection
[^DataSource datasource opts] [^DataSource datasource opts]
(let [^Connection connection (.getConnection datasource)] (let [^Connection connection (.getConnection datasource)]

View file

@ -1,13 +1,13 @@
;; copyright (c) 2018-2019 Sean Corfield, all rights reserved ;; copyright (c) 2018-2019 Sean Corfield, all rights reserved
(ns next.jdbc.prepare (ns next.jdbc.prepare
"Mostly an implementation namespace for how PreparedStatement objects are "Mostly an implementation namespace for how `PreparedStatement objects` are
created by the next generation java.jdbc library. created by the next generation java.jdbc library.
set-parameters is public and may be useful if you have a PreparedStatement `set-parameters` is public and may be useful if you have a `PreparedStatement`
that you wish to reuse and (re)set the parameters on it. that you wish to reuse and (re)set the parameters on it.
Defines the SettableParameter protocol for converting Clojure values Defines the `SettableParameter` protocol for converting Clojure values
to database-specific values." to database-specific values."
(:require [next.jdbc.protocols :as p]) (:require [next.jdbc.protocols :as p])
(:import (java.sql Connection (:import (java.sql Connection
@ -20,8 +20,8 @@
(defprotocol SettableParameter :extend-via-metadata true (defprotocol SettableParameter :extend-via-metadata true
"Protocol for setting SQL parameters in statement objects, which "Protocol for setting SQL parameters in statement objects, which
can convert from Clojure values. The default implementation just can convert from Clojure values. The default implementation just
calls .setObject on the parameter value. It can be extended to use other calls `.setObject` on the parameter value. It can be extended to use other
methods of PreparedStatement to convert and set parameter values." methods of `PreparedStatement` to convert and set parameter values."
(set-parameter [val stmt ix] (set-parameter [val stmt ix]
"Convert a Clojure value into a SQL value and store it as the ix'th "Convert a Clojure value into a SQL value and store it as the ix'th
parameter in the given SQL statement object.")) parameter in the given SQL statement object."))
@ -36,8 +36,8 @@
(.setObject s i nil))) (.setObject s i nil)))
(defn set-parameters (defn set-parameters
"Given a PreparedStatement and a vector of parameter values, update the "Given a `PreparedStatement` and a vector of parameter values, update the
PreparedStatement with those parameters and return it." `PreparedStatement` with those parameters and return it."
^java.sql.PreparedStatement ^java.sql.PreparedStatement
[^PreparedStatement ps params] [^PreparedStatement ps params]
(when (seq params) (when (seq params)
@ -48,19 +48,19 @@
ps) ps)
(def ^{:private true (def ^{:private true
:doc "Map friendly :concurrency values to ResultSet constants."} :doc "Map friendly `:concurrency` values to `ResultSet` constants."}
result-set-concurrency result-set-concurrency
{:read-only ResultSet/CONCUR_READ_ONLY {:read-only ResultSet/CONCUR_READ_ONLY
:updatable ResultSet/CONCUR_UPDATABLE}) :updatable ResultSet/CONCUR_UPDATABLE})
(def ^{:private true (def ^{:private true
:doc "Map friendly :cursors values to ResultSet constants."} :doc "Map friendly `:cursors` values to `ResultSet` constants."}
result-set-holdability result-set-holdability
{:hold ResultSet/HOLD_CURSORS_OVER_COMMIT {:hold ResultSet/HOLD_CURSORS_OVER_COMMIT
:close ResultSet/CLOSE_CURSORS_AT_COMMIT}) :close ResultSet/CLOSE_CURSORS_AT_COMMIT})
(def ^{:private true (def ^{:private true
:doc "Map friendly :type values to ResultSet constants."} :doc "Map friendly `:type` values to `ResultSet` constants."}
result-set-type result-set-type
{:forward-only ResultSet/TYPE_FORWARD_ONLY {:forward-only ResultSet/TYPE_FORWARD_ONLY
:scroll-insensitive ResultSet/TYPE_SCROLL_INSENSITIVE :scroll-insensitive ResultSet/TYPE_SCROLL_INSENSITIVE
@ -71,8 +71,8 @@
(into-array String return-keys)) (into-array String return-keys))
(defn create (defn create
"Given a connection, a SQL string, some parameters, and some options, "Given a `Connection`, a SQL string, some parameters, and some options,
return a PreparedStatement representing that." return a `PreparedStatement` representing that."
^java.sql.PreparedStatement ^java.sql.PreparedStatement
[^Connection con ^String sql params [^Connection con ^String sql params
{:keys [return-keys result-type concurrency cursors {:keys [return-keys result-type concurrency cursors

View file

@ -3,52 +3,52 @@
(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.
Sourceable protocol: `Sourceable` protocol:
get-datasource -- turn something into a javax.sql.DataSource; implementations `get-datasource` -- turn something into a `javax.sql.DataSource`; implementations
are provided for strings, hash maps (db-spec structures), and also a are provided for strings, hash maps (`db-spec` structures), and also a
DataSource (which just returns itself). `DataSource` (which just returns itself).
Connectable protocol: `Connectable` protocol:
get-connection -- create a new JDBC connection that should be closed when you `get-connection` -- create a new JDBC connection that should be closed when you
are finished with it; implementations are provided for DataSource and are finished with it; implementations are provided for `DataSource`,
Object, on the assumption that an Object can possibly be turned into a `PreparedStatement`, and `Object`, on the assumption that an `Object`
DataSource. can possibly be turned into a `DataSource`.
Executable protocol: `Executable` protocol:
-execute -- given SQL and parameters, produce a 'reducible' that, when `-execute` -- given SQL and parameters, produce a 'reducible' that, when
reduced, executes the SQL and produces a ResultSet that can be processed; reduced, executes the SQL and produces a `ResultSet` that can be processed;
implementations are provided for Connection, DataSource, implementations are provided for `Connection`, `DataSource`,
PreparedStatement, and Object (on the assumption that an Object can be `PreparedStatement`, and `Object` (on the assumption that an `Object` can be
turned into a DataSource and therefore used to get a Connection). turned into a `DataSource` and therefore used to get a `Connection`).
-execute-one -- given SQL and parameters, executes the SQL and produces `-execute-one` -- given SQL and parameters, executes the SQL and produces
the first row of the ResultSet as a datafiable hash map (by default); the first row of the `ResultSet` as a datafiable hash map (by default);
implementations are provided for Connection, DataSource, implementations are provided for `Connection`, `DataSource`,
PreparedStatement, and Object (on the assumption that an Object can be `PreparedStatement`, and `Object` (on the assumption that an `Object` can be
turned into a DataSource and therefore used to get a Connection). turned into a `DataSource` and therefore used to get a `Connection`).
-execute-all -- given SQL and parameters, executes the SQL and produces `-execute-all` -- given SQL and parameters, executes the SQL and produces
either a vector of datafiable hash maps from the ResultSet (default) either a vector of datafiable hash maps from the `ResultSet` (default)
or a vector of column names followed by vectors of row values; or a vector of column names followed by vectors of row values;
implementations are provided for Connection, DataSource, implementations are provided for `Connection`, `DataSource`,
PreparedStatement, and Object (on the assumption that an Object can be `PreparedStatement`, and `Object` (on the assumption that an `Object` can be
turned into a DataSource and therefore used to get a Connection). turned into a `DataSource` and therefore used to get a `Connection`).
Preparable protocol: `Preparable` protocol:
prepare -- given SQL and parameters, produce a PreparedStatement that can `prepare` -- given SQL and parameters, produce a `PreparedStatement` that can
be executed (by -execute above); implementation is provided for be executed (by -execute above); implementation is provided for
Connection. `Connection` only.
Transactable protocol: `Transactable` protocol:
-transact -- given a function (presumably containing SQL operations), `-transact` -- given a function (presumably containing SQL operations),
run the function inside a SQL transaction; implementations are provided run the function inside a SQL transaction; implementations are provided
for Connection, DataSource, and Object (on the assumption that an Object for `Connection`, `DataSource`, and `Object` (on the assumption that an
can be turned into a DataSource).") `Object` can be turned into a `DataSource`).")
(set! *warn-on-reflection* true) (set! *warn-on-reflection* true)
(defprotocol Sourceable :extend-via-metadata true (defprotocol Sourceable :extend-via-metadata true
(get-datasource ^javax.sql.DataSource [this] "Turn this into a javax.sql.DataSource.")) (get-datasource ^javax.sql.DataSource [this]))
(defprotocol Connectable (defprotocol Connectable
(get-connection ^java.lang.AutoCloseable [this opts])) (get-connection ^java.lang.AutoCloseable [this opts]))
(defprotocol Executable (defprotocol Executable

View file

@ -1,7 +1,7 @@
;; copyright (c) 2019 Sean Corfield, all rights reserved ;; copyright (c) 2019 Sean Corfield, all rights reserved
(ns next.jdbc.quoted (ns next.jdbc.quoted
"Provides functions for use with the :table-fn and :column-fn options "Provides functions for use with the `:table-fn` and `:column-fn` options
that define how SQL entities should be quoted in strings constructed that define how SQL entities should be quoted in strings constructed
from Clojure data." from Clojure data."
(:require [clojure.string :as str])) (:require [clojure.string :as str]))
@ -19,9 +19,11 @@
(defn schema (defn schema
"Given a quoting function, return a new quoting function that will "Given a quoting function, return a new quoting function that will
process schema-qualified names by quoting each segment: process schema-qualified names by quoting each segment:
```clojure
(mysql :foo.bar) ;=> `foo.bar` (mysql (name :foo.bar)) ;=> `foo.bar`
((schema mysql) :foo.bar) ;=> `foo`.`bar`" ((schema mysql) (name :foo.bar)) ;=> `foo`.`bar`
```
"
[quoting] [quoting]
(fn [s] (fn [s]
(->> (str/split s #"\.") (->> (str/split s #"\.")

View file

@ -1,16 +1,16 @@
;; copyright (c) 2018-2019 Sean Corfield, all rights reserved ;; copyright (c) 2018-2019 Sean Corfield, all rights reserved
(ns next.jdbc.result-set (ns next.jdbc.result-set
"An implementation of ResultSet handling functions. "An implementation of `ResultSet` handling functions.
Defines the following protocols: Defines the following protocols:
* ReadableColumn -- to read column values by label or index * `DatafiableRow` -- for turning a row into something datafiable
* RowBuilder -- for materializing a row * `ReadableColumn` -- to read column values by label or index
* ResultSetBuilder -- for materializing a result set * `RowBuilder` -- for materializing a row
* DatafiableRow -- for turning a row into something datafiable * `ResultSetBuilder` -- for materializing a result set
Also provides the default implemenations for Executable and Also provides the default implemenations for `Executable` and
the default datafy/nav behavior for rows from a result set." the default `datafy`/`nav` behavior for rows from a result set."
(:require [clojure.core.protocols :as core-p] (:require [clojure.core.protocols :as core-p]
[clojure.string :as str] [clojure.string :as str]
[next.jdbc.prepare :as prepare] [next.jdbc.prepare :as prepare]
@ -22,7 +22,7 @@
(set! *warn-on-reflection* true) (set! *warn-on-reflection* true)
(defn get-column-names (defn get-column-names
"Given ResultSetMetaData, return a vector of column names, each qualified by "Given `ResultSetMetaData`, return a vector of column names, each qualified by
the table from which it came." the table from which it came."
[^ResultSetMetaData rsmeta opts] [^ResultSetMetaData rsmeta opts]
(mapv (fn [^Integer i] (keyword (not-empty (.getTableName rsmeta i)) (mapv (fn [^Integer i] (keyword (not-empty (.getTableName rsmeta i))
@ -30,13 +30,13 @@
(range 1 (inc (.getColumnCount rsmeta))))) (range 1 (inc (.getColumnCount rsmeta)))))
(defn get-unqualified-column-names (defn get-unqualified-column-names
"Given ResultSetMetaData, return a vector of unqualified column names." "Given `ResultSetMetaData`, return a vector of unqualified column names."
[^ResultSetMetaData rsmeta opts] [^ResultSetMetaData rsmeta opts]
(mapv (fn [^Integer i] (keyword (.getColumnLabel rsmeta i))) (mapv (fn [^Integer i] (keyword (.getColumnLabel rsmeta i)))
(range 1 (inc (.getColumnCount rsmeta))))) (range 1 (inc (.getColumnCount rsmeta)))))
(defn get-lower-column-names (defn get-lower-column-names
"Given ResultSetMetaData, return a vector of lower-case column names, each "Given `ResultSetMetaData`, return a vector of lower-case column names, each
qualified by the table from which it came." qualified by the table from which it came."
[^ResultSetMetaData rsmeta opts] [^ResultSetMetaData rsmeta opts]
(mapv (fn [^Integer i] (keyword (some-> (.getTableName rsmeta i) (mapv (fn [^Integer i] (keyword (some-> (.getTableName rsmeta i)
@ -47,15 +47,15 @@
(range 1 (inc (.getColumnCount rsmeta))))) (range 1 (inc (.getColumnCount rsmeta)))))
(defn get-unqualified-lower-column-names (defn get-unqualified-lower-column-names
"Given ResultSetMetaData, return a vector of unqualified column names." "Given `ResultSetMetaData`, return a vector of unqualified column names."
[^ResultSetMetaData rsmeta opts] [^ResultSetMetaData rsmeta opts]
(mapv (fn [^Integer i] (keyword (str/lower-case (.getColumnLabel rsmeta i)))) (mapv (fn [^Integer i] (keyword (str/lower-case (.getColumnLabel rsmeta i))))
(range 1 (inc (.getColumnCount rsmeta))))) (range 1 (inc (.getColumnCount rsmeta)))))
(defprotocol ReadableColumn (defprotocol ReadableColumn
"Protocol for reading objects from the java.sql.ResultSet. Default "Protocol for reading objects from the `java.sql.ResultSet`. Default
implementations (for Object and nil) return the argument, and the implementations (for `Object` and `nil`) return the argument, and the
Boolean implementation ensures a canonicalized true/false value, `Boolean` implementation ensures a canonicalized `true`/`false` value,
but it can be extended to provide custom behavior for special types." but it can be extended to provide custom behavior for special types."
(read-column-by-label [val label] (read-column-by-label [val label]
"Function for transforming values after reading them via a column label.") "Function for transforming values after reading them via a column label.")
@ -77,13 +77,13 @@
(defprotocol RowBuilder (defprotocol RowBuilder
"Protocol for building rows in various representations: "Protocol for building rows in various representations:
->row -- called once per row to create the basis of each row `->row` -- called once per row to create the basis of each row
column-count -- return the number of columns in each row `column-count` -- return the number of columns in each row
with-column -- called with the row and the index of the column to be added; `with-column` -- called with the row and the index of the column to be added;
this is expected to read the column value from the ResultSet! this is expected to read the column value from the `ResultSet`!
row! -- called once per row to finalize each row once it is complete `row!` -- called once per row to finalize each row once it is complete
The default implementation for building hash maps: MapResultSetBuilder" The default implementation for building hash maps: `MapResultSetBuilder`"
(->row [_]) (->row [_])
(column-count [_]) (column-count [_])
(with-column [_ row i]) (with-column [_ row i])
@ -91,12 +91,12 @@
(defprotocol ResultSetBuilder (defprotocol ResultSetBuilder
"Protocol for building result sets in various representations: "Protocol for building result sets in various representations:
->rs -- called to create the basis of the result set `->rs` -- called to create the basis of the result set
with-row -- called with the result set and the row to be added `with-row` -- called with the result set and the row to be added
rs! -- called to finalize the result set once it is complete `rs!` -- called to finalize the result set once it is complete
Default implementations for building vectors of hash maps and vectors Default implementations for building vectors of hash maps and vectors
of column names and row values: MapResultSetBuilder & ArrayResultSetBuilder" of column names and row values: `MapResultSetBuilder` & `ArrayResultSetBuilder`"
(->rs [_]) (->rs [_])
(with-row [_ rs row]) (with-row [_ rs row])
(rs! [_ rs])) (rs! [_ rs]))
@ -117,7 +117,7 @@
(rs! [this mrs] (persistent! mrs))) (rs! [this mrs] (persistent! mrs)))
(defn as-maps (defn as-maps
"Given a ResultSet and options, return a RowBuilder / ResultSetBuilder "Given a `ResultSet` and options, return a `RowBuilder` / R`esultSetBuilder`
that produces bare vectors of hash map rows." that produces bare vectors of hash map rows."
[^ResultSet rs opts] [^ResultSet rs opts]
(let [rsmeta (.getMetaData rs) (let [rsmeta (.getMetaData rs)
@ -125,7 +125,7 @@
(->MapResultSetBuilder rs rsmeta cols))) (->MapResultSetBuilder rs rsmeta cols)))
(defn as-unqualified-maps (defn as-unqualified-maps
"Given a ResultSet and options, return a RowBuilder / ResultSetBuilder "Given a `ResultSet` and options, return a `RowBuilder` / `ResultSetBuilder`
that produces bare vectors of hash map rows, with simple keys." that produces bare vectors of hash map rows, with simple keys."
[^ResultSet rs opts] [^ResultSet rs opts]
(let [rsmeta (.getMetaData rs) (let [rsmeta (.getMetaData rs)
@ -133,7 +133,7 @@
(->MapResultSetBuilder rs rsmeta cols))) (->MapResultSetBuilder rs rsmeta cols)))
(defn as-lower-maps (defn as-lower-maps
"Given a ResultSet and options, return a RowBuilder / ResultSetBuilder "Given a `ResultSet` and options, return a `RowBuilder` / `ResultSetBuilder`
that produces bare vectors of hash map rows, with lower-case keys." that produces bare vectors of hash map rows, with lower-case keys."
[^ResultSet rs opts] [^ResultSet rs opts]
(let [rsmeta (.getMetaData rs) (let [rsmeta (.getMetaData rs)
@ -141,7 +141,7 @@
(->MapResultSetBuilder rs rsmeta cols))) (->MapResultSetBuilder rs rsmeta cols)))
(defn as-unqualified-lower-maps (defn as-unqualified-lower-maps
"Given a ResultSet and options, return a RowBuilder / ResultSetBuilder "Given a `ResultSet` and options, return a `RowBuilder` / `ResultSetBuilder`
that produces bare vectors of hash map rows, with simple, lower-case keys." that produces bare vectors of hash map rows, with simple, lower-case keys."
[^ResultSet rs opts] [^ResultSet rs opts]
(let [rsmeta (.getMetaData rs) (let [rsmeta (.getMetaData rs)
@ -162,7 +162,7 @@
(rs! [this ars] (persistent! ars))) (rs! [this ars] (persistent! ars)))
(defn as-arrays (defn as-arrays
"Given a ResultSet and options, return a RowBuilder / ResultSetBuilder "Given a `ResultSet` and options, return a `RowBuilder` / `ResultSetBuilder`
that produces a vector of column names followed by vectors of row values." that produces a vector of column names followed by vectors of row values."
[^ResultSet rs opts] [^ResultSet rs opts]
(let [rsmeta (.getMetaData rs) (let [rsmeta (.getMetaData rs)
@ -170,7 +170,7 @@
(->ArrayResultSetBuilder rs rsmeta cols))) (->ArrayResultSetBuilder rs rsmeta cols)))
(defn as-unqualified-arrays (defn as-unqualified-arrays
"Given a ResultSet and options, return a RowBuilder / ResultSetBuilder "Given a `ResultSet` and options, return a `RowBuilder` / `ResultSetBuilder`
that produces a vector of simple column names followed by vectors of row that produces a vector of simple column names followed by vectors of row
values." values."
[^ResultSet rs opts] [^ResultSet rs opts]
@ -179,7 +179,7 @@
(->ArrayResultSetBuilder rs rsmeta cols))) (->ArrayResultSetBuilder rs rsmeta cols)))
(defn as-lower-arrays (defn as-lower-arrays
"Given a ResultSet and options, return a RowBuilder / ResultSetBuilder "Given a `ResultSet` and options, return a `RowBuilder` / `ResultSetBuilder`
that produces a vector of lower-case column names followed by vectors of that produces a vector of lower-case column names followed by vectors of
row values." row values."
[^ResultSet rs opts] [^ResultSet rs opts]
@ -188,7 +188,7 @@
(->ArrayResultSetBuilder rs rsmeta cols))) (->ArrayResultSetBuilder rs rsmeta cols)))
(defn as-unqualified-lower-arrays (defn as-unqualified-lower-arrays
"Given a ResultSet and options, return a RowBuilder / ResultSetBuilder "Given a `ResultSet` and options, return a `RowBuilder` / `ResultSetBuilder`
that produces a vector of simple, lower-case column names followed by that produces a vector of simple, lower-case column names followed by
vectors of row values." vectors of row values."
[^ResultSet rs opts] [^ResultSet rs opts]
@ -200,11 +200,11 @@
(defprotocol DatafiableRow (defprotocol DatafiableRow
"Given a connectable object, return a function that knows how to turn a row "Given a connectable object, return a function that knows how to turn a row
into a datafiable object that can be 'nav'igated." into a datafiable object that can be `nav`igated."
(datafiable-row [this connectable opts])) (datafiable-row [this connectable opts]))
(defn- row-builder (defn- row-builder
"Given a RowBuilder -- a row materialization strategy -- produce a fully "Given a `RowBuilder` -- a row materialization strategy -- produce a fully
materialized row from it." materialized row from it."
[gen] [gen]
(->> (reduce (fn [r i] (with-column gen r i)) (->> (reduce (fn [r i] (with-column gen r i))
@ -213,21 +213,21 @@
(row! gen))) (row! gen)))
(defn- mapify-result-set (defn- mapify-result-set
"Given a result set, return an object that wraps the current row as a hash "Given a `ResultSet`, return an object that wraps the current row as a hash
map. Note that a result set is mutable and the current row will change behind map. Note that a result set is mutable and the current row will change behind
this wrapper so operations need to be eager (and fairly limited). this wrapper so operations need to be eager (and fairly limited).
In particular, this does not satisfy `map?` because it does not implement In particular, this does not satisfy `map?` because it does not implement
all of IPersistentMap. all of `IPersistentMap`.
Supports ILookup (keywords are treated as strings). Supports `ILookup` (keywords are treated as strings).
Supports Associative (again, keywords are treated as strings). If you assoc, Supports `Associative` (again, keywords are treated as strings). If you `assoc`,
a full row will be realized (via `row-builder` above). a full row will be realized (via `row-builder` above).
Supports Seqable which realizes a full row of the data. Supports `Seqable` which realizes a full row of the data.
Supports DatafiableRow (which realizes a full row of the data)." Supports `DatafiableRow` (which realizes a full row of the data)."
[^ResultSet rs opts] [^ResultSet rs opts]
(let [gen (delay ((get opts :gen-fn as-maps) rs opts))] (let [gen (delay ((get opts :gen-fn as-maps) rs opts))]
(reify (reify
@ -279,7 +279,7 @@
{`core-p/datafy (navize-row connectable opts)}))) {`core-p/datafy (navize-row connectable opts)})))
(defn- stmt->result-set (defn- stmt->result-set
"Given a PreparedStatement and options, execute it and return a ResultSet "Given a `PreparedStatement` and options, execute it and return a `ResultSet`
if possible." if possible."
^ResultSet ^ResultSet
[^PreparedStatement stmt opts] [^PreparedStatement stmt opts]
@ -291,12 +291,12 @@
(catch Exception _))))) (catch Exception _)))))
(defn- reduce-stmt (defn- reduce-stmt
"Execute the PreparedStatement, attempt to get either its ResultSet or "Execute the `PreparedStatement`, attempt to get either its `ResultSet` or
its generated keys (as a ResultSet), and reduce that using the supplied its generated keys (as a `ResultSet`), and reduce that using the supplied
function and initial value. function and initial value.
If the statement yields neither a ResultSet nor generated keys, return If the statement yields neither a `ResultSet` nor generated keys, return
a hash map containing :next.jdbc/update-count and the number of rows a hash map containing `:next.jdbc/update-count` and the number of rows
updated, with the supplied function and initial value applied." updated, with the supplied function and initial value applied."
[^PreparedStatement stmt f init opts] [^PreparedStatement stmt f init opts]
(if-let [rs (stmt->result-set stmt opts)] (if-let [rs (stmt->result-set stmt opts)]
@ -424,7 +424,7 @@
(defn- default-schema (defn- default-schema
"The default schema lookup rule for column names. "The default schema lookup rule for column names.
If a column name ends with _id or id, it is assumed to be a foreign key If a column name ends with `_id` or `id`, it is assumed to be a foreign key
into the table identified by the first part of the column name." into the table identified by the first part of the column name."
[col] [col]
(let [[_ table] (re-find #"(?i)^(.+?)_?id$" (name col))] (let [[_ table] (re-find #"(?i)^(.+?)_?id$" (name col))]
@ -433,19 +433,19 @@
(defn- navize-row (defn- navize-row
"Given a connectable object, return a function that knows how to turn a row "Given a connectable object, return a function that knows how to turn a row
into a navigable object. into a `nav`igable object.
A `:schema` option can provide a map from qualified column names A `:schema` option can provide a map from qualified column names
(`:<table>/<column>`) to tuples that indicate for which table they are a (`:<table>/<column>`) to tuples that indicate for which table they are a
foreign key, the name of the key within that table, and (optionality) the foreign key, the name of the key within that table, and (optionality) the
cardinality of that relationship (`:many`, `:one`). cardinality of that relationship (`:many`, `:one`).
If no `:schema` item is provided for a column, the convention of <table>id or If no `:schema` item is provided for a column, the convention of `<table>id` or
<table>_id is used, and the assumption is that such columns are foreign keys `<table>_id` is used, and the assumption is that such columns are foreign keys
in the <table> portion of their name, the key is called `id`, and the in the `<table>` portion of their name, the key is called `id`, and the
cardinality is :one. cardinality is `:one`.
Rows are looked up using `-execute-all` or `-execute-one` and the `:table-fn` Rows are looked up using `-execute-all` or `-execute-one`, and the `:table-fn`
option, if provided, is applied to both the assumed table name and the option, if provided, is applied to both the assumed table name and the
assumed foreign key column name." assumed foreign key column name."
[connectable opts] [connectable opts]

View file

@ -221,12 +221,12 @@
(execute! connectable (for-query table key-map opts) opts))) (execute! connectable (for-query table key-map opts) opts)))
(defn get-by-id (defn get-by-id
"Syntactic sugar over execute-one! to make certain common queries easier. "Syntactic sugar over `execute-one!` to make certain common queries easier.
Given a connectable object, a table name, and a primary key value, returns Given a connectable object, a table name, and a primary key value, returns
a hash map of the first row that matches. a hash map of the first row that matches.
By default, the primary key is assumed to be 'id' but that can be overridden By default, the primary key is assumed to be `id` but that can be overridden
in the five-argument call." in the five-argument call."
([connectable table pk] ([connectable table pk]
(get-by-id connectable table pk :id {})) (get-by-id connectable table pk :id {}))
@ -236,7 +236,7 @@
(execute-one! connectable (for-query table {pk-name pk} opts) opts))) (execute-one! connectable (for-query table {pk-name pk} opts) opts)))
(defn update! (defn update!
"Syntactic sugar over execute-one! to make certain common updates easier. "Syntactic sugar over `execute-one!` to make certain common updates easier.
Given a connectable object, a table name, a hash map of columns and values Given a connectable object, a table name, a hash map of columns and values
to set, and either a hash map of columns and values to search on or a vector to set, and either a hash map of columns and values to search on or a vector
@ -249,7 +249,7 @@
opts))) opts)))
(defn delete! (defn delete!
"Syntactic sugar over execute-one! to make certain common deletes easier. "Syntactic sugar over `execute-one!` to make certain common deletes easier.
Given a connectable object, a table name, and either a hash map of columns Given a connectable object, a table name, and either a hash map of columns
and values to search on or a vector of a SQL where clause and parameters, and values to search on or a vector of a SQL where clause and parameters,