Fix #19 by caching loaded database driver classes
This commit is contained in:
parent
c509525592
commit
99ee285689
2 changed files with 27 additions and 19 deletions
|
|
@ -10,4 +10,4 @@
|
||||||
|
|
||||||
The following changes have been committed to the **master** branch and will be in the next release:
|
The following changes have been committed to the **master** branch and will be in the next release:
|
||||||
|
|
||||||
* None at this time.
|
* Fix #19 by caching loaded database driver classes.
|
||||||
|
|
|
||||||
|
|
@ -72,13 +72,16 @@
|
||||||
p))
|
p))
|
||||||
|
|
||||||
(defn- get-driver-connection
|
(defn- get-driver-connection
|
||||||
"Common logic for loading the `DriverManager` and the designed JDBC driver
|
"Common logic for loading the designated JDBC driver class and
|
||||||
class and obtaining the appropriate `Connection` object."
|
obtaining the appropriate `Connection` object."
|
||||||
[url etc]
|
[url etc]
|
||||||
;; force DriverManager to be loaded
|
|
||||||
(DriverManager/getLoginTimeout)
|
|
||||||
(DriverManager/getConnection url (as-properties etc)))
|
(DriverManager/getConnection url (as-properties etc)))
|
||||||
|
|
||||||
|
(def ^:private driver-cache
|
||||||
|
"An optimization for repeated calls to get-datasource, or for get-connection
|
||||||
|
called on a db-spec hash map, so that we only try to load the classes once."
|
||||||
|
(atom {}))
|
||||||
|
|
||||||
(defn- spec->url+etc
|
(defn- spec->url+etc
|
||||||
"Given a database spec, return a JDBC URL and a map of any additional options."
|
"Given a database spec, return a JDBC URL and a map of any additional options."
|
||||||
[{:keys [dbtype dbname host port classname] :as db-spec}]
|
[{:keys [dbtype dbname host port classname] :as db-spec}]
|
||||||
|
|
@ -107,22 +110,27 @@
|
||||||
etc (dissoc db-spec :dbtype :dbname :host :port :classname)]
|
etc (dissoc db-spec :dbtype :dbname :host :port :classname)]
|
||||||
;; verify the datasource is loadable
|
;; verify the datasource is loadable
|
||||||
(if-let [class-name (or classname (classnames subprotocol))]
|
(if-let [class-name (or classname (classnames subprotocol))]
|
||||||
|
(swap! driver-cache update class-name
|
||||||
|
#(if % %
|
||||||
(do
|
(do
|
||||||
|
;; force DriverManager to be loaded
|
||||||
|
(DriverManager/getLoginTimeout)
|
||||||
(if (string? class-name)
|
(if (string? class-name)
|
||||||
(clojure.lang.RT/loadClassForName class-name)
|
(clojure.lang.RT/loadClassForName class-name)
|
||||||
(loop [[clazz & more] class-name]
|
(loop [[clazz & more] class-name]
|
||||||
(when-let [load-failure
|
(let [loaded
|
||||||
(try
|
(try
|
||||||
(clojure.lang.RT/loadClassForName clazz)
|
(clojure.lang.RT/loadClassForName clazz)
|
||||||
nil
|
|
||||||
(catch Exception e
|
(catch Exception e
|
||||||
e))]
|
e))]
|
||||||
|
(if (instance? Throwable loaded)
|
||||||
(if (seq more)
|
(if (seq more)
|
||||||
(recur more)
|
(recur more)
|
||||||
(throw load-failure))))))
|
(throw loaded))
|
||||||
|
loaded)))))))
|
||||||
(throw (ex-info (str "Unknown dbtype: " dbtype) db-spec)))
|
(throw (ex-info (str "Unknown dbtype: " dbtype) db-spec)))
|
||||||
[url etc]))
|
[url etc]))
|
||||||
|
(def class-name "java.lang.String")
|
||||||
(defn- string->url+etc
|
(defn- string->url+etc
|
||||||
"Given a JDBC URL, return it with an empty set of options with no parsing."
|
"Given a JDBC URL, return it with an empty set of options with no parsing."
|
||||||
[s]
|
[s]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue