fixes #221 by support :column-fn in plan
This commit is contained in:
parent
e12342dec1
commit
77248fc2eb
4 changed files with 24 additions and 18 deletions
|
|
@ -4,6 +4,7 @@ Only accretive/fixative changes will be made from now on.
|
||||||
|
|
||||||
* 1.3.next in progress
|
* 1.3.next in progress
|
||||||
* Fix [#222](https://github.com/seancorfield/next-jdbc/issues/222) by correcting implementation of `.cons` on a row.
|
* Fix [#222](https://github.com/seancorfield/next-jdbc/issues/222) by correcting implementation of `.cons` on a row.
|
||||||
|
* Address [#221](https://github.com/seancorfield/next-jdbc/issues/221) by supporting `:column-fn` a top-level option in `plan`-related functions to transform keys used in reducing function contexts. Also corrects handling of column names in schema `nav`igation (which previously only supported `:table-fn` and incorrectly applied it to columns as well).
|
||||||
* Address [#218](https://github.com/seancorfield/next-jdbc/issues/218) by moving `:extend-via-metadata true` after the protocols' docstrings.
|
* Address [#218](https://github.com/seancorfield/next-jdbc/issues/218) by moving `:extend-via-metadata true` after the protocols' docstrings.
|
||||||
* Document `:useBulkCopyForBatchInsert` for Microsoft SQL Server via PR [#216](https://github.com/seancorfield/next-jdbc/issues/216) -- [danskarda](https://github.com/danskarda).
|
* Document `:useBulkCopyForBatchInsert` for Microsoft SQL Server via PR [#216](https://github.com/seancorfield/next-jdbc/issues/216) -- [danskarda](https://github.com/danskarda).
|
||||||
* Address [#215](https://github.com/seancorfield/next-jdbc/issues/215) by dropping official support for JDK 8 and updating various JDBC drivers in the testing matrix.
|
* Address [#215](https://github.com/seancorfield/next-jdbc/issues/215) by dropping official support for JDK 8 and updating various JDBC drivers in the testing matrix.
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,8 @@ If you need additional options set on a connection, you can either use Java inte
|
||||||
|
|
||||||
Except for `query` (which is simply an alias for `execute!`), all the "friendly" SQL functions accept the following options (in addition to all the options that `plan`, `execute!`, and `execute-one!` can accept):
|
Except for `query` (which is simply an alias for `execute!`), all the "friendly" SQL functions accept the following options (in addition to all the options that `plan`, `execute!`, and `execute-one!` can accept):
|
||||||
|
|
||||||
* `:table-fn` -- the quoting function to be used on the string that identifies the table name, if provided,
|
* `:table-fn` -- the quoting function to be used on the string that identifies the table name, if provided; this also applies to assumed table names when `nav`igating schemas,
|
||||||
* `:column-fn` -- the quoting function to be used on any string that identifies a column name, if provided.
|
* `:column-fn` -- the quoting function to be used on any string that identifies a column name, if provided; this also applies to the reducing function context over `plan` and to assumed foreign key column names when `nav`igating schemas.
|
||||||
|
|
||||||
They also support a `:suffix` argument which can be used to specify a SQL string that should be appended to the generated SQL string before executing it, e.g., `:suffix "FOR UPDATE"`.
|
They also support a `:suffix` argument which can be used to specify a SQL string that should be appended to the generated SQL string before executing it, e.g., `:suffix "FOR UPDATE"`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -191,6 +191,8 @@ user=> (reduce
|
||||||
|
|
||||||
The call to `jdbc/plan` returns an `IReduceInit` object but does not actually run the SQL. Only when the returned object is reduced is the connection obtained from the data source, the SQL executed, and the computation performed. The connection is closed automatically when the reduction is complete. The `row` in the reduction is an abstraction over the underlying (mutable) `ResultSet` object -- it is not a Clojure data structure. Because of that, you can simply access the columns via their SQL labels as shown -- you do not need to use the column-qualified name, and you do not need to worry about the database returning uppercase column names (SQL labels are not case sensitive).
|
The call to `jdbc/plan` returns an `IReduceInit` object but does not actually run the SQL. Only when the returned object is reduced is the connection obtained from the data source, the SQL executed, and the computation performed. The connection is closed automatically when the reduction is complete. The `row` in the reduction is an abstraction over the underlying (mutable) `ResultSet` object -- it is not a Clojure data structure. Because of that, you can simply access the columns via their SQL labels as shown -- you do not need to use the column-qualified name, and you do not need to worry about the database returning uppercase column names (SQL labels are not case sensitive).
|
||||||
|
|
||||||
|
> Note: if you want a column name transformation to be applied here, specify `:column-fn` as an option to the `plan` call.
|
||||||
|
|
||||||
Here's the same computation rewritten using `transduce`:
|
Here's the same computation rewritten using `transduce`:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
|
|
|
||||||
|
|
@ -485,7 +485,8 @@
|
||||||
realize the full row explicitly before performing other
|
realize the full row explicitly before performing other
|
||||||
(metadata-preserving) operations on it."
|
(metadata-preserving) operations on it."
|
||||||
[^ResultSet rs opts]
|
[^ResultSet rs opts]
|
||||||
(let [builder (delay ((get opts :builder-fn as-maps) rs opts))]
|
(let [builder (delay ((get opts :builder-fn as-maps) rs opts))
|
||||||
|
name-fn (get opts :column-fn name)]
|
||||||
(reify
|
(reify
|
||||||
|
|
||||||
MapifiedResultSet
|
MapifiedResultSet
|
||||||
|
|
@ -511,15 +512,15 @@
|
||||||
clojure.lang.Associative
|
clojure.lang.Associative
|
||||||
(containsKey [this k]
|
(containsKey [this k]
|
||||||
(try
|
(try
|
||||||
(.getObject rs (name k))
|
(.getObject rs (name-fn k))
|
||||||
true
|
true
|
||||||
(catch SQLException _
|
(catch SQLException _
|
||||||
false)))
|
false)))
|
||||||
(entryAt [this k]
|
(entryAt [this k]
|
||||||
(try
|
(try
|
||||||
(clojure.lang.MapEntry. k (read-column-by-label
|
(clojure.lang.MapEntry. k (read-column-by-label
|
||||||
(.getObject rs (name k))
|
(.getObject rs (name-fn k))
|
||||||
(name k)))
|
(name-fn k)))
|
||||||
(catch SQLException _)))
|
(catch SQLException _)))
|
||||||
|
|
||||||
clojure.lang.Counted
|
clojure.lang.Counted
|
||||||
|
|
@ -542,14 +543,14 @@
|
||||||
(if (number? k)
|
(if (number? k)
|
||||||
(let [^Integer i (inc k)]
|
(let [^Integer i (inc k)]
|
||||||
(read-column-by-index (.getObject rs i) (:rsmeta @builder) i))
|
(read-column-by-index (.getObject rs i) (:rsmeta @builder) i))
|
||||||
(read-column-by-label (.getObject rs (name k)) (name k)))
|
(read-column-by-label (.getObject rs (name-fn k)) (name-fn k)))
|
||||||
(catch SQLException _)))
|
(catch SQLException _)))
|
||||||
(valAt [this k not-found]
|
(valAt [this k not-found]
|
||||||
(try
|
(try
|
||||||
(if (number? k)
|
(if (number? k)
|
||||||
(let [^Integer i (inc k)]
|
(let [^Integer i (inc k)]
|
||||||
(read-column-by-index (.getObject rs i) (:rsmeta @builder) i))
|
(read-column-by-index (.getObject rs i) (:rsmeta @builder) i))
|
||||||
(read-column-by-label (.getObject rs (name k)) (name k)))
|
(read-column-by-label (.getObject rs (name-fn k)) (name-fn k)))
|
||||||
(catch SQLException _
|
(catch SQLException _
|
||||||
not-found)))
|
not-found)))
|
||||||
|
|
||||||
|
|
@ -1082,8 +1083,8 @@
|
||||||
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 the assumed table name and `:column-fn` if
|
||||||
assumed foreign key column name."
|
provided to the assumed foreign key column name."
|
||||||
[connectable opts]
|
[connectable opts]
|
||||||
(fn [row]
|
(fn [row]
|
||||||
(vary-meta
|
(vary-meta
|
||||||
|
|
@ -1095,15 +1096,16 @@
|
||||||
(expand-schema k (or (get-in opts [:schema k])
|
(expand-schema k (or (get-in opts [:schema k])
|
||||||
(default-schema k)))]
|
(default-schema k)))]
|
||||||
(if (and fk connectable)
|
(if (and fk connectable)
|
||||||
(let [entity-fn (:table-fn opts identity)
|
(let [table-fn (:table-fn opts identity)
|
||||||
|
column-fn (:column-fn opts identity)
|
||||||
exec-fn! (if (= :many cardinality)
|
exec-fn! (if (= :many cardinality)
|
||||||
p/-execute-all
|
p/-execute-all
|
||||||
p/-execute-one)]
|
p/-execute-one)]
|
||||||
(exec-fn! connectable
|
(exec-fn! connectable
|
||||||
[(str "SELECT * FROM "
|
[(str "SELECT * FROM "
|
||||||
(entity-fn (name table))
|
(table-fn (name table))
|
||||||
" WHERE "
|
" WHERE "
|
||||||
(entity-fn (name fk))
|
(column-fn (name fk))
|
||||||
" = ?")
|
" = ?")
|
||||||
v]
|
v]
|
||||||
opts))
|
opts))
|
||||||
|
|
@ -1128,8 +1130,8 @@
|
||||||
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 the assumed table name and `:column-fn` if
|
||||||
assumed foreign key column name."
|
provided to the assumed foreign key column name."
|
||||||
[connectable opts]
|
[connectable opts]
|
||||||
(fn [_ k v]
|
(fn [_ k v]
|
||||||
(try
|
(try
|
||||||
|
|
@ -1137,15 +1139,16 @@
|
||||||
(expand-schema k (or (get-in opts [:schema k])
|
(expand-schema k (or (get-in opts [:schema k])
|
||||||
(default-schema k)))]
|
(default-schema k)))]
|
||||||
(if (and fk connectable)
|
(if (and fk connectable)
|
||||||
(let [entity-fn (:table-fn opts identity)
|
(let [table-fn (:table-fn opts identity)
|
||||||
|
column-fn (:column-fn opts identity)
|
||||||
exec-fn! (if (= :many cardinality)
|
exec-fn! (if (= :many cardinality)
|
||||||
p/-execute-all
|
p/-execute-all
|
||||||
p/-execute-one)]
|
p/-execute-one)]
|
||||||
(exec-fn! connectable
|
(exec-fn! connectable
|
||||||
[(str "SELECT * FROM "
|
[(str "SELECT * FROM "
|
||||||
(entity-fn (name table))
|
(table-fn (name table))
|
||||||
" WHERE "
|
" WHERE "
|
||||||
(entity-fn (name fk))
|
(column-fn (name fk))
|
||||||
" = ?")
|
" = ?")
|
||||||
v]
|
v]
|
||||||
opts))
|
opts))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue