diff --git a/doc/all-the-options.md b/doc/all-the-options.md index 83323d2..6c0856d 100644 --- a/doc/all-the-options.md +++ b/doc/all-the-options.md @@ -47,7 +47,7 @@ Any function that creates a `PreparedStatement` will accept the following option * `:fetch-size` -- an integer that guides the JDBC driver in terms of how many rows to fetch at once; it is common to set `:fetch-size` to a negative value in order to trigger streaming of result sets -- some JDBC drivers require additional options to be set on the connection _as well_, * `:max-rows` -- an integer that tells the JDBC driver to limit result sets to this many rows, * `:result-type` -- a keyword that affects how the `ResultSet` can be traversed: `:forward-only`, `:scroll-insensitive`, `:scroll-sensitive`, -* `:return-keys` -- a truthy value asks that the JDBC driver return any generated keys created by the operation; it can be `true` or it can be a vector of keywords identifying column names that should be returned, +* `:return-keys` -- a truthy value asks that the JDBC driver to return any generated keys created by the operation; it can be `true` or it can be a vector of keywords identifying column names that should be returned, * `:timeout` -- an integer that specifies the timeout allowed for SQL operations. Not all databases or drivers support all of these options, or all values for any given option. If `:return-keys` is a vector of column names and that is not supported, `next.jdbc` will attempt a generic "return generated keys" option instead. If that is not supported, `next.jdbc` will fall back to a regular SQL operation. If other options are not supported, you may get a `SQLException`. diff --git a/doc/datafy-nav-and-schema.md b/doc/datafy-nav-and-schema.md index db8b4d1..74542e0 100644 --- a/doc/datafy-nav-and-schema.md +++ b/doc/datafy-nav-and-schema.md @@ -2,7 +2,7 @@ Clojure 1.10 introduced a new namespace, [`clojure.datafy`](http://clojure.github.io/clojure/clojure.datafy-api.html), and two new protocols (`Datafiable` and `Navigable`) that allow for generalized, lazy navigation around data structures. Cognitect also released [REBL](http://rebl.cognitect.com/) -- a graphical, interactive tool for browsing Clojure data structures, based on the new `datafy` and `nav` functions. -Shortly after, I added experimental support to `clojure.java.jdbc` for `datafy` and `nav` that supported lazy navigation through result sets into foreign key relationships and connected rows and tables. `next.jdbc` bakes that support into result sets produced by `execute!` and `execute-one!`. +Shortly after REBL's release, I added experimental support to `clojure.java.jdbc` for `datafy` and `nav` that supported lazy navigation through result sets into foreign key relationships and connected rows and tables. `next.jdbc` bakes that support into result sets produced by `execute!` and `execute-one!`. ## The `datafy`/`nav` Lifecycle diff --git a/doc/friendly-sql-functions.md b/doc/friendly-sql-functions.md index b34a8eb..47a4a5b 100644 --- a/doc/friendly-sql-functions.md +++ b/doc/friendly-sql-functions.md @@ -27,7 +27,7 @@ These functions are described in more detail below. They are intended to cover t Given a table name (as a keyword) and a hash map of column names and values, this performs a single row insertion into the database: ```clojure -(sql/insert! ds :address {:name "A. Person" :email "albert@person.org"})` +(sql/insert! ds :address {:name "A. Person" :email "albert@person.org"}) ;; equivalent to (jdbc/execute-one! ds ["INSERT INTO address (name,email) VALUES (?,?)" "A.Person" "albert@person.org"] {:return-keys true}) @@ -42,7 +42,7 @@ Given a table name (as a keyword), a vector of column names, and a vector row va [:name :email] [["Stella" "stella@artois.beer"] ["Waldo" "waldo@lagunitas.beer"] - ["Aunt Sally" "sour@lagunitas.beer"]])` + ["Aunt Sally" "sour@lagunitas.beer"]]) ;; equivalent to (jdbc/execute! ds ["INSERT INTO address (name,email) VALUES (?,?), (?,?), (?,?)" "Stella" "stella@artois.beer" @@ -130,7 +130,7 @@ Note that in order to override the default primary key column name (of `:id`), y ## Table & Column Entity Names -By default, `next.jdbc.sql` constructs SQL strings with the entity names exactly matching the (unqualified) keywords provided. If you are trying to use a table name or column name that is a reserved name in SQL for your database, you will need to tell `next.jdbc.sql` to quote those names. +By default, `next.jdbc.sql` functions construct SQL strings with the entity names exactly matching the (unqualified) keywords provided. If you are trying to use a table name or column name that is a reserved name in SQL for your database, you will need to tell those functions to quote those names. The namespace `next.jdbc.quoted` provides five functions that cover the most common types of entity quoting, and a modifier function for quoting dot-separated names (e.g., that include schemas): diff --git a/doc/migration-from-clojure-java-jdbc.md b/doc/migration-from-clojure-java-jdbc.md index 348ef97..d796c9f 100644 --- a/doc/migration-from-clojure-java-jdbc.md +++ b/doc/migration-from-clojure-java-jdbc.md @@ -38,18 +38,18 @@ The `next.jdbc.sql` namespace contains several functions with similarities to `c * `insert!` -- similar to `clojure.java.jdbc/insert!` but only supports inserting a single map, * `insert-multi!` -- similar to `clojure.java.jdbc/insert-multi!` but only supports inserting columns and a vector of row values, * `query` -- similar to `clojure.java.jdbc/query`, -* `find-by-keys` -- similar to `clojure.java.jdbc/find-by-keys` but also accepts a partial where clause (vector), +* `find-by-keys` -- similar to `clojure.java.jdbc/find-by-keys` but will also accept a partial where clause (vector) instead of a hash map of column name/value pairs, * `get-by-id` -- similar to `clojure.java.jdbc/get-by-id`, -* `update!` -- similar to `clojure.java.jdbc/update!` but also accepts a hash map of column name/value pairs, -* `delete!` -- similar to `clojure.java.jdbc/delete!` but also accepts a hash map of column name/value pairs. +* `update!` -- similar to `clojure.java.jdbc/update!` but will also accept a hash map of column name/value pairs instead of a partial where clause (vector), +* `delete!` -- similar to `clojure.java.jdbc/delete!` but will also accept a hash map of column name/value pairs instead of a partial where clause (vector). -If you are using `:identifiers` and/or `:entities`, you will need to change to appropriate `:builder-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 `:builder-fn` and/or `:table-fn`/`:column-fn` options. For the latter, instead of the `quoted` function, there is the `next.jdbc.quoted` namespace 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!`). Remember that you can terminate a reduction early by using the `reduced` function to wrap the final value you produce. ## Further Minor differences -These are mostly drawn from Issue #5 although most of the bullets in that issue are described in more detail above. +These are mostly drawn from [Issue #5](https://github.com/seancorfield/next-jdbc/issues/5) although most of the bullets in that issue are described in more detail above. * Keyword options no longer end in `?` -- to reflect the latest best practice on predicates vs. attributes, * `with-db-connection` has been replaced by just `with-open` containing a call to `get-connection`, diff --git a/doc/prepared-statements.md b/doc/prepared-statements.md index c8736ab..50d0704 100644 --- a/doc/prepared-statements.md +++ b/doc/prepared-statements.md @@ -24,7 +24,7 @@ This can be extended to any Clojure data type, to provide a customized way to ad (with-meta obj {'next.jdbc.prepare/set-parameter (fn [v ps i]...)}) ``` -`next.jdbc/set-parameters` is available for you to call on any existing `PreparedStatement` to set or update the parameters that will be used when the statement is executed: +`next.jdbc.prepare/set-parameters` is available for you to call on any existing `PreparedStatement` to set or update the parameters that will be used when the statement is executed: * `(set-parameters ps params)` -- loops over a sequence of parameter values and calls `set-parameter` for each one, as above. diff --git a/doc/result-set-builders.md b/doc/result-set-builders.md index 7d8f497..80f1a7c 100644 --- a/doc/result-set-builders.md +++ b/doc/result-set-builders.md @@ -40,7 +40,7 @@ Only `execute!` expects this protocol to be implemented. `execute-one!` and `red The `as-*` functions described above are all implemented in terms of these protocols. They are passed the `ResultSet` object and the options hash map (as passed into various `next.jdbc` functions). They return an implementation of the protocols that is then used to build rows and the result set. Note that the `ResultSet` passed in is _mutable_ and is advanced from row to row by the SQL execution function, so each time `->row` is called, the underlying `ResultSet` object points at each new row in turn. By contrast, `->rs` (which is only called by `execute!`) is invoked _before_ the `ResultSet` is advanced to the first row. -The options hash map for any `next.jdbc` function can contain a `:builder-fn` key and the value is used at the row/result set builder function. The tests for `next.jdbc.result-set` include a [record-based builder function](https://github.com/seancorfield/next-jdbc/blob/master/test/next/jdbc/result_set_test.clj#L148-L164) as an example of how you can extend this to satisfy your needs. +The options hash map for any `next.jdbc` function can contain a `:builder-fn` key and the value is used as the row/result set builder function. The tests for `next.jdbc.result-set` include a [record-based builder function](https://github.com/seancorfield/next-jdbc/blob/master/test/next/jdbc/result_set_test.clj#L148-L164) as an example of how you can extend this to satisfy your needs. The options hash map passed to the builder function will contain a `:next.jdbc/sql-params` key, whose value is the SQL + parameters vector passed into the top-level `next.jdbc` functions (`reducible!`, `execute!`, and `execute-one!`). diff --git a/src/next/jdbc/protocols.clj b/src/next/jdbc/protocols.clj index 0aa83a1..9286069 100644 --- a/src/next/jdbc/protocols.clj +++ b/src/next/jdbc/protocols.clj @@ -3,11 +3,11 @@ (ns next.jdbc.protocols "This is the extensible core of the next generation java.jdbc library. - `Sourceable` -- for producing `javax.sql.DataSource` objects, - `Connectable` -- for producing new `java.sql.Connection` objects, - `Executable` -- for executing SQL operations, - `Preparable` -- for producing new `java.sql.PreparedStatement` objects, - `Transactable` -- for executing SQL operations transactionally.") + * `Sourceable` -- for producing `javax.sql.DataSource` objects, + * `Connectable` -- for producing new `java.sql.Connection` objects, + * `Executable` -- for executing SQL operations, + * `Preparable` -- for producing new `java.sql.PreparedStatement` objects, + * `Transactable` -- for executing SQL operations transactionally.") (set! *warn-on-reflection* true) diff --git a/src/next/jdbc/result_set.clj b/src/next/jdbc/result_set.clj index 043eed4..9633e2f 100644 --- a/src/next/jdbc/result_set.clj +++ b/src/next/jdbc/result_set.clj @@ -117,8 +117,10 @@ (rs! [this mrs] (persistent! mrs))) (defn as-maps - "Given a `ResultSet` and options, return a `RowBuilder` / R`esultSetBuilder` - that produces bare vectors of hash map rows." + "Given a `ResultSet` and options, return a `RowBuilder` / `ResultSetBuilder` + that produces bare vectors of hash map rows. + + This is the default `:builder-fn` option." [^ResultSet rs opts] (let [rsmeta (.getMetaData rs) cols (get-column-names rsmeta opts)] diff --git a/src/next/jdbc/sql.clj b/src/next/jdbc/sql.clj index 7af1b7c..ba7deb9 100644 --- a/src/next/jdbc/sql.clj +++ b/src/next/jdbc/sql.clj @@ -209,10 +209,11 @@ (defn find-by-keys "Syntactic sugar over `execute!` to make certain common queries easier. - Given a connectable object, a table name, and a hash map of columns and - their values, returns a vector of hash maps of rows that match. + 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, returns a vector of hash maps of rows that match. - If the `:order-by` option is present, add `ORDER BY` clause. `:order-by` + If the `:order-by` option is present, add an `ORDER BY` clause. `:order-by` should be a vector of column names or pairs of column name / direction, which can be `:asc` or `:desc`." ([connectable table key-map]