;;; http://chokkoyamada.github.io/blog/2013/05/27/dig-into-jdbc-4/
(set-env! :dependencies '[[funcool/clojure.jdbc "0.6.1"]])
(require '[jdbc.proto])
(import (java.sql ResultSet))
(defn- concurrency [^java.sql.DatabaseMetaData metadata ^Integer result-set-type]
(cond-> #{}
(.supportsResultSetConcurrency metadata result-set-type ResultSet/CONCUR_READ_ONLY) (conj :CONCUR_READ_ONLY)
(.supportsResultSetConcurrency metadata result-set-type ResultSet/CONCUR_UPDATABLE) (conj :CONCUR_UPDATABLE)))
(defn- result-set-types [^java.sql.DatabaseMetaData metadata]
(cond-> {}
(.supportsResultSetType metadata ResultSet/TYPE_FORWARD_ONLY) (conj [:FORWARD_ONLY (concurrency metadata ResultSet/TYPE_FORWARD_ONLY)])
(.supportsResultSetType metadata ResultSet/TYPE_SCROLL_INSENSITIVE) (conj [:SCROLL_INSENSITIVE (concurrency metadata ResultSet/TYPE_SCROLL_INSENSITIVE)])
(.supportsResultSetType metadata ResultSet/TYPE_SCROLL_SENSITIVE) (conj [:SCROLL_SENSITIVE (concurrency metadata ResultSet/TYPE_SCROLL_SENSITIVE)])))
(defn- holdability [^java.sql.DatabaseMetaData metadata]
{:default
({ResultSet/HOLD_CURSORS_OVER_COMMIT :HOLD_CURSORS_OVER_COMMIT
ResultSet/CLOSE_CURSORS_AT_COMMIT :CLOSE_CURSORS_AT_COMMIT} (.getResultSetHoldability metadata))
:supports (cond-> #{}
(.supportsResultSetHoldability metadata ResultSet/HOLD_CURSORS_OVER_COMMIT) (conj :HOLD_CURSORS_OVER_COMMIT)
(.supportsResultSetHoldability metadata ResultSet/CLOSE_CURSORS_AT_COMMIT) (conj :CLOSE_CURSORS_AT_COMMIT))})
(defn- cursor-capability [db-spec]
(with-open [conn (jdbc/connection db-spec)]
(let [metadata (jdbc.proto/get-database-metadata conn)]
{:hodability (holdability metadata)
:result-set-types (result-set-types metadata)})))
(comment
(cursor-capability {:classname "org.h2.Driver", :subprotocol "h2", :subname "./test"})
;; ↓
{:hodability {:default :CLOSE_CURSORS_AT_COMMIT, :supports #{:CLOSE_CURSORS_AT_COMMIT}},
:result-set-types
{:FORWARD_ONLY #{:CONCUR_UPDATABLE :CONCUR_READ_ONLY}, :SCROLL_INSENSITIVE #{:CONCUR_UPDATABLE :CONCUR_READ_ONLY}}})