Merge branch 'master' into multi-rs

# Conflicts:
#	test/next/jdbc/test_fixtures.clj
This commit is contained in:
Sean Corfield 2020-06-07 10:05:33 -07:00
commit 92f7923a2a
7 changed files with 56 additions and 19 deletions

View file

@ -5,6 +5,9 @@ Only accretive/fixative changes will be made from now on.
Changes made on master since 1.0.462:
* Add tests for `"jtds"` database driver (against MS SQL Server), making it officially supported.
* Switch from OpenTable Embedded PostgreSQL to Zonky's version, so that testing can move forward from PostgreSQL 10.11 to 12.2.0.
* Fix potential reflection warnings caused by `next.jdbc.prepare/statement` being incorrectly type-hinted.
* Address #119 by clarifying realization actions in the docstrings for `row-number`, `column-names`, and `metadata`.
* Address #115 by adding equivalent of `db-do-commands` in the `clojure.java.jdbc` migration guide.
* Add log4j2 as a test dependency so that I have better control over logging (which makes debugging easier!).
* WIP: support for stored procedures and multiple result sets!

View file

@ -55,6 +55,18 @@ The `next.jdbc.sql` namespace contains several functions with similarities to `c
* `update!` -- similar to `clojure.java.jdbc/update!` but will also accept a hash map of column name/value pairs instead of a partial where clause (vector),
* `delete!` -- similar to `clojure.java.jdbc/delete!` but will also accept a hash map of column name/value pairs instead of a partial where clause (vector).
If you were using `db-do-commands` in `clojure.java.jdbc` to execute DDL, the following is the equivalent in `next.jdbc`:
```clojure
(defn do-commands [connectable commands]
(if (instance? java.sql.Connection connectable)
(with-open [stmt (next.jdbc.prepare/statement connectable)]
(run! #(.addBatch stmt %) commands)
(into [] (.executeBatch stmt)))
(with-open [conn (next.jdbc/get-connection connectable)]
(do-commands conn commands))))
```
### `:identifiers` and `:qualifier`
If you are using `:identifiers`, you will need to change to the appropriate `:builder-fn` option with one of `next.jdbc.result-set`'s `as-*` functions.

View file

@ -149,12 +149,13 @@
(defn statement
"Given a `Connection` and some options, return a `Statement`."
^java.sql.Statement
([con] (statement con {}))
([^Connection con
{:keys [result-type concurrency cursors
fetch-size max-rows timeout]
:as opts}]
(^java.sql.Statement
[con] (statement con {}))
(^java.sql.Statement
[^Connection con
{:keys [result-type concurrency cursors
fetch-size max-rows timeout]
:as opts}]
(let [^Statement stmt
(cond
(and result-type concurrency)

View file

@ -396,16 +396,23 @@
to realize a row by calling `datafiable-row` but still wants to call
these functions on the (realized) row."
(row-number [this]
"Return the current 1-based row number, if available.")
"Return the current 1-based row number, if available.
Should not cause any row realization.")
(column-names [this]
"Return a vector of the column names from the result set.")
"Return a vector of the column names from the result set.
Reifies the result builder, in order to construct column names,
but should not cause any row realization.")
(metadata [this]
"Return the raw `ResultSetMetaData` object from the result set.
If `next.jdbc.datafy` has been required, this will be fully-realized
as a Clojure data structure, otherwise this should not be allowed to
'leak' outside of the reducing function as it may depend on the
connection remaining open, in order to be valid."))
Should not cause any row realization.
If `next.jdbc.datafy` has been required, this metadata will be
fully-realized as a Clojure data structure, otherwise this should
not be allowed to 'leak' outside of the reducing function as it may
depend on the connection remaining open, in order to be valid."))
(defn- mapify-result-set
"Given a `ResultSet`, return an object that wraps the current row as a hash
@ -428,7 +435,7 @@
InspectableMapifiedResultSet
(row-number [this] (.getRow rs))
(column-names [this] (:cols @builder))
(metadata [this] (d/datafy (:rsmeta @builder)))
(metadata [this] (d/datafy (.getMetaData rs)))
clojure.lang.IPersistentMap
(assoc [this k v]
@ -510,7 +517,7 @@
;; that they can be thrown when the actual functions are called
(let [row (try (.getRow rs) (catch Throwable t t))
cols (try (:cols @builder) (catch Throwable t t))
meta (try (d/datafy (:rsmeta @builder)) (catch Throwable t t))]
meta (try (d/datafy (.getMetaData rs)) (catch Throwable t t))]
(with-meta
(row-builder @builder)
{`core-p/datafy

View file

@ -40,7 +40,8 @@
:schema/exception)))
data (set (keys (d/datafy con)))]
(when-let [diff (seq (set/difference data reference-keys))]
(println (:dbtype (db)) :connection (sort diff)))
(println (format "%6s :%-10s %s"
(:dbtype (db)) "connection" (str (sort diff)))))
(is (= reference-keys
(set/intersection reference-keys data)))))))
@ -87,7 +88,8 @@
:rowIdLifetime/exception)))
data (set (keys (d/datafy (.getMetaData con))))]
(when-let [diff (seq (set/difference data reference-keys))]
(println (:dbtype (db)) :db-meta (sort diff)))
(println (format "%6s :%-10s %s"
(:dbtype (db)) "db-meta" (str (sort diff)))))
(is (= reference-keys
(set/intersection reference-keys data))))))
(testing "nav to catalogs yields object"

View file

@ -72,4 +72,5 @@
:sql-params-fn start-fn
:execute-fn exec-fn})
sql-p)
(println (:dbtype (db)) (:calls @timing) "calls took" (long (:total @timing)) "nanoseconds")))
(println (format "%6s %d calls took %,10d nanoseconds"
(:dbtype (db)) (:calls @timing) (long (:total @timing))))))

View file

@ -4,6 +4,7 @@
"Multi-database testing fixtures."
(:require [clojure.string :as str]
[next.jdbc :as jdbc]
[next.jdbc.prepare :as prep]
[next.jdbc.sql :as sql])
(:import (io.zonky.test.db.postgres.embedded EmbeddedPostgres)))
@ -94,6 +95,16 @@
[]
@test-datasource)
(defn- do-commands
"Example from migration docs: this serves as a test for it."
[connectable commands]
(if (instance? java.sql.Connection connectable)
(with-open [stmt (prep/statement connectable)]
(run! #(.addBatch stmt %) commands)
(into [] (.executeBatch stmt)))
(with-open [conn (jdbc/get-connection connectable)]
(do-commands conn commands))))
(defn with-test-db
"Given a test function (or suite), run it in the context of an in-memory
H2 database set up with a simple fruit table containing four rows of data.
@ -128,9 +139,9 @@
(jdbc/execute-one! con ["DROP PROCEDURE FRUITP"])
(catch Throwable _)))
(try
(jdbc/execute-one! con [(str "DROP TABLE " fruit)])
(do-commands con [(str "DROP TABLE " fruit)])
(catch Throwable _))
(jdbc/execute-one! con [(str "
(do-commands con [(str "
CREATE TABLE " fruit " (
ID INTEGER " auto-inc-pk ",
NAME VARCHAR(32),