Compare commits

...

28 commits

Author SHA1 Message Date
Sean Corfield
e3b80e6128
auto-add :jdk21 for xtdb
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-04-24 18:13:02 -04:00
Sean Corfield
150a4aa605
only run xtdb tests on jdk21+
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-04-24 18:04:14 -04:00
Sean Corfield
2a30c5cffd
back to xtdb beta 7
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-04-24 09:17:00 -04:00
Sean Corfield
0c385c36a6
temporarily drop back to xtdb beta 6 to debug CI
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-04-24 09:11:47 -04:00
Sean Corfield
af827c0200
update xtdb to beta 7
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-04-24 08:49:56 -04:00
Sean Corfield
0ff09dca21
note #299 / #300 in changelog
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-04-22 20:16:33 -04:00
Sean Corfield
fd3c61b1e6
Merge pull request #300 from GAumala/false-column-clob-builder
Allow false column values in clob-column-reader
2025-04-17 23:52:02 -04:00
Gabriel Aumala
a3fba32605 Allow false column values in clob-column-reader 2025-04-17 19:41:15 -05:00
Sean Corfield
f39f6b3d24
re-enable xtdb testing using beta6
instead of nightly

Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-27 10:30:55 -07:00
Sean Corfield
99075cd408
disable xtdb in ci for now
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-25 21:01:08 -07:00
Sean Corfield
14b4c3435f
move jdk24 jvm-opts to separate
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-25 20:48:46 -07:00
Sean Corfield
a40abc285e
update dev/test/build deps
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-25 17:35:16 -07:00
Sean Corfield
16c1faeaf6
more test cleanup
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-17 17:49:46 -07:00
Sean Corfield
d1115c8c42
switch quoted tests to core lazytest dsl
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-17 17:23:12 -07:00
Sean Corfield
60503dac03
put the refers back in! oops!
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-12 19:09:16 -07:00
Sean Corfield
a829074b99
clean up some tests
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-12 18:52:51 -07:00
Sean Corfield
532d77f372
note lazytest in changelog
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-12 18:45:39 -07:00
Sean Corfield
e650137f07
Merge pull request #297 from seancorfield/lazytest
migrate test suite to lazytest
2025-03-12 18:02:34 -07:00
Sean Corfield
9fdc24eab7
remove prep lib; restore gitlibs cache
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-10 10:15:42 -07:00
Sean Corfield
1642cc04ca
update to lazytest 1.6.1
revert throws? back to thrown?

Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-10 10:13:33 -07:00
Sean Corfield
9d1c35b86c
fix the slf4j nudge warning
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-08 14:21:05 -08:00
Sean Corfield
ed8ba5402a
reduce a couple of gratuitous diffs
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-08 13:41:16 -08:00
Sean Corfield
403d156331
don't cache gitlibs
avoid prep lib java version issue

Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-08 12:43:22 -08:00
Sean Corfield
78894f8ba4
and remove 1.11 override
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-08 12:38:23 -08:00
Sean Corfield
0d7b3b60ed
restore clojure 1.10 testing
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-08 12:34:28 -08:00
Sean Corfield
2214e06cfa
restore ns require layout
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-07 17:43:44 -08:00
Sean Corfield
0d7d58fece
migrate test suite to lazytest
no longer tests against clojure 1.10 (issue created)

Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-07 17:31:13 -08:00
Sean Corfield
c2b64dbd54
fix snapshot version ref
Signed-off-by: Sean Corfield <sean@corfield.org>
2025-03-06 13:01:15 -08:00
36 changed files with 324 additions and 152 deletions

View file

@ -0,0 +1,6 @@
{:linters {:cond-plus/empty-else {:level :error}
:cond-plus/missing-fn {:level :error}
:cond-plus/non-final-else {:level :error}
:cond-plus/sequence {:level :error}
:unresolved-symbol {:exclude [(cond-plus.core/cond+ [=> else])]}}
:hooks {:analyze-call {cond-plus.core/cond+ hooks.cond-plus-hook/cond+}}}

View file

@ -0,0 +1,65 @@
(ns hooks.cond-plus-hook
(:require [clj-kondo.hooks-api :as api]))
(defn analyze-clauses [clauses]
(reduce
(fn [found-else? clause]
;; non-sequence clause
(if (not (or (api/list-node? clause)
(api/vector-node? clause)))
(let [{:keys [row col]} (meta clause)]
(api/reg-finding!
{:message "must be sequence"
:type :cond-plus/sequence
:row row
:col col})
found-else?)
(let [[sym arrow fn-expr] (api/sexpr clause)]
(cond
;; non-final else
found-else?
(do (api/reg-finding!
(merge
{:message ":else must be in final position"
:type :cond-plus/non-final-else}
found-else?))
(reduced nil))
;; check fn-exprs
(and (or (= :> arrow)
(= '=> arrow))
(nil? fn-expr))
(let [{:keys [row col]} (meta clause)]
(api/reg-finding!
{:message "fn-expr must have third position symbol"
:type :cond-plus/missing-fn
:row row
:col col})
found-else?)
;; else handling
(or (= :else sym)
(= 'else sym))
(if found-else?
(let [{:keys [row col]} (meta clause)]
(api/reg-finding!
{:message "only one :else clause allowed"
:type :cond-plus/empty-else
:row row
:col col})
;; early exit cuz not worth analyzing the rest
(reduced nil))
(do (when-not arrow
(let [{:keys [row col]} (meta clause)]
(api/reg-finding!
{:message ":else must have a body"
:type :cond-plus/empty-else
:row row
:col col})))
;; Store row and col from existing else as we don't throw until
;; we've seen a following clause
(select-keys (meta clause) [:row :col])))))))
nil
clauses))
(defn cond+ [{:keys [node]}]
(analyze-clauses (rest (:children node)))
node)

View file

@ -0,0 +1,23 @@
{:lint-as {lazytest.core/given clojure.core/let
lazytest.core/around clojure.core/fn
lazytest.core/defdescribe clojure.core/def
;; clojure.test interface
lazytest.experimental.interfaces.clojure-test/deftest clojure.test/deftest
lazytest.experimental.interfaces.clojure-test/testing clojure.test/testing
lazytest.experimental.interfaces.clojure-test/is clojure.test/is
lazytest.experimental.interfaces.clojure-test/are clojure.test/are
;; xunit interface
lazytest.experimental.interfaces.xunit/defsuite clojure.core/def
;; Expectations v2
lazytest.extensions.expectations/defexpect clojure.core/def
lazytest.extensions.expectations/from-each clojure.core/for
lazytest.extensions.expectations/=? clojure.core/=
}
:hooks {:analyze-call {;; Expectations v2
lazytest.extensions.expectations/more-> hooks.lazytest.expectations/more->
lazytest.extensions.expectations/more-of hooks.lazytest.expectations/more-of
}}
:linters {:clojure-lsp/unused-public-var
{:exclude-when-defined-by #{lazytest.core/defdescribe
lazytest.experimental.interfaces.xunit/defsuite
lazytest.experimental.interfaces.clojure-test/deftest}}}}

View file

@ -0,0 +1,31 @@
;; Copied from https://github.com/clojure-expectations/clojure-test/blob/b90ed5b24924238b3b16b0bbaaee4c3b05a1268a
(ns hooks.lazytest.expectations
(:require [clj-kondo.hooks-api :as api]))
(defn more-> [{:keys [node]}]
(let [tail (rest (:children node))
rewritten
(api/list-node
(list*
(api/token-node 'cond->)
(api/token-node 'nil)
tail))]
{:node rewritten}))
(defn more-of [{:keys [node]}]
(let [bindings (fnext (:children node))
pairs (partition 2 (nnext (:children node)))
rewritten
(api/list-node
(list*
(api/token-node 'fn)
(api/vector-node (vector bindings))
(map (fn [[e a]]
(api/list-node
(list
(api/token-node 'lazytest.core/expect)
e
a)))
pairs)))]
{:node rewritten}))

View file

@ -0,0 +1,4 @@
{:linters
{:unresolved-symbol
{:exclude [(cljs.test/is [match? thrown-match?])
(clojure.test/is [match? thrown-match?])]}}}

View file

@ -0,0 +1,5 @@
{:lint-as
{rewrite-clj.zip/subedit-> clojure.core/->
rewrite-clj.zip/subedit->> clojure.core/->>
rewrite-clj.zip/edit-> clojure.core/->
rewrite-clj.zip/edit->> clojure.core/->>}}

View file

@ -15,11 +15,11 @@ jobs:
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '11'
java-version: '21'
- name: Setup Clojure
uses: DeLaGuardo/setup-clojure@master
with:
cli: '1.12.0.1488'
cli: '1.12.0.1530'
- name: Cache All The Things
uses: actions/cache@v4
with:
@ -34,7 +34,7 @@ jobs:
env:
MYSQL_ROOT_PASSWORD: testing
- name: Run MariaDB Tests
run: clojure -X:test
run: clojure -M:test:runner
env:
MYSQL_ROOT_PASSWORD: testing
NEXT_JDBC_TEST_MYSQL: yes

View file

@ -13,11 +13,11 @@ jobs:
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '11'
java-version: '21'
- name: Setup Clojure
uses: DeLaGuardo/setup-clojure@master
with:
cli: '1.12.0.1488'
cli: '1.12.0.1530'
- name: Cache All The Things
uses: actions/cache@v4
with:
@ -32,7 +32,7 @@ jobs:
env:
MYSQL_ROOT_PASSWORD: testing
- name: Run MariaDB Tests
run: clojure -X:test
run: clojure -M:test:runner
env:
MYSQL_ROOT_PASSWORD: testing
NEXT_JDBC_TEST_MYSQL: yes
@ -65,15 +65,14 @@ jobs:
- name: Setup Clojure
uses: DeLaGuardo/setup-clojure@master
with:
cli: '1.12.0.1488'
cli: '1.12.0.1530'
- name: Cache All The Things
uses: actions/cache@v4
with:
path: |
~/.m2/repository
~/.gitlibs
~/.clojure
~/.cpcache
key: ${{ runner.os }}-${{ hashFiles('**/deps.edn') }}
- name: Run Tests
run: clojure -T:build test
run: clojure -T:build:jdk${{ matrix.java }} test

View file

@ -17,7 +17,7 @@ jobs:
- name: Setup Clojure
uses: DeLaGuardo/setup-clojure@master
with:
cli: '1.12.0.1488'
cli: '1.12.0.1530'
- name: Cache All The Things
uses: actions/cache@v4
with:
@ -32,13 +32,13 @@ jobs:
env:
MYSQL_ROOT_PASSWORD: testing
- name: Run MariaDB Tests
run: clojure -X:test
run: clojure -M:test:runner
env:
MYSQL_ROOT_PASSWORD: testing
NEXT_JDBC_TEST_MYSQL: yes
NEXT_JDBC_TEST_MARIADB: yes
- name: Run All Tests
run: clojure -X:test
run: clojure -M:test:runner:jdk${{ matrix.java }}
env:
MYSQL_ROOT_PASSWORD: testing
NEXT_JDBC_TEST_MYSQL: yes

9
.gitignore vendored
View file

@ -1,11 +1,8 @@
*.class
*.jar
*.swp
*~
.calva/output-window/
.calva/repl.calva-repl
.classpath
.clj-kondo/.cache
.clj-kondo/.lock
.cpcache
.eastwood
.factorypath
@ -23,6 +20,10 @@
.settings
.socket-repl-port
.sw*
*.class
*.jar
*.swp
*~
/checkouts
/classes
/clojure_test_*

View file

@ -2,6 +2,11 @@
Only accretive/fixative changes will be made from now on.
* 1.3.next in progress
* Fix handling of `false` in `clob-column-reader` [#299](https://github.com/seancorfield/next-jdbc/issues/299) via PR [#300](https://github.com/seancorfield/next-jdbc/pull/300) from [@GAumala](https://github.com/GAumala)
* Switch tests to LazyTest via PR [#297](https://github.com/seancorfield/next-jdbc/pull/297).
* Update dev/test/build deps.
* 1.3.1002 -- 2025-03-06
* Address [#296](https://github.com/seancorfield/next-jdbc/issues/296) by adding an explicit check (and `throw`) for `sql-params` in `next.jdbc` functions.
* Address [#295](https://github.com/seancorfield/next-jdbc/issues/295) by providing a way to tell `next.jdbc` that certain options should be passed "as-is" in the `Properties` object when creating a `Connection` -- `:next.jdbc/as-is-properties` accepts a sequence (or set) of keywords, identifying properties that should not be converted to strings.

View file

@ -25,7 +25,7 @@ The documentation on GitHub is for **develop** since the 1.3.1002 release -- [se
This project follows the version scheme MAJOR.MINOR.COMMITS where MAJOR and MINOR provide some relative indication of the size of the change, but do not follow semantic versioning. In general, all changes endeavor to be non-breaking (by moving to new names rather than by breaking existing names). COMMITS is an ever-increasing counter of commits since the beginning of this repository.
> Note: every commit to the **develop** branch runs CI (GitHub Actions) and successful runs push a MAJOR.MINOR.999-SNAPSHOT build to Clojars so the very latest version of `next.jdbc` is always available either via that [snapshot on Clojars](https://clojars.org/com.github.seancorfield/next.jdbc) or via a git dependency on the latest SHA.
> Note: every commit to the **develop** branch runs CI (GitHub Actions) and successful runs push a MAJOR.MINOR.9999-SNAPSHOT build to Clojars so the very latest version of `next.jdbc` is always available either via that [snapshot on Clojars](https://clojars.org/com.github.seancorfield/next.jdbc) or via a git dependency on the latest SHA.
## Motivation
@ -51,7 +51,7 @@ From a `DataSource`, either you or `next.jdbc` can create a `java.sql.Connection
The primary SQL execution API in `next.jdbc` is:
* `plan` -- yields an `IReduceInit` that, when reduced with an initial value, executes the SQL statement and then reduces over the `ResultSet` with as little overhead as possible.
* `execute!` -- executes the SQL statement and produces a vector of realized hash maps, that use qualified keywords for the column names, of the form `:<table>/<column>`. If you join across multiple tables, the qualified keywords will reflect the originating tables for each of the columns. If the SQL produces named values that do not come from an associated table, a simple, unqualified keyword will be used. The realized hash maps returned by `execute!` are `Datafiable` and thus `Navigable` (see Clojure 1.10's `datafy` and `nav` functions, and tools like [Portal](https://github.com/djblue/portal), [Reveal](https://github.com/vlaaad/reveal), and Cognitect's REBL). Alternatively, you can specify `{:builder-fn rs/as-arrays}` and produce a vector with column names followed by vectors of row values. `rs/as-maps` is the default for `:builder-fn` but there are also `rs/as-unqualified-maps` and `rs/as-unqualified-arrays` if you want unqualified `:<column>` column names (and there are also lower-case variants of all of these).
* `execute!` -- executes the SQL statement and produces a vector of realized hash maps, that use qualified keywords for the column names, of the form `:<table>/<column>`. If you join across multiple tables, the qualified keywords will reflect the originating tables for each of the columns. If the SQL produces named values that do not come from an associated table, a simple, unqualified keyword will be used. The realized hash maps returned by `execute!` are `Datafiable` and thus `Navigable` (see Clojure 1.10's `datafy` and `nav` functions, and tools like [Portal](https://github.com/djblue/portal), [Reveal](https://github.com/vlaaad/reveal), and Nubank's Morse -- formerly Cognitect's REBL). Alternatively, you can specify `{:builder-fn rs/as-arrays}` and produce a vector with column names followed by vectors of row values. `rs/as-maps` is the default for `:builder-fn` but there are also `rs/as-unqualified-maps` and `rs/as-unqualified-arrays` if you want unqualified `:<column>` column names (and there are also lower-case variants of all of these).
* `execute-one!` -- executes the SQL or DDL statement and produces a single realized hash map. The realized hash map returned by `execute-one!` is `Datafiable` and thus `Navigable`.
In addition, there are API functions to create `PreparedStatement`s (`prepare`) from `Connection`s, which can be passed to `plan`, `execute!`, or `execute-one!`, and to run code inside a transaction (the `transact` function and the `with-transaction` macro).

View file

@ -5,14 +5,15 @@
clojure -T:build deploy
Run tests via:
clojure -X:test
clojure -M:test:runner
For more information, run:
clojure -A:deps -T:build help/doc"
(:refer-clojure :exclude [test])
(:require [clojure.tools.build.api :as b]
[deps-deploy.deps-deploy :as dd]))
[deps-deploy.deps-deploy :as dd]
[clojure.string :as str]))
(def lib 'com.github.seancorfield/next.jdbc)
(defn- the-version [patch] (format "1.3.%s" patch))
@ -23,11 +24,14 @@
(defn test "Run all the tests." [opts]
(doseq [alias [:1.10 :1.11 :1.12]]
(println "\nRunning tests for Clojure" (name alias))
(let [basis (b/create-basis {:aliases [:test alias]})
(let [basis (b/create-basis
{:aliases (cond-> [:test alias]
(str/starts-with? (System/getProperty "java.version") "21")
(conj :jdk21))})
cmds (b/java-command
{:basis basis
:main 'clojure.main
:main-args ["-m" "cognitect.test-runner"]})
:main-args ["-m" "lazytest.main"]})
{:keys [exit]} (b/process cmds)]
(when-not (zero? exit) (throw (ex-info "Tests failed" {})))))
opts)

View file

@ -7,7 +7,7 @@
camel-snake-kebab/camel-snake-kebab {:mvn/version "0.4.3"}}
:aliases
{;; for help: clojure -A:deps -T:build help/doc
:build {:deps {io.github.clojure/tools.build {:mvn/version "0.10.6"}
:build {:deps {io.github.clojure/tools.build {:mvn/version "0.10.7"}
slipset/deps-deploy {:mvn/version "0.2.2"}}
:ns-default build}
@ -17,12 +17,11 @@
:1.12 {:override-deps {org.clojure/clojure {:mvn/version "1.12.0"}}}
;; running tests/checks of various kinds:
:test {:extra-paths ["test"] ; can also run clojure -X:test
:test {:extra-paths ["test"]
:extra-deps {org.clojure/test.check {:mvn/version "1.1.1"}
io.github.cognitect-labs/test-runner
{:git/tag "v0.5.1" :git/sha "dfb30dd"}
io.github.noahtheduke/lazytest {:mvn/version "1.6.1"}
;; connection pooling
com.zaxxer/HikariCP {:mvn/version "6.2.1"}
com.zaxxer/HikariCP {:mvn/version "6.3.0"}
com.mchange/c3p0 {:mvn/version "0.10.1"}
;; JDBC drivers
;; 10.16.x is JDK17+
@ -31,24 +30,29 @@
org.hsqldb/hsqldb {:mvn/version "2.7.4"}
com.h2database/h2 {:mvn/version "2.3.232"}
net.sourceforge.jtds/jtds {:mvn/version "1.3.1"}
org.mariadb.jdbc/mariadb-java-client {:mvn/version "3.5.1"}
com.mysql/mysql-connector-j {:mvn/version "9.1.0"}
org.mariadb.jdbc/mariadb-java-client {:mvn/version "3.5.2"}
com.mysql/mysql-connector-j {:mvn/version "9.2.0"}
;; 42.7.4 changes update count (to -1) for stored procs:
org.postgresql/postgresql {:mvn/version "42.7.4"}
org.postgresql/postgresql {:mvn/version "42.7.5"}
io.zonky.test/embedded-postgres {:mvn/version "2.1.0"}
io.zonky.test.postgres/embedded-postgres-binaries-darwin-amd64 {:mvn/version "17.2.0"}
io.zonky.test.postgres/embedded-postgres-binaries-linux-amd64 {:mvn/version "17.2.0"}
io.zonky.test.postgres/embedded-postgres-binaries-windows-amd64 {:mvn/version "17.2.0"}
org.xerial/sqlite-jdbc {:mvn/version "3.47.1.0"}
com.microsoft.sqlserver/mssql-jdbc {:mvn/version "12.8.1.jre11"}
;; prerelease XTDB JDBC module:
com.xtdb/xtdb-jdbc {:mvn/version "2.0.0-SNAPSHOT"}
io.zonky.test.postgres/embedded-postgres-binaries-darwin-amd64 {:mvn/version "17.4.0"}
io.zonky.test.postgres/embedded-postgres-binaries-linux-amd64 {:mvn/version "17.4.0"}
io.zonky.test.postgres/embedded-postgres-binaries-windows-amd64 {:mvn/version "17.4.0"}
org.xerial/sqlite-jdbc {:mvn/version "3.49.1.0"}
com.microsoft.sqlserver/mssql-jdbc {:mvn/version "12.10.0.jre11"}
;; use log4j2 to reduce log noise during testing:
org.apache.logging.log4j/log4j-api {:mvn/version "2.24.2"}
org.apache.logging.log4j/log4j-api {:mvn/version "2.24.3"}
;; bridge everything into log4j:
org.apache.logging.log4j/log4j-1.2-api {:mvn/version "2.24.2"}
org.apache.logging.log4j/log4j-jcl {:mvn/version "2.24.2"}
org.apache.logging.log4j/log4j-jul {:mvn/version "2.24.2"}
org.apache.logging.log4j/log4j-slf4j-impl {:mvn/version "2.24.2"}}
:jvm-opts ["-Dlog4j2.configurationFile=log4j2-info.properties"]
:exec-fn cognitect.test-runner.api/test}}}
org.apache.logging.log4j/log4j-1.2-api {:mvn/version "2.24.3"}
org.apache.logging.log4j/log4j-jcl {:mvn/version "2.24.3"}
org.apache.logging.log4j/log4j-jul {:mvn/version "2.24.3"}
org.apache.logging.log4j/log4j-slf4j-impl {:mvn/version "2.24.3"}
org.apache.logging.log4j/log4j-slf4j2-impl {:mvn/version "2.24.3"}}
:jvm-opts ["-Dlog4j2.configurationFile=log4j2-info.properties"]}
:runner {:main-opts ["-m" "lazytest.main"]}
:jdk11 {}
:jdk17 {}
:jdk21 {:extra-deps {;; only need the XTDB JDBC module:
com.xtdb/xtdb-jdbc {:mvn/version "2.0.0-beta7"}}}
:jdk24 {:jvm-opts [;; for SQLite on JDK 24 locally
"--enable-native-access=ALL-UNNAMED"]}}}

View file

@ -15,7 +15,7 @@ services:
ports:
- "1433:1433"
xtdb:
image: ghcr.io/xtdb/xtdb:nightly
pull_policy: always
image: ghcr.io/xtdb/xtdb:latest
# pull_policy: always
ports:
- "5432:5432"

View file

@ -5,9 +5,17 @@
(defn- run-tests [env v]
(when v (println "\nTesting Clojure" v))
(let [{:keys [exit]}
(p/shell {:extra-env env} "clojure" (str "-X"
(when v (str ":" v))
":test"))]
(p/shell {:extra-env env}
"clojure"
(str "-M"
(when v (str ":" v))
":test:runner"
;; jdk21+ adds xtdb:
(when (System/getenv "NEXT_JDBC_TEST_XTDB")
":jdk21")
;; to suppress native access warnings on JDK24:
":jdk24")
"--output" "dots")]
(when-not (zero? exit)
(System/exit exit))))

View file

@ -323,7 +323,7 @@
"An example column-reader that still uses `.getObject` but expands CLOB
columns into strings."
[^ResultSet rs ^ResultSetMetaData _ ^Integer i]
(when-let [value (.getObject rs i)]
(let [value (.getObject rs i)]
(cond-> value
(instance? Clob value)
(clob->string))))

View file

@ -7,7 +7,8 @@
At some point, the datasource/connection tests should probably be extended
to accept EDN specs from an external source (environment variables?)."
(:require [clojure.string :as str]
[clojure.test :refer [deftest is testing use-fixtures]]
[lazytest.core :refer [around set-ns-context!]]
[lazytest.experimental.interfaces.clojure-test :refer [deftest is testing]]
[next.jdbc.connection :as c]
[next.jdbc.protocols :as p]
[next.jdbc.specs :as specs]
@ -16,7 +17,7 @@
(set! *warn-on-reflection* true)
(use-fixtures :once with-test-db)
(set-ns-context! [(around [f] (with-test-db f))])
(specs/instrument)

View file

@ -1,4 +1,4 @@
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
(ns next.jdbc.connection-test
"Tests for the main hash map spec to JDBC URL logic and the get-datasource
@ -7,7 +7,7 @@
At some point, the datasource/connection tests should probably be extended
to accept EDN specs from an external source (environment variables?)."
(:require [clojure.string :as str]
[clojure.test :refer [deftest is testing]]
[lazytest.experimental.interfaces.clojure-test :refer [deftest is testing]]
[next.jdbc.connection :as c]
[next.jdbc.protocols :as p])
(:import (com.zaxxer.hikari HikariDataSource)

View file

@ -1,10 +1,11 @@
;; copyright (c) 2020-2024 Sean Corfield, all rights reserved
;; copyright (c) 2020-2025 Sean Corfield, all rights reserved
(ns next.jdbc.datafy-test
"Tests for the datafy extensions over JDBC types."
(:require [clojure.datafy :as d]
[clojure.set :as set]
[clojure.test :refer [deftest is testing use-fixtures]]
[lazytest.core :refer [around set-ns-context!]]
[lazytest.experimental.interfaces.clojure-test :refer [deftest is testing]]
[next.jdbc :as jdbc]
[next.jdbc.datafy]
[next.jdbc.result-set :as rs]
@ -15,7 +16,7 @@
(set! *warn-on-reflection* true)
(use-fixtures :once with-test-db)
(set-ns-context! [(around [f] (with-test-db f))])
(specs/instrument)

View file

@ -1,4 +1,4 @@
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
(ns next.jdbc.date-time-test
"Date/time parameter auto-conversion tests.
@ -6,17 +6,17 @@
These tests contain no assertions. Without requiring `next.jdbc.date-time`
several of the `insert` operations would throw exceptions for some databases
so the test here just checks those operations 'succeed'."
(:require [clojure.test :refer [deftest is testing use-fixtures]]
(:require [lazytest.core :refer [around set-ns-context!]]
[lazytest.experimental.interfaces.clojure-test :refer [deftest]]
[next.jdbc :as jdbc]
[next.jdbc.date-time] ; to extend SettableParameter to date/time
[next.jdbc.test-fixtures :refer [with-test-db db ds
[next.jdbc.test-fixtures :refer [with-test-db ds
mssql? xtdb?]]
[next.jdbc.specs :as specs])
(:import (java.sql ResultSet)))
[next.jdbc.specs :as specs]))
(set! *warn-on-reflection* true)
(use-fixtures :once with-test-db)
(set-ns-context! [(around [f] (with-test-db f))])
(specs/instrument)

View file

@ -1,9 +1,8 @@
;; copyright (c) 2020-2024 Sean Corfield, all rights reserved
;; copyright (c) 2020-2025 Sean Corfield, all rights reserved
(ns next.jdbc.default-options-test
"Stub test namespace for default options. Nothing can really be tested
at this level tho'..."
(:require [clojure.test :refer [deftest is testing]]
[next.jdbc.default-options :refer :all]))
(:require [next.jdbc.default-options]))
(set! *warn-on-reflection* true)

View file

@ -1,4 +1,4 @@
;; copyright (c) 2024 Sean Corfield, all rights reserved
;; copyright (c) 2024-2025 Sean Corfield, all rights reserved
(ns next.jdbc.defer-test
"The idea behind the next.jdbc.defer namespace is to provide a
@ -11,7 +11,8 @@
describes a series of SQL operations to be performed, that
are held in a dynamic var, and that can be executed at a
later time, in a transaction."
(:require [clojure.test :refer [deftest is testing use-fixtures]]
(:require [lazytest.core :refer [around set-ns-context!]]
[lazytest.experimental.interfaces.clojure-test :refer [deftest is testing]]
[next.jdbc :as jdbc]
[next.jdbc.defer :as sut]
[next.jdbc.test-fixtures
@ -19,7 +20,7 @@
(set! *warn-on-reflection* true)
(use-fixtures :once with-test-db)
(set-ns-context! [(around [f] (with-test-db f))])
(deftest basic-test
(when-not (xtdb?)

View file

@ -1,9 +1,10 @@
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
(ns next.jdbc.optional-test
"Test namespace for the optional builder functions."
(:require [clojure.string :as str]
[clojure.test :refer [deftest is testing use-fixtures]]
[lazytest.core :refer [around set-ns-context!]]
[lazytest.experimental.interfaces.clojure-test :refer [deftest is testing]]
[next.jdbc.optional :as opt]
[next.jdbc.protocols :as p]
[next.jdbc.test-fixtures :refer [col-kw column default-options ds index
@ -13,7 +14,7 @@
(set! *warn-on-reflection* true)
(use-fixtures :once with-test-db)
(set-ns-context! [(around [f] (with-test-db f))])
(deftest test-map-row-builder
(testing "default row builder"
@ -62,7 +63,7 @@
(is (= "Peach" ((column :FRUIT/name) row))))))
(defn- default-column-reader
[^ResultSet rs ^ResultSetMetaData rsmeta ^Integer i]
[^ResultSet rs ^ResultSetMetaData _ ^Integer i]
(.getObject rs i))
(deftest test-map-row-adapter

View file

@ -1,8 +1,9 @@
;; copyright (c) 2020-2024 Sean Corfield, all rights reserved
;; copyright (c) 2020-2025 Sean Corfield, all rights reserved
(ns next.jdbc.plan-test
"Tests for the plan helpers."
(:require [clojure.test :refer [deftest is use-fixtures]]
(:require [lazytest.core :refer [around]]
[lazytest.experimental.interfaces.clojure-test :refer [deftest is]]
[next.jdbc.plan :as plan]
[next.jdbc.specs :as specs]
[next.jdbc.test-fixtures
@ -11,12 +12,10 @@
(set! *warn-on-reflection* true)
;; around each test because of the folding tests using 1,000 rows
(use-fixtures :each with-test-db)
(specs/instrument)
(deftest select-one!-tests
{:context [(around [f] (with-test-db f))]}
(is (= {(col-kw :id) 1}
(plan/select-one! (ds) [(col-kw :id)] [(str "select * from fruit order by " (index))])))
(is (= 1
@ -31,6 +30,7 @@
[(str "select * from fruit order by " (index))]))))
(deftest select-vector-tests
{:context [(around [f] (with-test-db f))]}
(is (= [{(col-kw :id) 1} {(col-kw :id) 2} {(col-kw :id) 3} {(col-kw :id) 4}]
(plan/select! (ds) [(col-kw :id)] [(str "select * from fruit order by " (index))])))
(is (= [1 2 3 4]
@ -45,6 +45,7 @@
[(str "select * from fruit where " (index) " = ?") 2]))))
(deftest select-set-tests
{:context [(around [f] (with-test-db f))]}
(is (= #{{(col-kw :id) 1} {(col-kw :id) 2} {(col-kw :id) 3} {(col-kw :id) 4}}
(plan/select! (ds) [(col-kw :id)] [(str "select * from fruit order by " (index))]
{:into #{}})))
@ -53,11 +54,13 @@
{:into #{}}))))
(deftest select-map-tests
{:context [(around [f] (with-test-db f))]}
(is (= {1 "Apple", 2 "Banana", 3 "Peach", 4 "Orange"}
(plan/select! (ds) (juxt (col-kw :id) :name) [(str "select * from fruit order by " (index))]
{:into {}}))))
(deftest select-issue-227
{:context [(around [f] (with-test-db f))]}
(is (= ["Apple"]
(plan/select! (ds) :name [(str "select * from fruit where " (index) " = ?") 1]
{:column-fn #(str/replace % "-" "_")})))

View file

@ -1,4 +1,4 @@
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
(ns next.jdbc.prepare-test
"Stub test namespace for PreparedStatement creation etc.
@ -8,7 +8,8 @@
The tests for the deprecated version of `execute-batch!` are here
as a guard against regressions."
(:require [clojure.test :refer [deftest is testing use-fixtures]]
(:require [lazytest.core :refer [around set-ns-context!]]
[lazytest.experimental.interfaces.clojure-test :refer [deftest is testing]]
[next.jdbc :as jdbc]
[next.jdbc.test-fixtures
:refer [with-test-db ds jtds? mssql? sqlite? xtdb?]]
@ -17,7 +18,7 @@
(set! *warn-on-reflection* true)
(use-fixtures :once with-test-db)
(set-ns-context! [(around [f] (with-test-db f))])
(specs/instrument)

View file

@ -1,9 +1,8 @@
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
(ns next.jdbc.protocols-test
"Stub test namespace for low-level protocols. Nothing can really be tested
at this level tho'..."
(:require [clojure.test :refer [deftest is testing]]
[next.jdbc.protocols :refer :all]))
(:require [next.jdbc.protocols]))
(set! *warn-on-reflection* true)

View file

@ -1,34 +1,30 @@
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
(ns next.jdbc.quoted-test
"Basic tests for quoting strategies. These are also tested indirectly
via the next.jdbc.sql tests."
(:require [clojure.test :refer [deftest are testing]]
(:require [lazytest.core :refer [defdescribe describe it expect]]
[next.jdbc.quoted :refer [ansi mysql sql-server oracle postgres
schema]]))
(set! *warn-on-reflection* true)
(deftest basic-quoting
(are [quote-fn quoted] (= (quote-fn "x") quoted)
ansi "\"x\""
mysql "`x`"
sql-server "[x]"
oracle "\"x\""
postgres "\"x\""))
(def ^:private quote-fns [ansi mysql sql-server oracle postgres])
(deftest schema-quoting
(testing "verify non-schema behavior"
(are [quote-fn quoted] (= (quote-fn "x.y") quoted)
ansi "\"x.y\""
mysql "`x.y`"
sql-server "[x.y]"
oracle "\"x.y\""
postgres "\"x.y\""))
(testing "verify schema behavior"
(are [quote-fn quoted] (= ((schema quote-fn) "x.y") quoted)
ansi "\"x\".\"y\""
mysql "`x`.`y`"
sql-server "[x].[y]"
oracle "\"x\".\"y\""
postgres "\"x\".\"y\"")))
(defdescribe quoted-functionality
(describe "base quoting"
(it "should correctly quote simple names"
(doseq [[f e] (map vector quote-fns
["\"x\"" "`x`" "[x]" "\"x\"" "\"x\""])]
(expect (= (f "x") e)))))
(describe "dotted name quoting"
(describe "basic quoting"
(it "should quote dotted names 'as-is'"
(doseq [[f e] (map vector quote-fns
["\"x.y\"" "`x.y`" "[x.y]" "\"x.y\"" "\"x.y\""])]
(expect (= (f "x.y") e)))))
(describe "schema quoting"
(it "should split and quote dotted names with schema"
(doseq [[f e] (map vector quote-fns
["\"x\".\"y\"" "`x`.`y`" "[x].[y]" "\"x\".\"y\"" "\"x\".\"y\""])]
(expect (= ((schema f) "x.y") e)))))))

View file

@ -1,4 +1,4 @@
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
(ns next.jdbc.result-set-test
"Test namespace for the result set functions.
@ -8,7 +8,8 @@
(:require [clojure.core.protocols :as core-p]
[clojure.datafy :as d]
[clojure.string :as str]
[clojure.test :refer [deftest is testing use-fixtures]]
[lazytest.core :refer [around set-ns-context!]]
[lazytest.experimental.interfaces.clojure-test :refer [deftest is testing]]
[next.jdbc.protocols :as p]
[next.jdbc.result-set :as rs]
[next.jdbc.specs :as specs]
@ -19,7 +20,7 @@
(set! *warn-on-reflection* true)
(use-fixtures :once with-test-db)
(set-ns-context! [(around [f] (with-test-db f))])
(specs/instrument)

View file

@ -1,11 +1,10 @@
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
(ns next.jdbc.specs-test
"Stub test namespace for the specs.
The specs are used (and 'tested') as part of the tests for the
next.jdbc and next.jdbc.sql namespaces."
(:require [clojure.test :refer [deftest is testing]]
[next.jdbc.specs :refer :all]))
(:require [next.jdbc.specs]))
(set! *warn-on-reflection* true)

View file

@ -1,8 +1,8 @@
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
(ns next.jdbc.sql.builder-test
"Tests for the SQL string building functions in next.jdbc.sql.builder."
(:require [clojure.test :refer [deftest is testing]]
(:require [lazytest.experimental.interfaces.clojure-test :refer [deftest is testing thrown?]]
[next.jdbc.quoted :refer [mysql sql-server]]
[next.jdbc.sql.builder :as builder]))

View file

@ -1,19 +1,20 @@
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
(ns next.jdbc.sql-test
"Tests for the syntactic sugar SQL functions."
(:require [clojure.test :refer [deftest is testing use-fixtures]]
(:require [lazytest.core :refer [around set-ns-context!]]
[lazytest.experimental.interfaces.clojure-test :refer [deftest is testing thrown?]]
[next.jdbc :as jdbc]
[next.jdbc.specs :as specs]
[next.jdbc.sql :as sql]
[next.jdbc.test-fixtures
:refer [column col-kw default-options derby? ds index
jtds? maria? mssql? mysql? postgres? sqlite? with-test-db xtdb?]]
:refer [col-kw column default-options derby? ds index jtds?
maria? mssql? mysql? postgres? sqlite? with-test-db xtdb?]]
[next.jdbc.types :refer [as-other as-real as-varchar]]))
(set! *warn-on-reflection* true)
(use-fixtures :once with-test-db)
(set-ns-context! [(around [f] (with-test-db f))])
(specs/instrument)
@ -276,8 +277,8 @@
(deftest no-empty-order-by
(is (thrown? clojure.lang.ExceptionInfo
(sql/find-by-keys (ds) :fruit
{:name "Apple"}
{:order-by []}))))
{:name "Apple"}
{:order-by []}))))
(deftest array-in
(when (postgres?)

View file

@ -67,7 +67,10 @@
(def ^:private test-xtdb-map {:dbtype "xtdb" :dbname "xtdb"})
(def ^:private test-xtdb
(when (System/getenv "NEXT_JDBC_TEST_XTDB") test-xtdb-map))
(when (and (System/getenv "NEXT_JDBC_TEST_XTDB")
;; only if we're on jdk21+
(str/starts-with? (System/getProperty "java.version") "2"))
test-xtdb-map))
(def ^:private test-db-specs
(cond-> [test-derby test-h2-mem test-h2 test-hsql test-sqlite]

View file

@ -1,17 +1,10 @@
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
(ns next.jdbc.transaction-test
"Stub test namespace for transaction handling."
(:require [clojure.test :refer [deftest is testing use-fixtures]]
[next.jdbc :as jdbc]
[next.jdbc.specs :as specs]
[next.jdbc.test-fixtures :refer [with-test-db db ds column
default-options
derby? mssql? mysql? postgres?]]
[next.jdbc.transaction :as tx]))
(:require [next.jdbc.specs :as specs]
[next.jdbc.transaction]))
(set! *warn-on-reflection* true)
(use-fixtures :once with-test-db)
(specs/instrument)

View file

@ -1,14 +1,19 @@
;; copyright (c) 2020-2024 Sean Corfield, all rights reserved
;; copyright (c) 2020-2025 Sean Corfield, all rights reserved
(ns next.jdbc.types-test
"Some tests for the type-assist functions."
(:require [clojure.test :refer [deftest is]]
(:require [lazytest.core :refer [defdescribe describe it expect]]
[next.jdbc.types :refer [as-varchar]]))
(set! *warn-on-reflection* true)
(deftest as-varchar-test
(defdescribe as-varchar-tests
(let [v (as-varchar "Hello")]
(is (= "Hello" (v)))
(is (contains? (meta v) 'next.jdbc.prepare/set-parameter))
(is (fn? (get (meta v) 'next.jdbc.prepare/set-parameter)))))
(describe "produces a function"
(it "yields the original value when invoked"
(expect (fn? v))
(expect (= "Hello" (v)))))
(describe "carries metadata"
(it "has a `set-parameter` function"
(expect (contains? (meta v) 'next.jdbc.prepare/set-parameter))
(expect (fn? (get (meta v) 'next.jdbc.prepare/set-parameter)))))))

View file

@ -1,11 +1,13 @@
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
(ns next.jdbc-test
"Basic tests for the primary API of `next.jdbc`."
(:require
[clojure.core.reducers :as r]
[clojure.string :as str]
[clojure.test :refer [deftest is testing use-fixtures]]
[lazytest.core :refer [around defdescribe it ok?]]
[lazytest.experimental.interfaces.clojure-test :refer [deftest is testing
thrown?]]
[next.jdbc :as jdbc]
[next.jdbc.connection :as c]
[next.jdbc.prepare :as prep]
@ -23,22 +25,22 @@
(set! *warn-on-reflection* true)
;; around each test because of the folding tests using 1,000 rows
(use-fixtures :each with-test-db)
(specs/instrument)
(deftest spec-tests
(defdescribe spec-tests
"sanity checks on instrumented function calls"
{:context [(around [f] (with-test-db f))]}
(let [db-spec {:dbtype "h2:mem" :dbname "clojure_test"}]
;; some sanity checks on instrumented function calls:
(jdbc/get-datasource db-spec)
(jdbc/get-connection db-spec)
;; and again with options:
(it "succeeds with a basic db-spec"
(ok? #(jdbc/get-datasource db-spec))
(ok? #(jdbc/get-connection db-spec)))
(let [db-spec' (jdbc/with-options db-spec {})]
(jdbc/get-datasource db-spec')
(jdbc/get-connection db-spec'))))
(it "succeeds with an option-wrapped db-spec"
(ok? #(jdbc/get-datasource db-spec'))
(ok? #(jdbc/get-connection db-spec'))))))
(deftest basic-tests
{:context [(around [f] (with-test-db f))]}
;; use ds-opts instead of (ds) anywhere you want default options applied:
(let [ds-opts (jdbc/with-options (ds) (default-options))]
(testing "plan"
@ -363,6 +365,7 @@ VALUES ('Pear', 'green', 49, 47)
(is (= ac (.getAutoCommit con))))))))
(deftest issue-146
{:context [(around [f] (with-test-db f))]}
;; since we use an embedded PostgreSQL data source, we skip this:
(when-not (or (postgres?) (xtdb?)
;; and now we skip MS SQL because we can't use the db-spec
@ -479,6 +482,7 @@ VALUES ('Pear', 'green', 49, 47)
#_
(deftest duplicate-insert-test
{:context [(around [f] (with-test-db f))]}
;; this is primarily a look at exception types/information for #226
(try
(jdbc/execute! (ds) ["
@ -501,6 +505,7 @@ VALUES ('Pear', 'green', 49, 47)
"\n\t" (ex-message t)))))
(deftest bool-tests
{:context [(around [f] (with-test-db f))]} ;; Ensure the test database is used
(testing (str "bool-tests for " (:dbtype (db)))
(let [lit-t (cond (hsqldb?) "(1=1)" (mssql?) "1" :else "TRUE")
lit-f (cond (hsqldb?) "(1=0)" (mssql?) "0" :else "FALSE")]
@ -590,6 +595,7 @@ VALUES ('Pear', 'green', 49, 47)
(is (every? boolean? (map :twiddle data))))))))
(deftest execute-batch-tests
{:context [(around [f] (with-test-db f))]}
(when-not (xtdb?)
(testing "simple batch insert"
(is (= [1 1 1 1 1 1 1 1 1 13]
@ -692,6 +698,7 @@ INSERT INTO fruit (name, appearance) VALUES (?,?)
(is (= 4 (count (jdbc/execute! (ds) ["select * from fruit"]))))))))
(deftest execute-batch-connectable-tests
{:context [(around [f] (with-test-db f))]}
(when-not (xtdb?)
(testing "simple batch insert"
(is (= [1 1 1 1 1 1 1 1 1 13]
@ -948,6 +955,7 @@ INSERT INTO fruit (name, appearance) VALUES (?,?)
(is (= 4 (count (jdbc/execute! (ds) ["select * from fruit"]))))))))
(deftest folding-test
{:context [(around [f] (with-test-db f))]}
(jdbc/execute-one! (ds) ["delete from fruit"])
(if (xtdb?)
(with-open [con (jdbc/get-connection (ds))
@ -1006,6 +1014,7 @@ INSERT INTO fruit (name, appearance) VALUES (?,?)
(is (= "Fruit-1000" (last result)))))))
(deftest connection-tests
{:context [(around [f] (with-test-db f))]}
(testing "datasource via jdbcUrl"
(when-not (or (postgres?) (xtdb?))
(let [[url etc] (#'c/spec->url+etc (db))
@ -1032,6 +1041,7 @@ INSERT INTO fruit (name, appearance) VALUES (?,?)
(is (instance? java.sql.Connection con)))))))
(deftest multi-rs
{:context [(around [f] (with-test-db f))]}
(when (mssql?)
(testing "script with multiple result sets"
(let [multi-rs
@ -1080,6 +1090,7 @@ INSERT INTO fruit (name, appearance) VALUES (?,?)
(println 'call-proc (:dbtype (db)) (ex-message t) (some-> t (ex-cause) (ex-message))))))))
(deftest plan-misuse
{:context [(around [f] (with-test-db f))]}
(let [s (pr-str (jdbc/plan (ds) ["select * from fruit"]))]
(is (re-find #"missing reduction" s)))
(let [s (pr-str (into [] (jdbc/plan (ds) ["select * from fruit"])))]
@ -1101,6 +1112,7 @@ INSERT INTO fruit (name, appearance) VALUES (?,?)
(doall (take 3 (jdbc/plan (ds) ["select * from fruit"]))))))
(deftest issue-204
{:context [(around [f] (with-test-db f))]}
(testing "against a Connection"
(is (seq (with-open [con (jdbc/get-connection (ds))]
(jdbc/on-connection
@ -1121,6 +1133,7 @@ INSERT INTO fruit (name, appearance) VALUES (?,?)
(jdbc/execute! x ["select * from fruit"]))))))
(deftest issue-256
{:context [(around [f] (with-test-db f))]}
(testing "against a Connection"
(is (seq (with-open [con (jdbc/get-connection (ds))]
(jdbc/on-connection+options