Skip to content

Commit

Permalink
fixes #291 by adding XTDB tips & tricks
Browse files Browse the repository at this point in the history
Signed-off-by: Sean Corfield <[email protected]>
  • Loading branch information
seancorfield committed Dec 12, 2024
1 parent 151b7d8 commit 801e6c9
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Only accretive/fixative changes will be made from now on.

* 1.3.next in progress
* Address [#291](https://github.com/seancorfield/next-jdbc/issues/291) by adding an XTDB section to **Tips & Tricks**.
* Added XTDB as a supported database for testing via PR [#290](https://github.com/seancorfield/next-jdbc/pull/290). _Note: not all features are tested against XTDB due to several fundamental differences in architecture, mostly around primary key/generated keys and lack of DDL operations (since XTDB is schemaless)._
* Update dev/test dependencies.

Expand Down
14 changes: 7 additions & 7 deletions doc/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ for `project.clj` or `build.boot`.

**In addition, you will need to add dependencies for the JDBC drivers you wish to use for whatever databases you are using. For example:**

* MySQL: `com.mysql/mysql-connector-j {:mvn/version "8.1.0"}` ([search for latest version](https://search.maven.org/artifact/com.mysql/mysql-connector-j))
* PostgreSQL: `org.postgresql/postgresql {:mvn/version "42.6.0"}` ([search for latest version](https://search.maven.org/artifact/org.postgresql/postgresql))
* Microsoft SQL Server: `com.microsoft.sqlserver/mssql-jdbc {:mvn/version "12.4.1.jre11"}` ([search for latest version](https://search.maven.org/artifact/com.microsoft.sqlserver/mssql-jdbc))
* Sqlite: `org.xerial/sqlite-jdbc {:mvn/version "3.43.0.0"}` ([search for latest version](https://search.maven.org/artifact/org.xerial/sqlite-jdbc))
* MySQL: `com.mysql/mysql-connector-j {:mvn/version "9.1.0"}` ([search for latest version](https://search.maven.org/artifact/com.mysql/mysql-connector-j))
* PostgreSQL: `org.postgresql/postgresql {:mvn/version "42.7.4"}` ([search for latest version](https://search.maven.org/artifact/org.postgresql/postgresql))
* Microsoft SQL Server: `com.microsoft.sqlserver/mssql-jdbc {:mvn/version "12.8.1.jre11"}` ([search for latest version](https://search.maven.org/artifact/com.microsoft.sqlserver/mssql-jdbc))
* Sqlite: `org.xerial/sqlite-jdbc {:mvn/version "3.47.1.0"}` ([search for latest version](https://search.maven.org/artifact/org.xerial/sqlite-jdbc))

> Note: these are the versions that `next.jdbc` is tested against but there may be more recent versions and those should generally work too -- click the "search for latest version" link to see all available versions of those drivers on Maven Central. You can see the full list of drivers and versions that `next.jdbc` is tested against in [the project's `deps.edn` file](https://github.com/seancorfield/next-jdbc/blob/develop/deps.edn#L10-L27), but many other JDBC drivers for other databases should also work (e.g., Oracle, Red Shift).
Expand All @@ -39,7 +39,7 @@ For the examples in this documentation, we will use a local H2 database on disk,
;; deps.edn
{:deps {org.clojure/clojure {:mvn/version "1.12.0"}
com.github.seancorfield/next.jdbc {:mvn/version "1.3.967"}
com.h2database/h2 {:mvn/version "2.2.224"}}}
com.h2database/h2 {:mvn/version "2.3.232"}}}
```

### Create & Populate a Database
Expand Down Expand Up @@ -487,9 +487,9 @@ Not all databases support using a `PreparedStatement` for every type of SQL oper
First, you need to add the connection pooling library as a dependency, e.g.,

```clojure
com.zaxxer/HikariCP {:mvn/version "5.0.1"}
com.zaxxer/HikariCP {:mvn/version "6.2.1"}
;; or:
com.mchange/c3p0 {:mvn/version "0.9.5.5"}
com.mchange/c3p0 {:mvn/version "0.10.1"}
```

_Check those libraries' documentation for the latest version to use!_
Expand Down
27 changes: 26 additions & 1 deletion doc/tips-and-tricks.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ be very database-specific. Some database drivers **don't** use the hierarchy
above -- notably PostgreSQL, which has a generic `PSQLException` type
with its own subclasses and semantics. See [PostgreSQL JDBC issue #963](https://github.com/pgjdbc/pgjdbc/issues/963)
for a discussion of the difficulty in adopting the standard JDBC hierarchy
(dating back five years).
(dating back to 2017!).

The `java.sql.SQLException` class provides `.getErrorCode()` and
`.getSQLState()` methods but the values returned by those are
Expand Down Expand Up @@ -237,6 +237,7 @@ common approach, there is also a non-JDBC Clojure/Java driver for PostgreSQL cal
quite a bit faster than using JDBC.

When you use `:return-keys true` with `execute!` or `execute-one!` (or you use `insert!`), PostgreSQL returns the entire inserted row (unlike nearly every other database that just returns any generated keys!).
_[It seems to achieve this by the equivalent of automatically appending `RETURNING *` to your SQL, if necessary.]_

The default result set builder for `next.jdbc` is `as-qualified-maps` which
uses the `.getTableName()` method on `ResultSetMetaData` to qualify the
Expand Down Expand Up @@ -574,3 +575,27 @@ If you are using `plan`, you'll most likely be accessing columns by just the lab

See also [`datafy`, `nav`, and `:schema` > **SQLite**](/doc/datafy-nav-and-schema.md#sqlite)
for additional caveats on the `next.jdbc.datafy` namespace when using SQLite.

## XTDB

XTDB is a bitemporal, schemaless, document-oriented database that presents
itself as a PostgreSQL-compatible database, in terms of JDBC. It has a number
of SQL extensions, and some differences from common JDBC behavior. See
its documentation for details:
* [SQL Overview](https://docs.xtdb.com/quickstart/sql-overview.html)
* [SQL Queries](https://docs.xtdb.com/reference/main/sql/queries.html)
* [SQL Transactions/DML](https://docs.xtdb.com/reference/main/sql/txs.html)

`next.jdbc` officially supports XTDB as of 1.3.next but there are some caveats:
* You can use `:dbtype "xtdb"` to identify XTDB as the database type.
* You must specify `:dbname "xtdb"` in the db-spec hash map or JDBC URL.
* XTDB does not support `.getTableName()` so you always get unqualified column names in result sets.
* The `:max-rows` / `:maxRows` options are not (yet) supported by XTDB (use `LIMIT` in your SQL instead).
* The primary key on all tables is `_id` and it must be specified in all `INSERT` operations (no auto-generated keys).
* That means that `next.jdbc.sql/get-by-id` requires the 5-argument call, so that you can specify the `pk-name` as `:_id` and provide an options map.
* If you want to use `next.jdbc`'s built-in `datafy` / `nav` functionality, you need to explicitly specify `:schema-opts {:pk "_id"}` to override the default assumption of `id` as the primary key.
* DML operations (`INSERT`, `UPDATE`, and `DELETE`) are essentially asynchronous in XTDB and therefore can not return an accurate `next.jdbc/update-count` (so it is always 0).
* `INSERT` operations do not return the inserted row (like PostgreSQL does) nor even the provided `_id` primary key.
* That means that the `next.jdbc.defer` namespace functions do not work well with XTDB.
* `next.jdbc.sql/insert-multi!` returns an empty vector for XTDB (since `INSERT` operations do not return keys or update counts).
* The `next.jdbc.result-set/*-kebab-maps` functions (and associated `next.jdbc/*-kebab-opts` option maps) cause leading `_` to be stripped from column names and cannot be used with XTDB (this is inherent in the underlying library that `next.jdbc` relies on -- you can of course write your own custom result set builder function to handle this).

0 comments on commit 801e6c9

Please sign in to comment.