Rename :gen-fn to :builder-fn
This commit is contained in:
parent
b5f0ef4daa
commit
cf75268087
8 changed files with 61 additions and 57 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
* 2019-04-22 -- 1.0.0-alpha9 -- Fix #14 by respecting `:gen-fn` in `execute-one` for `PreparedStatement`.
|
* 2019-04-22 -- 1.0.0-alpha9 -- Fix #14 by respecting `:gen-fn` (as of 1.0.0-alpha10: `:builder-fn`) in `execute-one` for `PreparedStatement`.
|
||||||
* 2019-04-21 -- 1.0.0-alpha8 -- Initial publicly announced release.
|
* 2019-04-21 -- 1.0.0-alpha8 -- Initial publicly announced release.
|
||||||
|
|
||||||
## Unreleased Changes
|
## Unreleased Changes
|
||||||
|
|
@ -8,3 +8,4 @@
|
||||||
The following changes have been committed to the **master** branch and will be in the next release:
|
The following changes have been committed to the **master** branch and will be in the next release:
|
||||||
|
|
||||||
* Fix #15 by adding `:next.jdbc/sql-string` to options hash map that is passed down into the builder function.
|
* Fix #15 by adding `:next.jdbc/sql-string` to options hash map that is passed down into the builder function.
|
||||||
|
* Rename `:gen-fn` option to `:builder-fn` since the term "builder" is used everywhere.
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,11 @@ The next generation of `clojure.java.jdbc`: a new low-level Clojure wrapper for
|
||||||
|
|
||||||
## TL;DR
|
## TL;DR
|
||||||
|
|
||||||
|
The latest versions on Clojars and on cljdoc:
|
||||||
|
|
||||||
[](https://clojars.org/seancorfield/next.jdbc) [](https://cljdoc.org/d/seancorfield/next.jdbc/CURRENT)
|
[](https://clojars.org/seancorfield/next.jdbc) [](https://cljdoc.org/d/seancorfield/next.jdbc/CURRENT)
|
||||||
|
|
||||||
|
This documentation is for 1.0.0-alpha9.
|
||||||
|
|
||||||
* [Getting Started](/doc/getting-started.md)
|
* [Getting Started](/doc/getting-started.md)
|
||||||
* [Migrating from `clojure.java.jdbc`](/doc/migration-from-clojure-java-jdbc.md)
|
* [Migrating from `clojure.java.jdbc`](/doc/migration-from-clojure-java-jdbc.md)
|
||||||
|
|
@ -35,7 +38,7 @@ From a `DataSource`, either you or `next.jdbc` can create a `java.sql.Connection
|
||||||
|
|
||||||
The primary SQL execution API in `next.jdbc` is:
|
The primary SQL execution API in `next.jdbc` is:
|
||||||
* `reducible!` -- yields an `IReduceInit` that, when reduced, executes the SQL statement and then reduces over the `ResultSet` with as little overhead as possible.
|
* `reducible!` -- yields an `IReduceInit` that, when reduced, executes the SQL statement and then reduces over the `ResultSet` with as little overhead as possible.
|
||||||
* `execute!` -- executes the SQL statement and produces a vector of realized hash maps, that use qualified keywords for the column names, of the form `:<table>/<column>`. If you join across multiple tables, the qualified keywords will reflect the originating tables for each of the columns. If the SQL produces named values that do not come from an associated table, a simple, unqualified keyword will be used. The realized hash maps returned by `execute!` are `Datafiable` and thus `Navigable` (see Clojure 1.10's `datafy` and `nav` functions, and tools like Cognitect's REBL). Alternatively, you can specify `{:gen-fn rs/as-arrays}` and produce a vector with column names followed by vectors of row values. `rs/as-maps` is the default for `:gen-fn` but there are also `rs/as-unqualified-maps` and `rs/as-unqualified-arrays` if you want unqualified `:<column>` column names (and there are also lower-case variants of all of these).
|
* `execute!` -- executes the SQL statement and produces a vector of realized hash maps, that use qualified keywords for the column names, of the form `:<table>/<column>`. If you join across multiple tables, the qualified keywords will reflect the originating tables for each of the columns. If the SQL produces named values that do not come from an associated table, a simple, unqualified keyword will be used. The realized hash maps returned by `execute!` are `Datafiable` and thus `Navigable` (see Clojure 1.10's `datafy` and `nav` functions, and tools like Cognitect's REBL). Alternatively, you can specify `{:builder-fn rs/as-arrays}` and produce a vector with column names followed by vectors of row values. `rs/as-maps` is the default for `:builder-fn` but there are also `rs/as-unqualified-maps` and `rs/as-unqualified-arrays` if you want unqualified `:<column>` column names (and there are also lower-case variants of all of these).
|
||||||
* `execute-one!` -- executes the SQL statement and produces a single realized hash map. The realized hash map returned by `execute-one!` is `Datafiable` and thus `Navigable`.
|
* `execute-one!` -- executes the SQL statement and produces a single realized hash map. The realized hash map returned by `execute-one!` is `Datafiable` and thus `Navigable`.
|
||||||
|
|
||||||
In addition, there are API functions to create `PreparedStatement`s (`prepare`) from `Connection`s, which can be passed to `reducible!`, `execute!`, or `execute-one!`, and to run code inside a transaction (the `transact` function and the `with-transaction` macro).
|
In addition, there are API functions to create `PreparedStatement`s (`prepare`) from `Connection`s, which can be passed to `reducible!`, `execute!`, or `execute-one!`, and to run code inside a transaction (the `transact` function and the `with-transaction` macro).
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ The "friendly" SQL functions all accept the following options:
|
||||||
|
|
||||||
Any function that might realize a row or a result set will accept:
|
Any function that might realize a row or a result set will accept:
|
||||||
|
|
||||||
* `:gen-fn` -- a function that implements the `RowBuilder` and `ResultSetBuilder` protocols; strictly speaking, `reducible!` and `execute-one!` only need `RowBuilder` to be implemented (and `reducible!` only needs that if it actually has to realize a row) but most generation functions will implement both for ease of use.
|
* `:builder-fn` -- a function that implements the `RowBuilder` and `ResultSetBuilder` protocols; strictly speaking, `reducible!` and `execute-one!` only need `RowBuilder` to be implemented (and `reducible!` only needs that if it actually has to realize a row) but most generation functions will implement both for ease of use.
|
||||||
|
|
||||||
## Prepared Statements
|
## Prepared Statements
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,9 @@ This page attempts to list all of the differences between [clojure.java.jdbc](ht
|
||||||
|
|
||||||
### Rows and Result Sets
|
### Rows and Result Sets
|
||||||
|
|
||||||
`clojure.java.jdbc` returned result sets (and generated keys) as hash maps with simple, lower-case keys by default. `next.jdbc` returns result sets (and generated keys) as hash maps with qualified, as-is keys by default: each key is qualified by the name of table from which it is drawn, if known. The as-is default is chosen to a) improve performance and b) not mess with the data. Using a `:gen-fn` option of `next.jdbc.result-set/as-unqualified-maps` will produce simple, as-is keys. Using a `:gen-fn` option of `next.jdbc.result-set/as-unqualified-lower-maps` will produce simple, lower-case keys -- the most compatible with `clojure.java.jdbc`'s default behavior.
|
`clojure.java.jdbc` returned result sets (and generated keys) as hash maps with simple, lower-case keys by default. `next.jdbc` returns result sets (and generated keys) as hash maps with qualified, as-is keys by default: each key is qualified by the name of table from which it is drawn, if known. The as-is default is chosen to a) improve performance and b) not mess with the data. Using a `:builder-fn` option of `next.jdbc.result-set/as-unqualified-maps` will produce simple, as-is keys. Using a `:builder-fn` option of `next.jdbc.result-set/as-unqualified-lower-maps` will produce simple, lower-case keys -- the most compatible with `clojure.java.jdbc`'s default behavior.
|
||||||
|
|
||||||
If you used `:as-arrays? true`, you will need to use a `:gen-fn` option of `next.jdbc.result-set/as-arrays` (or the unqualified or lower variant, as appropriate).
|
If you used `:as-arrays? true`, you will need to use a `:builder-fn` option of `next.jdbc.result-set/as-arrays` (or the unqualified or lower variant, as appropriate).
|
||||||
|
|
||||||
## Primary API
|
## Primary API
|
||||||
|
|
||||||
|
|
@ -43,7 +43,7 @@ The `next.jdbc.sql` namespace contains several functions with similarities to `c
|
||||||
* `update!` -- similar to `clojure.java.jdbc/update!` but also accepts a hash map of column name/value pairs,
|
* `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.
|
* `delete!` -- similar to `clojure.java.jdbc/delete!` but also accepts a hash map of column name/value pairs.
|
||||||
|
|
||||||
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 `: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 `: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.
|
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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 `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 `:gen-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 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 passed to the builder function will contain a `:next.jdbc/sql-string` key, whose value is the SQL string passed into the top-level `next.jdbc` functions (`reducible!`, `execute!`, and `execute-one!`). If no SQL string was passed in -- those functions were called with just a `PreparedStatement` -- then `:next.jdbc/sql-string` will have a `nil` value.
|
The options hash map passed to the builder function will contain a `:next.jdbc/sql-string` key, whose value is the SQL string passed into the top-level `next.jdbc` functions (`reducible!`, `execute!`, and `execute-one!`). If no SQL string was passed in -- those functions were called with just a `PreparedStatement` -- then `:next.jdbc/sql-string` will have a `nil` value.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -214,11 +214,11 @@
|
||||||
(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]
|
[builder]
|
||||||
(->> (reduce (fn [r i] (with-column gen r i))
|
(->> (reduce (fn [r i] (with-column builder r i))
|
||||||
(->row gen)
|
(->row builder)
|
||||||
(range 1 (inc (column-count gen))))
|
(range 1 (inc (column-count builder))))
|
||||||
(row! gen)))
|
(row! builder)))
|
||||||
|
|
||||||
(defn- mapify-result-set
|
(defn- mapify-result-set
|
||||||
"Given a `ResultSet`, 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
|
||||||
|
|
@ -237,7 +237,7 @@
|
||||||
|
|
||||||
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 [builder (delay ((get opts :builder-fn as-maps) rs opts))]
|
||||||
(reify
|
(reify
|
||||||
|
|
||||||
clojure.lang.ILookup
|
clojure.lang.ILookup
|
||||||
|
|
@ -265,16 +265,16 @@
|
||||||
(name k)))
|
(name k)))
|
||||||
(catch SQLException _)))
|
(catch SQLException _)))
|
||||||
(assoc [this k v]
|
(assoc [this k v]
|
||||||
(assoc (row-builder @gen) k v))
|
(assoc (row-builder @builder) k v))
|
||||||
|
|
||||||
clojure.lang.Seqable
|
clojure.lang.Seqable
|
||||||
(seq [this]
|
(seq [this]
|
||||||
(seq (row-builder @gen)))
|
(seq (row-builder @builder)))
|
||||||
|
|
||||||
DatafiableRow
|
DatafiableRow
|
||||||
(datafiable-row [this connectable opts]
|
(datafiable-row [this connectable opts]
|
||||||
(with-meta
|
(with-meta
|
||||||
(row-builder @gen)
|
(row-builder @builder)
|
||||||
{`core-p/datafy (navize-row connectable opts)})))))
|
{`core-p/datafy (navize-row connectable opts)})))))
|
||||||
|
|
||||||
(extend-protocol
|
(extend-protocol
|
||||||
|
|
@ -334,10 +334,10 @@
|
||||||
(rest sql-params)
|
(rest sql-params)
|
||||||
opts)]
|
opts)]
|
||||||
(if-let [rs (stmt->result-set stmt opts)]
|
(if-let [rs (stmt->result-set stmt opts)]
|
||||||
(let [gen-fn (get opts :gen-fn as-maps)
|
(let [builder-fn (get opts :builder-fn as-maps)
|
||||||
gen (gen-fn rs opts)]
|
builder (builder-fn rs opts)]
|
||||||
(when (.next rs)
|
(when (.next rs)
|
||||||
(datafiable-row (row-builder gen) this opts)))
|
(datafiable-row (row-builder builder) this opts)))
|
||||||
{:next.jdbc/update-count (.getUpdateCount stmt)})))
|
{:next.jdbc/update-count (.getUpdateCount stmt)})))
|
||||||
(-execute-all [this sql-params opts]
|
(-execute-all [this sql-params opts]
|
||||||
(with-open [stmt (prepare/create this
|
(with-open [stmt (prepare/create this
|
||||||
|
|
@ -345,14 +345,14 @@
|
||||||
(rest sql-params)
|
(rest sql-params)
|
||||||
opts)]
|
opts)]
|
||||||
(if-let [rs (stmt->result-set stmt opts)]
|
(if-let [rs (stmt->result-set stmt opts)]
|
||||||
(let [gen-fn (get opts :gen-fn as-maps)
|
(let [builder-fn (get opts :builder-fn as-maps)
|
||||||
gen (gen-fn rs opts)]
|
builder (builder-fn rs opts)]
|
||||||
(loop [rs' (->rs gen) more? (.next rs)]
|
(loop [rs' (->rs builder) more? (.next rs)]
|
||||||
(if more?
|
(if more?
|
||||||
(recur (with-row gen rs'
|
(recur (with-row builder rs'
|
||||||
(datafiable-row (row-builder gen) this opts))
|
(datafiable-row (row-builder builder) this opts))
|
||||||
(.next rs))
|
(.next rs))
|
||||||
(rs! gen rs'))))
|
(rs! builder rs'))))
|
||||||
[{:next.jdbc/update-count (.getUpdateCount stmt)}])))
|
[{:next.jdbc/update-count (.getUpdateCount stmt)}])))
|
||||||
|
|
||||||
javax.sql.DataSource
|
javax.sql.DataSource
|
||||||
|
|
@ -372,10 +372,10 @@
|
||||||
(rest sql-params)
|
(rest sql-params)
|
||||||
opts)]
|
opts)]
|
||||||
(if-let [rs (stmt->result-set stmt opts)]
|
(if-let [rs (stmt->result-set stmt opts)]
|
||||||
(let [gen-fn (get opts :gen-fn as-maps)
|
(let [builder-fn (get opts :builder-fn as-maps)
|
||||||
gen (gen-fn rs opts)]
|
builder (builder-fn rs opts)]
|
||||||
(when (.next rs)
|
(when (.next rs)
|
||||||
(datafiable-row (row-builder gen) this opts)))
|
(datafiable-row (row-builder builder) this opts)))
|
||||||
{:next.jdbc/update-count (.getUpdateCount stmt)}))))
|
{:next.jdbc/update-count (.getUpdateCount stmt)}))))
|
||||||
(-execute-all [this sql-params opts]
|
(-execute-all [this sql-params opts]
|
||||||
(with-open [con (p/get-connection this opts)]
|
(with-open [con (p/get-connection this opts)]
|
||||||
|
|
@ -384,14 +384,14 @@
|
||||||
(rest sql-params)
|
(rest sql-params)
|
||||||
opts)]
|
opts)]
|
||||||
(if-let [rs (stmt->result-set stmt opts)]
|
(if-let [rs (stmt->result-set stmt opts)]
|
||||||
(let [gen-fn (get opts :gen-fn as-maps)
|
(let [builder-fn (get opts :builder-fn as-maps)
|
||||||
gen (gen-fn rs opts)]
|
builder (builder-fn rs opts)]
|
||||||
(loop [rs' (->rs gen) more? (.next rs)]
|
(loop [rs' (->rs builder) more? (.next rs)]
|
||||||
(if more?
|
(if more?
|
||||||
(recur (with-row gen rs'
|
(recur (with-row builder rs'
|
||||||
(datafiable-row (row-builder gen) this opts))
|
(datafiable-row (row-builder builder) this opts))
|
||||||
(.next rs))
|
(.next rs))
|
||||||
(rs! gen rs'))))
|
(rs! builder rs'))))
|
||||||
[{:next.jdbc/update-count (.getUpdateCount stmt)}]))))
|
[{:next.jdbc/update-count (.getUpdateCount stmt)}]))))
|
||||||
|
|
||||||
java.sql.PreparedStatement
|
java.sql.PreparedStatement
|
||||||
|
|
@ -404,23 +404,23 @@
|
||||||
(reduce-stmt this f init (assoc opts :return-keys true)))))
|
(reduce-stmt this f init (assoc opts :return-keys true)))))
|
||||||
(-execute-one [this _ opts]
|
(-execute-one [this _ opts]
|
||||||
(if-let [rs (stmt->result-set this (assoc opts :return-keys true))]
|
(if-let [rs (stmt->result-set this (assoc opts :return-keys true))]
|
||||||
(let [gen-fn (get opts :gen-fn as-maps)
|
(let [builder-fn (get opts :builder-fn as-maps)
|
||||||
gen (gen-fn rs opts)]
|
builder (builder-fn rs opts)]
|
||||||
(when (.next rs)
|
(when (.next rs)
|
||||||
(datafiable-row (row-builder gen)
|
(datafiable-row (row-builder builder)
|
||||||
(.getConnection this) opts)))
|
(.getConnection this) opts)))
|
||||||
{:next.jdbc/update-count (.getUpdateCount this)}))
|
{:next.jdbc/update-count (.getUpdateCount this)}))
|
||||||
(-execute-all [this _ opts]
|
(-execute-all [this _ opts]
|
||||||
(if-let [rs (stmt->result-set this opts)]
|
(if-let [rs (stmt->result-set this opts)]
|
||||||
(let [gen-fn (get opts :gen-fn as-maps)
|
(let [builder-fn (get opts :builder-fn as-maps)
|
||||||
gen (gen-fn rs opts)]
|
builder (builder-fn rs opts)]
|
||||||
(loop [rs' (->rs gen) more? (.next rs)]
|
(loop [rs' (->rs builder) more? (.next rs)]
|
||||||
(if more?
|
(if more?
|
||||||
(recur (with-row gen rs'
|
(recur (with-row builder rs'
|
||||||
(datafiable-row (row-builder gen)
|
(datafiable-row (row-builder builder)
|
||||||
(.getConnection this) opts))
|
(.getConnection this) opts))
|
||||||
(.next rs))
|
(.next rs))
|
||||||
(rs! gen rs'))))
|
(rs! builder rs'))))
|
||||||
[{:next.jdbc/update-count (.getUpdateCount this)}]))
|
[{:next.jdbc/update-count (.getUpdateCount this)}]))
|
||||||
|
|
||||||
Object
|
Object
|
||||||
|
|
|
||||||
|
|
@ -76,21 +76,21 @@
|
||||||
(testing "unqualified row builder"
|
(testing "unqualified row builder"
|
||||||
(let [row (p/-execute-one (ds)
|
(let [row (p/-execute-one (ds)
|
||||||
["select * from fruit where id = ?" 2]
|
["select * from fruit where id = ?" 2]
|
||||||
{:gen-fn rs/as-unqualified-maps})]
|
{:builder-fn rs/as-unqualified-maps})]
|
||||||
(is (map? row))
|
(is (map? row))
|
||||||
(is (= 2 (:ID row)))
|
(is (= 2 (:ID row)))
|
||||||
(is (= "Banana" (:NAME row)))))
|
(is (= "Banana" (:NAME row)))))
|
||||||
(testing "lower-case row builder"
|
(testing "lower-case row builder"
|
||||||
(let [row (p/-execute-one (ds)
|
(let [row (p/-execute-one (ds)
|
||||||
["select * from fruit where id = ?" 3]
|
["select * from fruit where id = ?" 3]
|
||||||
{:gen-fn rs/as-lower-maps})]
|
{:builder-fn rs/as-lower-maps})]
|
||||||
(is (map? row))
|
(is (map? row))
|
||||||
(is (= 3 (:fruit/id row)))
|
(is (= 3 (:fruit/id row)))
|
||||||
(is (= "Peach" (:fruit/name row)))))
|
(is (= "Peach" (:fruit/name row)))))
|
||||||
(testing "lower-case row builder"
|
(testing "lower-case row builder"
|
||||||
(let [row (p/-execute-one (ds)
|
(let [row (p/-execute-one (ds)
|
||||||
["select * from fruit where id = ?" 4]
|
["select * from fruit where id = ?" 4]
|
||||||
{:gen-fn rs/as-unqualified-lower-maps})]
|
{:builder-fn rs/as-unqualified-lower-maps})]
|
||||||
(is (map? row))
|
(is (map? row))
|
||||||
(is (= 4 (:id row)))
|
(is (= 4 (:id row)))
|
||||||
(is (= "Orange" (:name row))))))
|
(is (= "Orange" (:name row))))))
|
||||||
|
|
@ -100,27 +100,27 @@
|
||||||
(is (= [false]
|
(is (= [false]
|
||||||
(into [] (map map?) ; it is not a real map
|
(into [] (map map?) ; it is not a real map
|
||||||
(p/-execute (ds) ["select * from fruit where id = ?" 1]
|
(p/-execute (ds) ["select * from fruit where id = ?" 1]
|
||||||
{:gen-fn (constantly nil)}))))
|
{:builder-fn (constantly nil)}))))
|
||||||
(is (= ["Apple"]
|
(is (= ["Apple"]
|
||||||
(into [] (map :name) ; but keyword selection works
|
(into [] (map :name) ; but keyword selection works
|
||||||
(p/-execute (ds) ["select * from fruit where id = ?" 1]
|
(p/-execute (ds) ["select * from fruit where id = ?" 1]
|
||||||
{:gen-fn (constantly nil)}))))
|
{:builder-fn (constantly nil)}))))
|
||||||
(is (= [[2 [:name "Banana"]]]
|
(is (= [[2 [:name "Banana"]]]
|
||||||
(into [] (map (juxt #(get % "id") ; get by string key works
|
(into [] (map (juxt #(get % "id") ; get by string key works
|
||||||
#(find % :name))) ; get MapEntry works
|
#(find % :name))) ; get MapEntry works
|
||||||
(p/-execute (ds) ["select * from fruit where id = ?" 2]
|
(p/-execute (ds) ["select * from fruit where id = ?" 2]
|
||||||
{:gen-fn (constantly nil)}))))
|
{:builder-fn (constantly nil)}))))
|
||||||
(is (= [{:id 3 :name "Peach"}]
|
(is (= [{:id 3 :name "Peach"}]
|
||||||
(into [] (map #(select-keys % [:id :name])) ; select-keys works
|
(into [] (map #(select-keys % [:id :name])) ; select-keys works
|
||||||
(p/-execute (ds) ["select * from fruit where id = ?" 3]
|
(p/-execute (ds) ["select * from fruit where id = ?" 3]
|
||||||
{:gen-fn (constantly nil)}))))
|
{:builder-fn (constantly nil)}))))
|
||||||
(is (= [[:orange 4]]
|
(is (= [[:orange 4]]
|
||||||
(into [] (map #(vector (if (contains? % :name) ; contains works
|
(into [] (map #(vector (if (contains? % :name) ; contains works
|
||||||
(keyword (str/lower-case (:name %)))
|
(keyword (str/lower-case (:name %)))
|
||||||
:unnamed)
|
:unnamed)
|
||||||
(get % :id 0))) ; get with not-found works
|
(get % :id 0))) ; get with not-found works
|
||||||
(p/-execute (ds) ["select * from fruit where id = ?" 4]
|
(p/-execute (ds) ["select * from fruit where id = ?" 4]
|
||||||
{:gen-fn (constantly nil)})))))
|
{:builder-fn (constantly nil)})))))
|
||||||
(testing "assoc and seq build maps"
|
(testing "assoc and seq build maps"
|
||||||
(is (map? (reduce (fn [_ row] (reduced (assoc row :x 1)))
|
(is (map? (reduce (fn [_ row] (reduced (assoc row :x 1)))
|
||||||
nil
|
nil
|
||||||
|
|
@ -163,12 +163,12 @@
|
||||||
(deftest custom-map-builder
|
(deftest custom-map-builder
|
||||||
(let [row (p/-execute-one (ds)
|
(let [row (p/-execute-one (ds)
|
||||||
["select * from fruit where appearance = ?" "red"]
|
["select * from fruit where appearance = ?" "red"]
|
||||||
{:gen-fn fruit-builder})]
|
{:builder-fn fruit-builder})]
|
||||||
(is (instance? Fruit row))
|
(is (instance? Fruit row))
|
||||||
(is (= 1 (:id row))))
|
(is (= 1 (:id row))))
|
||||||
(let [rs (p/-execute-all (ds)
|
(let [rs (p/-execute-all (ds)
|
||||||
["select * from fruit where appearance = ?" "red"]
|
["select * from fruit where appearance = ?" "red"]
|
||||||
{:gen-fn fruit-builder})]
|
{:builder-fn fruit-builder})]
|
||||||
(is (every? #(instance? Fruit %) rs))
|
(is (every? #(instance? Fruit %) rs))
|
||||||
(is (= 1 (count rs)))
|
(is (= 1 (count rs)))
|
||||||
(is (= 1 (:id (first rs))))))
|
(is (= 1 (:id (first rs))))))
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@
|
||||||
(let [rs (jdbc/execute!
|
(let [rs (jdbc/execute!
|
||||||
(ds)
|
(ds)
|
||||||
["select * from fruit order by id"]
|
["select * from fruit order by id"]
|
||||||
{:gen-fn rs/as-maps})]
|
{:builder-fn rs/as-maps})]
|
||||||
(is (every? map? rs))
|
(is (every? map? rs))
|
||||||
(is (every? meta rs))
|
(is (every? meta rs))
|
||||||
(is (= 4 (count rs)))
|
(is (= 4 (count rs)))
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
(let [rs (jdbc/execute!
|
(let [rs (jdbc/execute!
|
||||||
(ds)
|
(ds)
|
||||||
["select * from fruit order by id"]
|
["select * from fruit order by id"]
|
||||||
{:gen-fn rs/as-arrays})]
|
{:builder-fn rs/as-arrays})]
|
||||||
(is (every? vector? rs))
|
(is (every? vector? rs))
|
||||||
(is (= 5 (count rs)))
|
(is (= 5 (count rs)))
|
||||||
(is (every? #(= 5 (count %)) rs))
|
(is (every? #(= 5 (count %)) rs))
|
||||||
|
|
@ -54,7 +54,7 @@
|
||||||
(let [rs (jdbc/execute!
|
(let [rs (jdbc/execute!
|
||||||
(ds)
|
(ds)
|
||||||
["select * from fruit order by id"]
|
["select * from fruit order by id"]
|
||||||
{:gen-fn rs/as-unqualified-maps})]
|
{:builder-fn rs/as-unqualified-maps})]
|
||||||
(is (every? map? rs))
|
(is (every? map? rs))
|
||||||
(is (every? meta rs))
|
(is (every? meta rs))
|
||||||
(is (= 4 (count rs)))
|
(is (= 4 (count rs)))
|
||||||
|
|
@ -63,7 +63,7 @@
|
||||||
(let [rs (jdbc/execute!
|
(let [rs (jdbc/execute!
|
||||||
(ds)
|
(ds)
|
||||||
["select * from fruit order by id"]
|
["select * from fruit order by id"]
|
||||||
{:gen-fn rs/as-unqualified-arrays})]
|
{:builder-fn rs/as-unqualified-arrays})]
|
||||||
(is (every? vector? rs))
|
(is (every? vector? rs))
|
||||||
(is (= 5 (count rs)))
|
(is (= 5 (count rs)))
|
||||||
(is (every? #(= 5 (count %)) rs))
|
(is (every? #(= 5 (count %)) rs))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue