Fix #63 by adding caveats to qualified column name docs
This commit is contained in:
parent
e03de7828a
commit
8cb05f4495
6 changed files with 11 additions and 4 deletions
|
|
@ -7,6 +7,7 @@ Only accretive/fixative changes will be made from now on.
|
|||
The following changes have been committed to the **master** branch since the 1.0.7 release:
|
||||
|
||||
* Add `next.jdbc.specs/unstrument`. PR #64 (@gerred).
|
||||
* Address #63 by improving documentation around qualified column names and `:qualifier` (`clojure.java.jdbc`) migration.
|
||||
|
||||
## Stable Builds
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ Any function that might realize a row or a result set will accept:
|
|||
|
||||
* `:builder-fn` -- a function that implements the `RowBuilder` and `ResultSetBuilder` protocols; strictly speaking, `plan` and `execute-one!` only need `RowBuilder` to be implemented (and `plan` only needs that if it actually has to realize a row) but most generation functions will implement both for ease of use.
|
||||
* `:label-fn` -- if `:builder-fn` is specified as one of `next.jdbc.result-set`'s `as-modified-*` builders, this option must be present and should specify a string-to-string transformation that will be applied to the column label for each returned column name.
|
||||
* `:qualifier-fn` -- if `:builder-fn` is specified as one of `next.jdbc.result-set`'s `as-modified-*` builders, this option should specify a string-to-string transformation that will be applied to the table name for each returned column name. It can be omitted for the `as-unqualified-modified-*` variants.
|
||||
* `:qualifier-fn` -- if `:builder-fn` is specified as one of `next.jdbc.result-set`'s `as-modified-*` builders, this option should specify a string-to-string transformation that will be applied to the table name for each returned column name for which the table name is known. It can be omitted for the `as-unqualified-modified-*` variants.
|
||||
|
||||
## Prepared Statements
|
||||
|
||||
|
|
|
|||
|
|
@ -166,12 +166,16 @@ Note that the entity naming function is passed a string, the result of calling `
|
|||
|
||||
This section will accrue various tips and tricks that make it easier to use `next.jdbc` with a variety of databases. It will be organized by database.
|
||||
|
||||
## MySQL
|
||||
### MySQL
|
||||
|
||||
MySQL generally stores tables as files so they are case-sensitive if your O/S is (Linux) or case-insensitive if your O/S is not (Mac, Windows) but the column names are generally case-insensitive. This can matter when if you use `next.jdbc.result-set/as-lower-maps` because that will lower-case the table names (as well as the column names) so if you are round-tripping based on the keys you get back, you may produce an incorrect table name in terms of case. You'll also need to be careful about `:table-fn`/`:column-fn` because of this.
|
||||
|
||||
It's also worth noting that column comparisons are case-insensitive so `WHERE foo = 'BAR'` will match `"bar"` or `"BAR"` etc.
|
||||
|
||||
### Oracle
|
||||
|
||||
Ah, dear old Oracle! Over the years of maintaining `clojure.java.jdbc` and now `next.jdbc`, I've had all sorts of bizarre and non-standard behavior reported from Oracle users. The main issue I'm aware of with `next.jdbc` is that Oracle's JDBC drivers all return an empty string from `ResultSetMetaData.getTableName()` so you won't get qualified keywords in the result set hash maps. Sorry!
|
||||
|
||||
### PostgreSQL
|
||||
|
||||
If you have a query where you want to select where a column is `IN` a sequence of values, you can use `col = ANY(?)` with a native array of the values instead of `IN (?,?,?,,,?)` and a sequence of values.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
The `next.jdbc` library provides a simpler, faster alternative to the [`clojure.java.jdbc`](https://github.com/clojure/java.jdbc) Contrib library and is the next step in the evolution of that library.
|
||||
|
||||
It is designed to work with Clojure 1.10 or later, supports `datafy`/`nav`, and by default produces hash maps with automatically qualified keywords, indicating source tables and column names (labels).
|
||||
It is designed to work with Clojure 1.10 or later, supports `datafy`/`nav`, and by default produces hash maps with automatically qualified keywords, indicating source tables and column names (labels), if your database supports that.
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ If you are using `:identifiers`, you will need to change to the appropriate `:bu
|
|||
|
||||
`clojure.java.jdbc`'s default is the equivalent of `as-unqualified-lower-maps`. If you specified `:identifiers identity`, you can use `as-unqualified-maps`. If you provided your own string transformation function, you probably want `as-unqualified-modified-maps` and also pass your transformation function as the `:label-fn` option.
|
||||
|
||||
If you used `:qualifier`, you may be able to get the same effect with `as-maps`, `as-lower-maps`, or `as-modified-maps`. Otherwise, you may need to specify `:qualifier-fn` as `(constantly "my-qualifier")` with one of the `modified` builder variants.
|
||||
If you used `:qualifier`, you may be able to get the same effect with `as-maps`, `as-lower-maps`, or `as-modified-maps`. Otherwise, you may need to specify the fixed qualifier via the `:label-fn #(str "my_qualifier/" %)`. You might think you could use `:qualifier-fn (constantly "my_qualifier")` for this but it is only called when the column has a known table name so it wouldn't be applied for derived values (and some databases don't provide the table name, so it wouldn't be applied at all for those databases).
|
||||
|
||||
### `:entities`
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
In [Getting Started](/doc/getting-started.md), it was noted that, by default, `execute!` and `execute-one!` return result sets as (vectors of) hash maps with namespace-qualified keys as-is. If your database naturally produces uppercase column names from the JDBC driver, that's what you'll get. If it produces mixed-case names, that's what you'll get.
|
||||
|
||||
*Note: Some databases do not return the table name in the metadata by default. If you run into this, you might try adding `:ResultSetMetaDataOptions "1"` to your db-spec (so it is passed as a property to the JDBC driver when you create connections). If your database supports that, it will perform additional work to try to add table names to the result set metadata. It has been reported that Oracle just plain old does not support table names at all in its JDBC drivers.*
|
||||
|
||||
The default builder for rows and result sets creates qualified keywords that match whatever case the JDBC driver produces. That builder is `next.jdbc.result-set/as-maps` but there are several options available:
|
||||
|
||||
* `as-maps` -- table-qualified keywords as-is, the default, e.g., `:ADDRESS/ID`, `:myTable/firstName`,
|
||||
|
|
|
|||
Loading…
Reference in a new issue