Finish off #47

Make `dbtypes` public again (oops!). Note that it _won't_ contain defaults (if folks feel they need them, they can easily be added). Use `:host :none` in `dbtypes` to indicate a local database (no `:host`/`:port` segment) which is more consistent with how users would specify a new database.

Reduce the number of special cases in the JDBC URL assembly, now that `:host :none` from `dbtypes` can drive that.
This commit is contained in:
Sean Corfield 2019-07-15 11:15:26 -07:00
parent 816fc7ce4b
commit 8883167805

View file

@ -9,12 +9,14 @@
(set! *warn-on-reflection* true) (set! *warn-on-reflection* true)
(def ^:private dbtypes (def dbtypes
"A map of all known database types (including aliases) to the class name(s) "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, and port that `next.jdbc` supports out of the box. For databases that have
this also includes the prefixes used in the JDBC string for the `:host` non-standard prefixes for the `:dbname` and/or `:host` values in the JDBC
and `:dbname` (which are `//` and either `/` or `:` respectively for string, this table includes `:dbname-separator` and/or `:host-prefix`. The
nearly all types). default prefix for `:dbname` is either `/` or `:` and for `:host` it is `//`.
For local databases, with no `:host`/`:port` segment in their JDBC URL, a
value of `:none` is provided for `:host` in this table.
For known database types, you can use `:dbtype` (and omit `:classname`). For known database types, you can use `:dbtype` (and omit `:classname`).
@ -55,54 +57,61 @@
named class in order, until one succeeds. This allows for a given `:dbtype` 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 to be used with different versions of a JDBC driver, if the class name
has changed over time (such as with MySQL)." has changed over time (such as with MySQL)."
{"derby" {:classname "org.apache.derby.jdbc.EmbeddedDriver"} {"derby" {:classname "org.apache.derby.jdbc.EmbeddedDriver"
"h2" {:classname "org.h2.Driver"} :host :none}
"h2" {:classname "org.h2.Driver"
:host :none}
"h2:mem" {:classname "org.h2.Driver"} "h2:mem" {:classname "org.h2.Driver"}
"hsql" {:classname "org.hsqldb.jdbcDriver" "hsql" {:classname "org.hsqldb.jdbcDriver"
:alias-for "hsqldb"} :alias-for "hsqldb"
"hsqldb" {:classname "org.hsqldb.jdbcDriver"} :host :none}
"hsqldb" {:classname "org.hsqldb.jdbcDriver"
:host :none}
"jtds" {:classname "net.sourceforge.jtds.jdbc.Driver" "jtds" {:classname "net.sourceforge.jtds.jdbc.Driver"
:port 1433 :alias-for "jtds:sqlserver"
:alias-for "jtds:sqlserver"} :port 1433}
"jtds:sqlserver" {:classname "net.sourceforge.jtds.jdbc.Driver" "jtds:sqlserver" {:classname "net.sourceforge.jtds.jdbc.Driver"
:port 1433} :port 1433}
"mssql" {:classname "com.microsoft.sqlserver.jdbc.SQLServerDriver" "mssql" {:classname "com.microsoft.sqlserver.jdbc.SQLServerDriver"
:port 1433
:alias-for "sqlserver" :alias-for "sqlserver"
:dbname-separator ";DATABASENAME="} :dbname-separator ";DATABASENAME="
:port 1433}
"mysql" {:classname ["com.mysql.cj.jdbc.Driver" "mysql" {:classname ["com.mysql.cj.jdbc.Driver"
"com.mysql.jdbc.Driver"] "com.mysql.jdbc.Driver"]
:port 3306} :port 3306}
"oracle" {:classname "oracle.jdbc.OracleDriver" "oracle" {:classname "oracle.jdbc.OracleDriver"
:port 1521
:alias-for "oracle:thin" :alias-for "oracle:thin"
:host-prefix "@"} :host-prefix "@"
:port 1521}
"oracle:oci" {:classname "oracle.jdbc.OracleDriver" "oracle:oci" {:classname "oracle.jdbc.OracleDriver"
:port 1521 :host-prefix "@"
:host-prefix "@"} :port 1521}
"oracle:sid" {:classname "oracle.jdbc.OracleDriver" "oracle:sid" {:classname "oracle.jdbc.OracleDriver"
:port 1521
:alias-for "oracle:thin" :alias-for "oracle:thin"
:dbname-separator ":" :dbname-separator ":"
:host-prefix "@"} :host-prefix "@"
:port 1521}
"oracle:thin" {:classname "oracle.jdbc.OracleDriver" "oracle:thin" {:classname "oracle.jdbc.OracleDriver"
:port 1521 :host-prefix "@"
:host-prefix "@"} :port 1521}
"postgres" {:classname "org.postgresql.Driver" "postgres" {:classname "org.postgresql.Driver"
:port 5432 :alias-for "postgresql"
:alias-for "postgresql"} :port 5432}
"postgresql" {:classname "org.postgresql.Driver" "postgresql" {:classname "org.postgresql.Driver"
:port 5432} :port 5432}
"pgsql" {:classname "com.impossibl.postgres.jdbc.PGDriver"} "pgsql" {:classname "com.impossibl.postgres.jdbc.PGDriver"}
"redshift" {:classname "com.amazon.redshift.jdbc.Driver"} "redshift" {:classname "com.amazon.redshift.jdbc.Driver"}
"sqlite" {:classname "org.sqlite.JDBC"} "sqlite" {:classname "org.sqlite.JDBC"
:host :none}
"sqlserver" {:classname "com.microsoft.sqlserver.jdbc.SQLServerDriver" "sqlserver" {:classname "com.microsoft.sqlserver.jdbc.SQLServerDriver"
:port 1433 :dbname-separator ";DATABASENAME="
:dbname-separator ";DATABASENAME="} :port 1433}
"timesten:client" {:classname "com.timesten.jdbc.TimesTenClientDriver" "timesten:client" {:classname "com.timesten.jdbc.TimesTenClientDriver"
:dbname-separator ":dsn="} :dbname-separator ":dsn="
:host :none}
"timesten:direct" {:classname "com.timesten.jdbc.TimesTenDriver" "timesten:direct" {:classname "com.timesten.jdbc.TimesTenDriver"
:dbname-separator ":dsn="}}) :dbname-separator ":dsn="
:host :none}})
(defn- ^Properties as-properties (defn- ^Properties as-properties
"Convert any seq of pairs to a `java.util.Properties` instance." "Convert any seq of pairs to a `java.util.Properties` instance."
@ -130,14 +139,11 @@
:as db-spec}] :as db-spec}]
(let [;; allow aliases for dbtype (let [;; allow aliases for dbtype
subprotocol (-> dbtype dbtypes :alias-for (or dbtype)) subprotocol (-> dbtype dbtypes :alias-for (or dbtype))
host (or host "127.0.0.1") host (or host (-> dbtype dbtypes :host) "127.0.0.1")
port (or port (-> dbtype dbtypes :port)) port (or port (-> dbtype dbtypes :port))
db-sep (or dbname-separator (-> dbtype dbtypes :dbname-separator (or "/"))) db-sep (or dbname-separator (-> dbtype dbtypes :dbname-separator (or "/")))
local-sep (or dbname-separator (-> dbtype dbtypes :dbname-separator (or ":"))) local-sep (or dbname-separator (-> dbtype dbtypes :dbname-separator (or ":")))
url (cond (#{"derby" "hsqldb" "sqlite"} subprotocol) url (cond (#{"h2"} subprotocol)
(str "jdbc:" subprotocol local-sep dbname)
(#{"h2"} subprotocol)
(str "jdbc:" subprotocol local-sep (str "jdbc:" subprotocol local-sep
(if (re-find #"^([A-Za-z]:)?[\./\\]" dbname) (if (re-find #"^([A-Za-z]:)?[\./\\]" dbname)
;; DB name starts with relative or absolute path ;; DB name starts with relative or absolute path
@ -148,9 +154,6 @@
(#{"h2:mem"} subprotocol) (#{"h2:mem"} subprotocol)
(str "jdbc:" subprotocol local-sep dbname ";DB_CLOSE_DELAY=-1") (str "jdbc:" subprotocol local-sep dbname ";DB_CLOSE_DELAY=-1")
(#{"timesten:client" "timesten:direct"} subprotocol)
(str "jdbc:" subprotocol local-sep dbname)
(= :none host) (= :none host)
(str "jdbc:" subprotocol local-sep dbname) (str "jdbc:" subprotocol local-sep dbname)