From 79d6f5ef2935c4e5a1f3bea27155132d25fd9b25 Mon Sep 17 00:00:00 2001 From: Sean Corfield Date: Wed, 10 Jul 2019 11:54:13 -0700 Subject: [PATCH] Improve documentation around :dbtype Expose `next.jdbc.connection/dbtypes` which is a table of all known `:dbtype` values and their driver class names, ports, etc. --- CHANGELOG.md | 1 + doc/getting-started.md | 2 +- src/next/jdbc/connection.clj | 39 ++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82ca54e..264eb0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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.1 release: * Fix #40 by adding `next.jdbc.prepare/execute-batch!`. +* Expose `next.jdbc.connect/dbtypes` as a table of known database types and aliases, along with their class name(s), port, and other JDBC string components. * Improved docstrings and documentation, especially around prepared statement handling. ## Stable Builds diff --git a/doc/getting-started.md b/doc/getting-started.md index 2941625..6fd02ea 100644 --- a/doc/getting-started.md +++ b/doc/getting-started.md @@ -61,7 +61,7 @@ user=> ``` We described the database with just `:dbtype` and `:dbname` because it is created as a local file and needs no authentication. For most databases, you would need `:user` and `:password` for authentication, and if the database is running on a remote machine you would need `:host` and possibly `:port` (`next.jdbc` tries to guess the correct port based on the `:dbtype`). -> Note: You can see the full list of `:dbtype` values supported in [next.jdbc/get-datasource](https://cljdoc.org/d/seancorfield/next.jdbc/CURRENT/api/next.jdbc#get-datasource). +> Note: You can see the full list of `:dbtype` values supported in [next.jdbc/get-datasource](https://cljdoc.org/d/seancorfield/next.jdbc/CURRENT/api/next.jdbc#get-datasource)'s docstring. If you need this programmatically, you can get it from the [next.jdbc.connection/dbtypes](https://cljdoc.org/d/seancorfield/next.jdbc/CURRENT/api/next.jdbc.connection#dbtypes) hash map. If those lists differ, the hash map is the definitive list (and I'll need to fix the docstring!). The docstring of that Var explains how to tell `next.jdbc` about additional databases. We used `execute!` to create the `address` table, to insert a new row into it, and to query it. In all three cases, `execute!` returns a vector of hash maps with namespace-qualified keys, representing the result set from the operation, if available. When no result set is produced, `next.jdbc` returns a "result set" containing the "update count" from the operation (which is usually the number of rows affected). By default, H2 uses uppercase names and `next.jdbc` returns these as-is. diff --git a/src/next/jdbc/connection.clj b/src/next/jdbc/connection.clj index 065cfe4..69460dc 100644 --- a/src/next/jdbc/connection.clj +++ b/src/next/jdbc/connection.clj @@ -63,6 +63,45 @@ "sqlserver" ";DATABASENAME=" "oracle:sid" ":"}) +(def dbtypes + "A map of all known database types (including aliases) to the class name(s) + and port that `next.jdbc` supports out of the box. Just for completeness, + this also includes the prefixes used in the JDBC string for the `:host` + and `:dbname` (which are `//` and `/` respectively for nearly all types). + + For known database types, you can use `:dbtype` (and omit `:classname`). + + If you want to use a database that is not in this list, you can specify + a new `:dbtype` along with the class name of the JDBC driver in `:classname`. + You will also need to specify `:port`. For example: + + `{:dbtype \"acme\" :classname \"com.acme.JdbcDriver\" ...}` + + JDBC drivers are not provided by `next.jdbc` -- you need to specify the + driver(s) you need as additional dependencies in your project. For + example: + + `[com.acme/jdbc \"1.2.3\"] ; lein/boot` + or: + `{com.acme/jdbc {:mvn/version \"1.2.3\"}} ; CLI/deps.edn` + + Note: the `:classname` value can be a string or a vector of strings. If + a vector of strings is provided, an attempt will be made to load each + named class in order, until one succeeds. This allows for a given `:dbtype` + to be used with different versions of a JDBC driver, if the class name + has changed over time (such as with MySQL)." + (let [dbs (merge (zipmap (keys classnames) (keys classnames)) aliases)] + (reduce-kv (fn [m k v] + (assoc m + k + (cond-> {:classname (classnames v) + :host-prefix (host-prefixes v "//") + :dbname-separator (dbname-separators v "/")} + (ports v) + (assoc :port (ports v))))) + {} + dbs))) + (defn- ^Properties as-properties "Convert any seq of pairs to a `java.util.Properties` instance." [m]