Extend datafication and simplify
Handles weird SQLite edge case; datafies Statement and ResultSet; improves exception handling in `safe-bean` (but we really need a better bean maker).
This commit is contained in:
parent
e406c90d6f
commit
4be2b7130b
2 changed files with 46 additions and 22 deletions
|
|
@ -12,7 +12,8 @@
|
|||
[next.jdbc.result-set :as rs])
|
||||
(:import (java.sql Connection
|
||||
DatabaseMetaData
|
||||
ResultSetMetaData)))
|
||||
ResultSet ResultSetMetaData
|
||||
Statement)))
|
||||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
||||
|
|
@ -46,22 +47,34 @@
|
|||
;; ensure we return a basic hash map:
|
||||
(merge {} (bean o))
|
||||
(catch Throwable t
|
||||
{:exception (ex-message t)
|
||||
:cause (ex-message (ex-cause t))})))
|
||||
(let [dex (juxt type (comp str ex-message))
|
||||
cause (ex-cause t)]
|
||||
(with-meta (cond-> {:exception (dex t)}
|
||||
cause (assoc :cause (dex cause)))
|
||||
{:exception t})))))
|
||||
|
||||
(defn- datafy-result-set-meta-data
|
||||
[^ResultSetMetaData this]
|
||||
(mapv #(reduce-kv (fn [m k f] (assoc m k (f this %)))
|
||||
{}
|
||||
column-meta)
|
||||
(range 1 (inc (.getColumnCount this)))))
|
||||
|
||||
(extend-protocol core-p/Datafiable
|
||||
Connection
|
||||
(datafy [this]
|
||||
(with-meta (safe-bean this)
|
||||
{`core-p/nav (fn [_ k v]
|
||||
(if (= :metaData k)
|
||||
(.getMetaData this)
|
||||
v))}))
|
||||
(datafy [this] (safe-bean this))
|
||||
DatabaseMetaData
|
||||
(datafy [this]
|
||||
(with-meta (safe-bean this)
|
||||
(with-meta (let [data (safe-bean this)]
|
||||
(cond-> data
|
||||
(not (:exception (meta data)))
|
||||
(assoc :all-tables [])))
|
||||
{`core-p/nav (fn [_ k v]
|
||||
(condp = k
|
||||
:all-tables
|
||||
(rs/datafiable-result-set (.getTables this nil nil nil nil)
|
||||
(.getConnection this)
|
||||
{})
|
||||
:catalogs
|
||||
(rs/datafiable-result-set (.getCatalogs this)
|
||||
(.getConnection this)
|
||||
|
|
@ -84,8 +97,15 @@
|
|||
{})
|
||||
v))}))
|
||||
ResultSetMetaData
|
||||
(datafy [this] (datafy-result-set-meta-data this))
|
||||
ResultSet
|
||||
(datafy [this]
|
||||
(mapv #(reduce-kv (fn [m k f] (assoc m k (f this %)))
|
||||
{}
|
||||
column-meta)
|
||||
(range 1 (inc (.getColumnCount this))))))
|
||||
;; SQLite has a combination ResultSet/Metadata object...
|
||||
(if (instance? ResultSetMetaData this)
|
||||
(datafy-result-set-meta-data this)
|
||||
(let [s (.getStatement this)
|
||||
c (when s (.getConnection s))]
|
||||
(cond-> (safe-bean this)
|
||||
c (assoc :rows (rs/datafiable-result-set this c {}))))))
|
||||
Statement
|
||||
(datafy [this] (safe-bean this)))
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
[next.jdbc.result-set :as rs]
|
||||
[next.jdbc.specs :as specs]
|
||||
[next.jdbc.test-fixtures :refer [with-test-db db ds
|
||||
derby? postgres? sqlite?]])
|
||||
derby? mysql? postgres? sqlite?]])
|
||||
(:import (java.sql DatabaseMetaData)))
|
||||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
|
@ -38,12 +38,7 @@
|
|||
(when-let [diff (seq (set/difference data basic-connection-keys))]
|
||||
(println (:dbtype (db)) :connection (sort diff)))
|
||||
(is (= basic-connection-keys
|
||||
(set/intersection basic-connection-keys data)))))))
|
||||
(testing "nav to metadata yields object"
|
||||
(when-not (derby?)
|
||||
(with-open [con (jdbc/get-connection (ds))]
|
||||
(is (instance? DatabaseMetaData
|
||||
(d/nav (d/datafy con) :metaData nil)))))))
|
||||
(set/intersection basic-connection-keys data))))))))
|
||||
|
||||
(def ^:private basic-database-metadata-keys
|
||||
"Generic JDBC Connection fields."
|
||||
|
|
@ -96,8 +91,17 @@
|
|||
(testing "result set metadata datafication"
|
||||
(let [data (reduce (fn [_ row] (reduced (rs/metadata row)))
|
||||
nil
|
||||
(jdbc/plan (ds) ["select * from fruit"]))]
|
||||
(jdbc/plan (ds) [(str "SELECT * FROM "
|
||||
(if (mysql?) "fruit" "FRUIT"))]))]
|
||||
(is (vector? data))
|
||||
(is (= 5 (count data)))
|
||||
(is (every? map? data))
|
||||
(is (every? :label data)))))
|
||||
|
||||
(comment
|
||||
(def con (jdbc/get-connection (ds)))
|
||||
(rs/datafiable-result-set (.getTables (.getMetaData con) nil nil nil nil) con {})
|
||||
(def ps (jdbc/prepare con ["SELECT * FROM fruit"]))
|
||||
(.execute ps)
|
||||
(.getResultSet ps)
|
||||
(.close con))
|
||||
|
|
|
|||
Loading…
Reference in a new issue