Compare commits
No commits in common. "develop" and "v1.3.981" have entirely different histories.
48 changed files with 291 additions and 668 deletions
|
|
@ -1,6 +0,0 @@
|
|||
{: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+}}}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
(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)
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
{: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}}}}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
;; 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}))
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
{:linters
|
||||
{:unresolved-symbol
|
||||
{:exclude [(cljs.test/is [match? thrown-match?])
|
||||
(clojure.test/is [match? thrown-match?])]}}}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
{: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/->>}}
|
||||
|
|
@ -1 +0,0 @@
|
|||
{:config-in-call {xtdb.api/template {:ignore [:unresolved-symbol :unresolved-namespace]}}}
|
||||
6
.github/workflows/test-and-release.yml
vendored
6
.github/workflows/test-and-release.yml
vendored
|
|
@ -15,11 +15,11 @@ jobs:
|
|||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '21'
|
||||
java-version: '11'
|
||||
- name: Setup Clojure
|
||||
uses: DeLaGuardo/setup-clojure@master
|
||||
with:
|
||||
cli: '1.12.0.1530'
|
||||
cli: '1.12.0.1488'
|
||||
- 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 -M:test:runner
|
||||
run: clojure -X:test
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: testing
|
||||
NEXT_JDBC_TEST_MYSQL: yes
|
||||
|
|
|
|||
11
.github/workflows/test-and-snapshot.yml
vendored
11
.github/workflows/test-and-snapshot.yml
vendored
|
|
@ -13,11 +13,11 @@ jobs:
|
|||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '21'
|
||||
java-version: '11'
|
||||
- name: Setup Clojure
|
||||
uses: DeLaGuardo/setup-clojure@master
|
||||
with:
|
||||
cli: '1.12.0.1530'
|
||||
cli: '1.12.0.1488'
|
||||
- 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 -M:test:runner
|
||||
run: clojure -X:test
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: testing
|
||||
NEXT_JDBC_TEST_MYSQL: yes
|
||||
|
|
@ -65,14 +65,15 @@ jobs:
|
|||
- name: Setup Clojure
|
||||
uses: DeLaGuardo/setup-clojure@master
|
||||
with:
|
||||
cli: '1.12.0.1530'
|
||||
cli: '1.12.0.1488'
|
||||
- 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:jdk${{ matrix.java }} test
|
||||
run: clojure -T:build test
|
||||
|
|
|
|||
6
.github/workflows/test.yml
vendored
6
.github/workflows/test.yml
vendored
|
|
@ -17,7 +17,7 @@ jobs:
|
|||
- name: Setup Clojure
|
||||
uses: DeLaGuardo/setup-clojure@master
|
||||
with:
|
||||
cli: '1.12.0.1530'
|
||||
cli: '1.12.0.1488'
|
||||
- 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 -M:test:runner
|
||||
run: clojure -X:test
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: testing
|
||||
NEXT_JDBC_TEST_MYSQL: yes
|
||||
NEXT_JDBC_TEST_MARIADB: yes
|
||||
- name: Run All Tests
|
||||
run: clojure -M:test:runner:jdk${{ matrix.java }}
|
||||
run: clojure -X:test
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: testing
|
||||
NEXT_JDBC_TEST_MYSQL: yes
|
||||
|
|
|
|||
9
.gitignore
vendored
9
.gitignore
vendored
|
|
@ -1,8 +1,11 @@
|
|||
*.class
|
||||
*.jar
|
||||
*.swp
|
||||
*~
|
||||
.calva/output-window/
|
||||
.calva/repl.calva-repl
|
||||
.classpath
|
||||
.clj-kondo/.cache
|
||||
.clj-kondo/.lock
|
||||
.cpcache
|
||||
.eastwood
|
||||
.factorypath
|
||||
|
|
@ -20,10 +23,6 @@
|
|||
.settings
|
||||
.socket-repl-port
|
||||
.sw*
|
||||
*.class
|
||||
*.jar
|
||||
*.swp
|
||||
*~
|
||||
/checkouts
|
||||
/classes
|
||||
/clojure_test_*
|
||||
|
|
|
|||
6
.joker
Normal file
6
.joker
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{:known-macros [next.jdbc/with-transaction]
|
||||
:ignored-unused-namespaces [next.jdbc.connection
|
||||
next.jdbc.date-time
|
||||
next.jdbc.prepare
|
||||
next.jdbc.result-set
|
||||
next.jdbc.transaction]}
|
||||
16
CHANGELOG.md
16
CHANGELOG.md
|
|
@ -2,22 +2,6 @@
|
|||
|
||||
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.
|
||||
* Fix [#181](https://github.com/seancorfield/next-jdbc/issues/181) (again!) by adding `Wrapped` protocol as a way for `DefaultOptions` and `SQLLogging` to consistently expose the underlying connectable, even when nested.
|
||||
|
||||
* 1.3.994 -- 2025-01-28
|
||||
* Fix [#293](https://github.com/seancorfield/next-jdbc/issues/293) by no longer `locking` on the `Connection` retrieved from a `DataSource`.
|
||||
* Fix documentation examples of `execute-batch!` via PR [#292](https://github.com/seancorfield/next-jdbc/pull/292) from [@devurandom](https://github.com/devurandom).
|
||||
* Update `java.data` to 1.3.113.
|
||||
* Beef up bit/boolean tests and enable them for XTDB.
|
||||
|
||||
* 1.3.981 -- 2024-12-13
|
||||
* Address [#291](https://github.com/seancorfield/next-jdbc/issues/291) by adding an XTDB section to **Tips & Tricks**.
|
||||
* Added XTDB as a supported database for testing via PR [#290](https://github.com/seancorfield/next-jdbc/pull/290). _Note: not all features are tested against XTDB due to several fundamental differences in architecture, mostly around primary key/generated keys and lack of DDL operations (since XTDB is schemaless)._
|
||||
|
|
|
|||
11
README.md
11
README.md
|
|
@ -8,11 +8,10 @@ The next generation of `clojure.java.jdbc`: a new low-level Clojure wrapper for
|
|||
|
||||
The latest versions on Clojars and on cljdoc:
|
||||
|
||||
[](https://clojars.org/com.github.seancorfield/next.jdbc)
|
||||
[](https://cljdoc.org/d/com.github.seancorfield/next.jdbc/CURRENT)
|
||||
[](https://clojars.org/com.github.seancorfield/next.jdbc)
|
||||
[](https://cljdoc.org/d/com.github.seancorfield/next.jdbc/CURRENT)
|
||||
[](https://clojurians.slack.com/app_redirect?channel=sql)
|
||||
[](http://clojurians.net)
|
||||
[](https://clojurians.zulipchat.com/#narrow/channel/152063-sql)
|
||||
|
||||
The documentation on [cljdoc.org](https://cljdoc.org/d/com.github.seancorfield/next.jdbc/CURRENT) is for the current version of `next.jdbc`:
|
||||
|
||||
|
|
@ -21,11 +20,11 @@ The documentation on [cljdoc.org](https://cljdoc.org/d/com.github.seancorfield/n
|
|||
* [Migrating from `clojure.java.jdbc`](https://cljdoc.org/d/com.github.seancorfield/next.jdbc/CURRENT/doc/migration-from-clojure-java-jdbc)
|
||||
* Feedback via [issues](https://github.com/seancorfield/next-jdbc/issues) or in the [`#sql` channel on the Clojurians Slack](https://clojurians.slack.com/messages/C1Q164V29/) or the [`#sql` stream on the Clojurians Zulip](https://clojurians.zulipchat.com/#narrow/stream/152063-sql).
|
||||
|
||||
The documentation on GitHub is for **develop** since the 1.3.1002 release -- [see the CHANGELOG](https://github.com/seancorfield/next-jdbc/blob/develop/CHANGELOG.md) and then read the [corresponding updated documentation](https://github.com/seancorfield/next-jdbc/tree/develop/doc) on GitHub if you want. Older versions of `next.jdbc` were published under the `seancorfield` group ID and you can find [older seancorfield/next.jdbc documentation on cljdoc.org](https://cljdoc.org/versions/seancorfield/next.jdbc).
|
||||
The documentation on GitHub is for **develop** since the 1.3.981 release -- [see the CHANGELOG](https://github.com/seancorfield/next-jdbc/blob/develop/CHANGELOG.md) and then read the [corresponding updated documentation](https://github.com/seancorfield/next-jdbc/tree/develop/doc) on GitHub if you want. Older versions of `next.jdbc` were published under the `seancorfield` group ID and you can find [older seancorfield/next.jdbc documentation on cljdoc.org](https://cljdoc.org/versions/seancorfield/next.jdbc).
|
||||
|
||||
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.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.
|
||||
> 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.
|
||||
|
||||
## Motivation
|
||||
|
||||
|
|
@ -51,7 +50,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 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!` -- 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-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).
|
||||
|
|
|
|||
14
build.clj
14
build.clj
|
|
@ -5,33 +5,29 @@
|
|||
clojure -T:build deploy
|
||||
|
||||
Run tests via:
|
||||
clojure -M:test:runner
|
||||
clojure -X:test
|
||||
|
||||
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]
|
||||
[clojure.string :as str]))
|
||||
[deps-deploy.deps-deploy :as dd]))
|
||||
|
||||
(def lib 'com.github.seancorfield/next.jdbc)
|
||||
(defn- the-version [patch] (format "1.3.%s" patch))
|
||||
(def version (the-version (b/git-count-revs nil)))
|
||||
(def snapshot (the-version "9999-SNAPSHOT"))
|
||||
(def snapshot (the-version "999-SNAPSHOT"))
|
||||
(def class-dir "target/classes")
|
||||
|
||||
(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 (cond-> [:test alias]
|
||||
(str/starts-with? (System/getProperty "java.version") "21")
|
||||
(conj :jdk21))})
|
||||
(let [basis (b/create-basis {:aliases [:test alias]})
|
||||
cmds (b/java-command
|
||||
{:basis basis
|
||||
:main 'clojure.main
|
||||
:main-args ["-m" "lazytest.main"]})
|
||||
:main-args ["-m" "cognitect.test-runner"]})
|
||||
{:keys [exit]} (b/process cmds)]
|
||||
(when-not (zero? exit) (throw (ex-info "Tests failed" {})))))
|
||||
opts)
|
||||
|
|
|
|||
50
deps.edn
50
deps.edn
|
|
@ -2,12 +2,12 @@
|
|||
"ossrh-snapshots" {:url "https://s01.oss.sonatype.org/content/repositories/snapshots"}}
|
||||
:paths ["src" "resources"]
|
||||
:deps {org.clojure/clojure {:mvn/version "1.10.3"}
|
||||
org.clojure/java.data {:mvn/version "1.3.113"}
|
||||
org.clojure/java.data {:mvn/version "1.2.107"}
|
||||
|
||||
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.7"}
|
||||
:build {:deps {io.github.clojure/tools.build {:mvn/version "0.10.6"}
|
||||
slipset/deps-deploy {:mvn/version "0.2.2"}}
|
||||
:ns-default build}
|
||||
|
||||
|
|
@ -17,11 +17,12 @@
|
|||
:1.12 {:override-deps {org.clojure/clojure {:mvn/version "1.12.0"}}}
|
||||
|
||||
;; running tests/checks of various kinds:
|
||||
:test {:extra-paths ["test"]
|
||||
:test {:extra-paths ["test"] ; can also run clojure -X:test
|
||||
:extra-deps {org.clojure/test.check {:mvn/version "1.1.1"}
|
||||
io.github.noahtheduke/lazytest {:mvn/version "1.6.1"}
|
||||
io.github.cognitect-labs/test-runner
|
||||
{:git/tag "v0.5.1" :git/sha "dfb30dd"}
|
||||
;; connection pooling
|
||||
com.zaxxer/HikariCP {:mvn/version "6.3.0"}
|
||||
com.zaxxer/HikariCP {:mvn/version "6.2.1"}
|
||||
com.mchange/c3p0 {:mvn/version "0.10.1"}
|
||||
;; JDBC drivers
|
||||
;; 10.16.x is JDK17+
|
||||
|
|
@ -30,29 +31,24 @@
|
|||
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.2"}
|
||||
com.mysql/mysql-connector-j {:mvn/version "9.2.0"}
|
||||
org.mariadb.jdbc/mariadb-java-client {:mvn/version "3.5.1"}
|
||||
com.mysql/mysql-connector-j {:mvn/version "9.1.0"}
|
||||
;; 42.7.4 changes update count (to -1) for stored procs:
|
||||
org.postgresql/postgresql {:mvn/version "42.7.5"}
|
||||
org.postgresql/postgresql {:mvn/version "42.7.4"}
|
||||
io.zonky.test/embedded-postgres {:mvn/version "2.1.0"}
|
||||
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"}
|
||||
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"}
|
||||
;; use log4j2 to reduce log noise during testing:
|
||||
org.apache.logging.log4j/log4j-api {:mvn/version "2.24.3"}
|
||||
org.apache.logging.log4j/log4j-api {:mvn/version "2.24.2"}
|
||||
;; bridge everything into log4j:
|
||||
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"]}}}
|
||||
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}}}
|
||||
|
|
|
|||
|
|
@ -33,9 +33,6 @@ Any path that calls `get-connection` will accept the following options:
|
|||
|
||||
If you need additional options set on a connection, you can either use Java interop to set them directly, or provide them as part of the "db spec" hash map passed to `get-datasource` (although then they will apply to _all_ connections obtained from that datasource).
|
||||
|
||||
Additional options passed are set as `java.util.Properties` and, by default, are coerced to strings.
|
||||
If you are working with a driver that requires a non-string value for a property (such as the Snowflake driver), you can provide a `:next.jdbc/as-is-properties` option containing a sequence of options that should be added as-is, rather than coerced to strings.
|
||||
|
||||
> Note: If `plan`, `execute!`, or `execute-one!` are passed a `DataSource`, a "db spec" hash map, or a JDBC URL string, they will call `get-connection`, so they will accept the above options in those cases.
|
||||
|
||||
## Generating SQL
|
||||
|
|
|
|||
|
|
@ -117,8 +117,8 @@ will use `execute-batch!` under the hood, instead of `execute!`, as follows:
|
|||
{:batch true})
|
||||
;; equivalent to
|
||||
(jdbc/execute-batch! ds
|
||||
"INSERT INTO address (name,email) VALUES (?,?)"
|
||||
[["Stella" "stella@artois.beer"]
|
||||
["INSERT INTO address (name,email) VALUES (?,?)"
|
||||
["Stella" "stella@artois.beer"]
|
||||
["Waldo" "waldo@lagunitas.beer"]
|
||||
["Aunt Sally" "sour@lagunitas.beer"]]
|
||||
{:return-keys true :return-generated-keys true})
|
||||
|
|
@ -131,8 +131,8 @@ will use `execute-batch!` under the hood, instead of `execute!`, as follows:
|
|||
{:batch true})
|
||||
;; equivalent to
|
||||
(jdbc/execute-batch! ds
|
||||
"INSERT INTO address (name,email) VALUES (?,?)"
|
||||
[["Stella" "stella@artois.beer"]
|
||||
["INSERT INTO address (name,email) VALUES (?,?)"
|
||||
["Stella" "stella@artois.beer"]
|
||||
["Waldo" "waldo@lagunitas.beer"]
|
||||
["Aunt Sally" "sour@lagunitas.beer"]]
|
||||
{:return-keys true :return-generated-keys true})
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ It is designed to work with Clojure 1.10 or later, supports `datafy`/`nav`, and
|
|||
You can add `next.jdbc` to your project with either:
|
||||
|
||||
```clojure
|
||||
com.github.seancorfield/next.jdbc {:mvn/version "1.3.1002"}
|
||||
com.github.seancorfield/next.jdbc {:mvn/version "1.3.981"}
|
||||
```
|
||||
for `deps.edn` or:
|
||||
|
||||
```clojure
|
||||
[com.github.seancorfield/next.jdbc "1.3.1002"]
|
||||
[com.github.seancorfield/next.jdbc "1.3.981"]
|
||||
```
|
||||
for `project.clj` or `build.boot`.
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ For the examples in this documentation, we will use a local H2 database on disk,
|
|||
```clojure
|
||||
;; deps.edn
|
||||
{:deps {org.clojure/clojure {:mvn/version "1.12.0"}
|
||||
com.github.seancorfield/next.jdbc {:mvn/version "1.3.1002"}
|
||||
com.github.seancorfield/next.jdbc {:mvn/version "1.3.981"}
|
||||
com.h2database/h2 {:mvn/version "2.3.232"}}}
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ services:
|
|||
ports:
|
||||
- "1433:1433"
|
||||
xtdb:
|
||||
image: ghcr.io/xtdb/xtdb:latest
|
||||
# pull_policy: always
|
||||
image: ghcr.io/xtdb/xtdb:nightly
|
||||
pull_policy: always
|
||||
ports:
|
||||
- "5432:5432"
|
||||
|
|
|
|||
|
|
@ -5,17 +5,9 @@
|
|||
(defn- run-tests [env v]
|
||||
(when v (println "\nTesting Clojure" v))
|
||||
(let [{:keys [exit]}
|
||||
(p/shell {:extra-env env}
|
||||
"clojure"
|
||||
(str "-M"
|
||||
(p/shell {:extra-env env} "clojure" (str "-X"
|
||||
(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")]
|
||||
":test"))]
|
||||
(when-not (zero? exit)
|
||||
(System/exit exit))))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;; copyright (c) 2018-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2018-2024 Sean Corfield, all rights reserved
|
||||
|
||||
(ns next.jdbc
|
||||
"The public API of the next generation java.jdbc library.
|
||||
|
|
@ -177,14 +177,6 @@
|
|||
[spec user password opts]
|
||||
(p/get-connection spec (assoc opts :user user :password password))))
|
||||
|
||||
(defn- ensure-sql-params [sql-params]
|
||||
(when-not (or (nil? sql-params)
|
||||
(and (seqable? sql-params)
|
||||
(or (empty? sql-params)
|
||||
(string? (first sql-params)))))
|
||||
(throw (ex-info "sql-params should be a vector containing a SQL string and any parameters"
|
||||
{:sql-params sql-params}))))
|
||||
|
||||
(defn prepare
|
||||
"Given a connection to a database, and a vector containing SQL and any
|
||||
parameters it needs, return a new `PreparedStatement`.
|
||||
|
|
@ -200,11 +192,9 @@
|
|||
be passed to prepare."
|
||||
(^java.sql.PreparedStatement
|
||||
[connection sql-params]
|
||||
(ensure-sql-params sql-params)
|
||||
(p/prepare connection sql-params {}))
|
||||
(^java.sql.PreparedStatement
|
||||
[connection sql-params opts]
|
||||
(ensure-sql-params sql-params)
|
||||
(p/prepare connection sql-params opts)))
|
||||
|
||||
(defn plan
|
||||
|
|
@ -242,12 +232,10 @@
|
|||
(p/-execute stmt [] {}))
|
||||
(^clojure.lang.IReduceInit
|
||||
[connectable sql-params]
|
||||
(ensure-sql-params sql-params)
|
||||
(p/-execute connectable sql-params
|
||||
{:next.jdbc/sql-params sql-params}))
|
||||
(^clojure.lang.IReduceInit
|
||||
[connectable sql-params opts]
|
||||
(ensure-sql-params sql-params)
|
||||
(p/-execute connectable sql-params
|
||||
(assoc opts :next.jdbc/sql-params sql-params))))
|
||||
|
||||
|
|
@ -264,11 +252,9 @@
|
|||
([stmt]
|
||||
(p/-execute-all stmt [] {}))
|
||||
([connectable sql-params]
|
||||
(ensure-sql-params sql-params)
|
||||
(p/-execute-all connectable sql-params
|
||||
{:next.jdbc/sql-params sql-params}))
|
||||
([connectable sql-params opts]
|
||||
(ensure-sql-params sql-params)
|
||||
(p/-execute-all connectable sql-params
|
||||
(assoc opts :next.jdbc/sql-params sql-params))))
|
||||
|
||||
|
|
@ -285,11 +271,9 @@
|
|||
([stmt]
|
||||
(p/-execute-one stmt [] {}))
|
||||
([connectable sql-params]
|
||||
(ensure-sql-params sql-params)
|
||||
(p/-execute-one connectable sql-params
|
||||
{:next.jdbc/sql-params sql-params}))
|
||||
([connectable sql-params opts]
|
||||
(ensure-sql-params sql-params)
|
||||
(p/-execute-one connectable sql-params
|
||||
(assoc opts :next.jdbc/sql-params sql-params))))
|
||||
|
||||
|
|
@ -352,9 +336,9 @@
|
|||
result))))
|
||||
params)))
|
||||
([connectable sql param-groups opts]
|
||||
(when-not (string? sql)
|
||||
(throw (IllegalArgumentException. "execute-batch! requires a SQL string")))
|
||||
(if (instance? java.sql.Connection (p/unwrap connectable))
|
||||
(if (or (instance? java.sql.Connection connectable)
|
||||
(and (satisfies? p/Connectable connectable)
|
||||
(instance? java.sql.Connection (:connectable connectable))))
|
||||
(with-open [ps (prepare connectable [sql] opts)]
|
||||
(execute-batch! ps param-groups opts))
|
||||
(with-open [con (get-connection connectable)]
|
||||
|
|
@ -381,10 +365,13 @@
|
|||
executes the body, and automatically closes it for you."
|
||||
[[sym connectable] & body]
|
||||
(let [con-sym (vary-meta sym assoc :tag 'java.sql.Connection)]
|
||||
`(let [con-obj# ~connectable
|
||||
bare-con# (p/unwrap con-obj#)]
|
||||
(if (instance? java.sql.Connection bare-con#)
|
||||
((^{:once true} fn* [~con-sym] ~@body) bare-con#)
|
||||
`(let [con-obj# ~connectable]
|
||||
(cond (instance? java.sql.Connection con-obj#)
|
||||
((^{:once true} fn* [~con-sym] ~@body) con-obj#)
|
||||
(and (satisfies? p/Connectable con-obj#)
|
||||
(instance? java.sql.Connection (:connectable con-obj#)))
|
||||
((^{:once true} fn* [~con-sym] ~@body) (:connectable con-obj#))
|
||||
:else
|
||||
(with-open [con# (get-connection con-obj#)]
|
||||
((^{:once true} fn* [~con-sym] ~@body) con#))))))
|
||||
|
||||
|
|
@ -416,8 +403,12 @@
|
|||
with `on-connection`."
|
||||
[[sym connectable] & body]
|
||||
`(let [con-obj# ~connectable]
|
||||
(if (instance? java.sql.Connection (p/unwrap con-obj#))
|
||||
(cond (instance? java.sql.Connection con-obj#)
|
||||
((^{:once true} fn* [~sym] ~@body) con-obj#)
|
||||
(and (satisfies? p/Connectable con-obj#)
|
||||
(instance? java.sql.Connection (:connectable con-obj#)))
|
||||
((^{:once true} fn* [~sym] ~@body) con-obj#)
|
||||
:else
|
||||
(with-open [con# (get-connection con-obj#)]
|
||||
((^{:once true} fn* [~sym] ~@body)
|
||||
(with-options con# (:options con-obj# {})))))))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;; copyright (c) 2018-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2018-2024 Sean Corfield, all rights reserved
|
||||
|
||||
(ns next.jdbc.connection
|
||||
"Standard implementations of `get-datasource` and `get-connection`.
|
||||
|
|
@ -374,12 +374,9 @@
|
|||
(defn- as-properties
|
||||
"Convert any seq of pairs to a `java.util.Properties` instance."
|
||||
^Properties [m]
|
||||
(let [p (Properties.)
|
||||
as-is (set (:next.jdbc/as-is-properties m))]
|
||||
(doseq [[k v] (dissoc m :next.jdbc/as-is-properties)]
|
||||
(if (contains? as-is k)
|
||||
(.put p (name k) v)
|
||||
(.setProperty p (name k) (str v))))
|
||||
(let [p (Properties.)]
|
||||
(doseq [[k v] m]
|
||||
(.setProperty p (name k) (str v)))
|
||||
p))
|
||||
|
||||
(defn uri->db-spec
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;; copyright (c) 2020-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2020-2024 Sean Corfield, all rights reserved
|
||||
|
||||
(ns ^:no-doc next.jdbc.default-options
|
||||
"Implementation of default options logic."
|
||||
|
|
@ -8,10 +8,6 @@
|
|||
|
||||
(defrecord DefaultOptions [connectable options])
|
||||
|
||||
(extend-protocol p/Wrapped
|
||||
DefaultOptions
|
||||
(unwrap [this] (p/unwrap (:connectable this))))
|
||||
|
||||
(extend-protocol p/Sourceable
|
||||
DefaultOptions
|
||||
(get-datasource [this]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;; copyright (c) 2018-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2018-2024 Sean Corfield, all rights reserved
|
||||
|
||||
(ns next.jdbc.protocols
|
||||
"This is the extensible core of the next generation java.jdbc library.
|
||||
|
|
@ -63,15 +63,3 @@
|
|||
:extend-via-metadata true
|
||||
(-transact [this body-fn opts]
|
||||
"Run the `body-fn` inside a transaction."))
|
||||
|
||||
(defprotocol Wrapped
|
||||
"Protocol for (un)wrapping a `next.jdbc` connectable.
|
||||
|
||||
Implementations are provided for `Object` (identity) and `DefaultOptions`
|
||||
and SQLLogging."
|
||||
(unwrap [this]
|
||||
"Unwrap the connectable to get the underlying connectable."))
|
||||
|
||||
(extend-protocol Wrapped
|
||||
Object
|
||||
(unwrap [this] this))
|
||||
|
|
|
|||
|
|
@ -323,7 +323,7 @@
|
|||
"An example column-reader that still uses `.getObject` but expands CLOB
|
||||
columns into strings."
|
||||
[^ResultSet rs ^ResultSetMetaData _ ^Integer i]
|
||||
(let [value (.getObject rs i)]
|
||||
(when-let [value (.getObject rs i)]
|
||||
(cond-> value
|
||||
(instance? Clob value)
|
||||
(clob->string))))
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@
|
|||
:opts (s/? ::opts-map)))
|
||||
|
||||
(s/fdef jdbc/prepare
|
||||
:args (s/cat :connection ::proto-connectable
|
||||
:args (s/cat :connection ::connection
|
||||
:sql-params ::sql-params
|
||||
:opts (s/? ::opts-map)))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;; copyright (c) 2021-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2021-2024 Sean Corfield, all rights reserved
|
||||
|
||||
(ns ^:no-doc next.jdbc.sql-logging
|
||||
"Implementation of sql-logging logic."
|
||||
|
|
@ -8,10 +8,6 @@
|
|||
|
||||
(defrecord SQLLogging [connectable sql-logger result-logger options])
|
||||
|
||||
(extend-protocol p/Wrapped
|
||||
SQLLogging
|
||||
(unwrap [this] (p/unwrap (:connectable this))))
|
||||
|
||||
(extend-protocol p/Sourceable
|
||||
SQLLogging
|
||||
(get-datasource [this]
|
||||
|
|
|
|||
|
|
@ -145,11 +145,7 @@
|
|||
javax.sql.DataSource
|
||||
(-transact [this body-fn opts]
|
||||
(with-open [con (p/get-connection this opts)]
|
||||
;; this connection is assumed unique so we do not need the active-tx check:
|
||||
(let [raw (raw-connection con)]
|
||||
;; we don't lock either, per #293:
|
||||
(binding [*active-tx* (conj *active-tx* raw)]
|
||||
(transact* con body-fn opts)))))
|
||||
(p/-transact con body-fn opts)))
|
||||
Object
|
||||
(-transact [this body-fn opts]
|
||||
(p/-transact (p/get-datasource this) body-fn opts)))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
|
||||
|
||||
(ns next.jdbc.connection-string-test
|
||||
"Tests for the main hash map spec to JDBC URL logic and the get-datasource
|
||||
|
|
@ -7,17 +7,15 @@
|
|||
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]
|
||||
[lazytest.core :refer [around set-ns-context!]]
|
||||
[lazytest.experimental.interfaces.clojure-test :refer [deftest is testing]]
|
||||
[clojure.test :refer [deftest is testing use-fixtures]]
|
||||
[next.jdbc.connection :as c]
|
||||
[next.jdbc.protocols :as p]
|
||||
[next.jdbc.specs :as specs]
|
||||
[next.jdbc.test-fixtures :refer [db with-test-db]])
|
||||
(:import [java.util Properties]))
|
||||
[next.jdbc.test-fixtures :refer [with-test-db db]]))
|
||||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
||||
(set-ns-context! [(around [f] (with-test-db f))])
|
||||
(use-fixtures :once with-test-db)
|
||||
|
||||
(specs/instrument)
|
||||
|
||||
|
|
@ -41,16 +39,3 @@
|
|||
(when (and user password)
|
||||
(with-open [con (p/get-connection ds {})]
|
||||
(is (instance? java.sql.Connection con)))))))
|
||||
|
||||
(deftest property-tests
|
||||
(is (string? (.getProperty ^Properties (#'c/as-properties {:foo [42]}) "foo")))
|
||||
(is (string? (.get ^Properties (#'c/as-properties {:foo [42]}) "foo")))
|
||||
(is (vector? (.get ^Properties (#'c/as-properties
|
||||
{:foo [42]
|
||||
:next.jdbc/as-is-properties [:foo]})
|
||||
"foo")))
|
||||
;; because .getProperty drops non-string values!
|
||||
(is (nil? (.getProperty ^Properties (#'c/as-properties
|
||||
{:foo [42]
|
||||
:next.jdbc/as-is-properties [:foo]})
|
||||
"foo"))))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2019-2024 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]
|
||||
[lazytest.experimental.interfaces.clojure-test :refer [deftest is testing]]
|
||||
[clojure.test :refer [deftest is testing]]
|
||||
[next.jdbc.connection :as c]
|
||||
[next.jdbc.protocols :as p])
|
||||
(:import (com.zaxxer.hikari HikariDataSource)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
;; copyright (c) 2020-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2020-2024 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]
|
||||
[lazytest.core :refer [around set-ns-context!]]
|
||||
[lazytest.experimental.interfaces.clojure-test :refer [deftest is testing]]
|
||||
[clojure.test :refer [deftest is testing use-fixtures]]
|
||||
[next.jdbc :as jdbc]
|
||||
[next.jdbc.datafy]
|
||||
[next.jdbc.result-set :as rs]
|
||||
|
|
@ -16,7 +15,7 @@
|
|||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
||||
(set-ns-context! [(around [f] (with-test-db f))])
|
||||
(use-fixtures :once with-test-db)
|
||||
|
||||
(specs/instrument)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2019-2024 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 [lazytest.core :refer [around set-ns-context!]]
|
||||
[lazytest.experimental.interfaces.clojure-test :refer [deftest]]
|
||||
(:require [clojure.test :refer [deftest is testing use-fixtures]]
|
||||
[next.jdbc :as jdbc]
|
||||
[next.jdbc.date-time] ; to extend SettableParameter to date/time
|
||||
[next.jdbc.test-fixtures :refer [with-test-db ds
|
||||
[next.jdbc.test-fixtures :refer [with-test-db db ds
|
||||
mssql? xtdb?]]
|
||||
[next.jdbc.specs :as specs]))
|
||||
[next.jdbc.specs :as specs])
|
||||
(:import (java.sql ResultSet)))
|
||||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
||||
(set-ns-context! [(around [f] (with-test-db f))])
|
||||
(use-fixtures :once with-test-db)
|
||||
|
||||
(specs/instrument)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
;; copyright (c) 2020-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2020-2024 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 [next.jdbc.default-options]))
|
||||
(:require [clojure.test :refer [deftest is testing]]
|
||||
[next.jdbc.default-options :refer :all]))
|
||||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;; copyright (c) 2024-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2024 Sean Corfield, all rights reserved
|
||||
|
||||
(ns next.jdbc.defer-test
|
||||
"The idea behind the next.jdbc.defer namespace is to provide a
|
||||
|
|
@ -11,8 +11,7 @@
|
|||
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 [lazytest.core :refer [around set-ns-context!]]
|
||||
[lazytest.experimental.interfaces.clojure-test :refer [deftest is testing]]
|
||||
(:require [clojure.test :refer [deftest is testing use-fixtures]]
|
||||
[next.jdbc :as jdbc]
|
||||
[next.jdbc.defer :as sut]
|
||||
[next.jdbc.test-fixtures
|
||||
|
|
@ -20,7 +19,7 @@
|
|||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
||||
(set-ns-context! [(around [f] (with-test-db f))])
|
||||
(use-fixtures :once with-test-db)
|
||||
|
||||
(deftest basic-test
|
||||
(when-not (xtdb?)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
|
||||
|
||||
(ns next.jdbc.optional-test
|
||||
"Test namespace for the optional builder functions."
|
||||
(:require [clojure.string :as str]
|
||||
[lazytest.core :refer [around set-ns-context!]]
|
||||
[lazytest.experimental.interfaces.clojure-test :refer [deftest is testing]]
|
||||
[clojure.test :refer [deftest is testing use-fixtures]]
|
||||
[next.jdbc.optional :as opt]
|
||||
[next.jdbc.protocols :as p]
|
||||
[next.jdbc.test-fixtures :refer [col-kw column default-options ds index
|
||||
|
|
@ -14,7 +13,7 @@
|
|||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
||||
(set-ns-context! [(around [f] (with-test-db f))])
|
||||
(use-fixtures :once with-test-db)
|
||||
|
||||
(deftest test-map-row-builder
|
||||
(testing "default row builder"
|
||||
|
|
@ -63,7 +62,7 @@
|
|||
(is (= "Peach" ((column :FRUIT/name) row))))))
|
||||
|
||||
(defn- default-column-reader
|
||||
[^ResultSet rs ^ResultSetMetaData _ ^Integer i]
|
||||
[^ResultSet rs ^ResultSetMetaData rsmeta ^Integer i]
|
||||
(.getObject rs i))
|
||||
|
||||
(deftest test-map-row-adapter
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
;; copyright (c) 2020-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2020-2024 Sean Corfield, all rights reserved
|
||||
|
||||
(ns next.jdbc.plan-test
|
||||
"Tests for the plan helpers."
|
||||
(:require [lazytest.core :refer [around]]
|
||||
[lazytest.experimental.interfaces.clojure-test :refer [deftest is]]
|
||||
(:require [clojure.test :refer [deftest is use-fixtures]]
|
||||
[next.jdbc.plan :as plan]
|
||||
[next.jdbc.specs :as specs]
|
||||
[next.jdbc.test-fixtures
|
||||
|
|
@ -12,10 +11,12 @@
|
|||
|
||||
(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
|
||||
|
|
@ -30,7 +31,6 @@
|
|||
[(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,7 +45,6 @@
|
|||
[(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 #{}})))
|
||||
|
|
@ -54,13 +53,11 @@
|
|||
{: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 % "-" "_")})))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
|
||||
|
||||
(ns next.jdbc.prepare-test
|
||||
"Stub test namespace for PreparedStatement creation etc.
|
||||
|
|
@ -8,8 +8,7 @@
|
|||
|
||||
The tests for the deprecated version of `execute-batch!` are here
|
||||
as a guard against regressions."
|
||||
(:require [lazytest.core :refer [around set-ns-context!]]
|
||||
[lazytest.experimental.interfaces.clojure-test :refer [deftest is testing]]
|
||||
(:require [clojure.test :refer [deftest is testing use-fixtures]]
|
||||
[next.jdbc :as jdbc]
|
||||
[next.jdbc.test-fixtures
|
||||
:refer [with-test-db ds jtds? mssql? sqlite? xtdb?]]
|
||||
|
|
@ -18,7 +17,7 @@
|
|||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
||||
(set-ns-context! [(around [f] (with-test-db f))])
|
||||
(use-fixtures :once with-test-db)
|
||||
|
||||
(specs/instrument)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2019-2024 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 [next.jdbc.protocols]))
|
||||
(:require [clojure.test :refer [deftest is testing]]
|
||||
[next.jdbc.protocols :refer :all]))
|
||||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
|
|
|||
|
|
@ -1,30 +1,34 @@
|
|||
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2019-2024 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 [lazytest.core :refer [defdescribe describe it expect]]
|
||||
(:require [clojure.test :refer [deftest are testing]]
|
||||
[next.jdbc.quoted :refer [ansi mysql sql-server oracle postgres
|
||||
schema]]))
|
||||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
||||
(def ^:private quote-fns [ansi mysql sql-server oracle postgres])
|
||||
(deftest basic-quoting
|
||||
(are [quote-fn quoted] (= (quote-fn "x") quoted)
|
||||
ansi "\"x\""
|
||||
mysql "`x`"
|
||||
sql-server "[x]"
|
||||
oracle "\"x\""
|
||||
postgres "\"x\""))
|
||||
|
||||
(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)))))))
|
||||
(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\"")))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
|
||||
|
||||
(ns next.jdbc.result-set-test
|
||||
"Test namespace for the result set functions.
|
||||
|
|
@ -8,8 +8,7 @@
|
|||
(:require [clojure.core.protocols :as core-p]
|
||||
[clojure.datafy :as d]
|
||||
[clojure.string :as str]
|
||||
[lazytest.core :refer [around set-ns-context!]]
|
||||
[lazytest.experimental.interfaces.clojure-test :refer [deftest is testing]]
|
||||
[clojure.test :refer [deftest is testing use-fixtures]]
|
||||
[next.jdbc.protocols :as p]
|
||||
[next.jdbc.result-set :as rs]
|
||||
[next.jdbc.specs :as specs]
|
||||
|
|
@ -20,7 +19,7 @@
|
|||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
||||
(set-ns-context! [(around [f] (with-test-db f))])
|
||||
(use-fixtures :once with-test-db)
|
||||
|
||||
(specs/instrument)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2019-2024 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 [next.jdbc.specs]))
|
||||
(:require [clojure.test :refer [deftest is testing]]
|
||||
[next.jdbc.specs :refer :all]))
|
||||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
|
||||
|
||||
(ns next.jdbc.sql.builder-test
|
||||
"Tests for the SQL string building functions in next.jdbc.sql.builder."
|
||||
(:require [lazytest.experimental.interfaces.clojure-test :refer [deftest is testing thrown?]]
|
||||
(:require [clojure.test :refer [deftest is testing]]
|
||||
[next.jdbc.quoted :refer [mysql sql-server]]
|
||||
[next.jdbc.sql.builder :as builder]))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,20 +1,19 @@
|
|||
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
|
||||
|
||||
(ns next.jdbc.sql-test
|
||||
"Tests for the syntactic sugar SQL functions."
|
||||
(:require [lazytest.core :refer [around set-ns-context!]]
|
||||
[lazytest.experimental.interfaces.clojure-test :refer [deftest is testing thrown?]]
|
||||
(:require [clojure.test :refer [deftest is testing use-fixtures]]
|
||||
[next.jdbc :as jdbc]
|
||||
[next.jdbc.specs :as specs]
|
||||
[next.jdbc.sql :as sql]
|
||||
[next.jdbc.test-fixtures
|
||||
:refer [col-kw column default-options derby? ds index jtds?
|
||||
maria? mssql? mysql? postgres? sqlite? with-test-db xtdb?]]
|
||||
:refer [column col-kw 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)
|
||||
|
||||
(set-ns-context! [(around [f] (with-test-db f))])
|
||||
(use-fixtures :once with-test-db)
|
||||
|
||||
(specs/instrument)
|
||||
|
||||
|
|
|
|||
|
|
@ -67,10 +67,7 @@
|
|||
(def ^:private test-xtdb-map {:dbtype "xtdb" :dbname "xtdb"})
|
||||
|
||||
(def ^:private test-xtdb
|
||||
(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))
|
||||
(when (System/getenv "NEXT_JDBC_TEST_XTDB") test-xtdb-map))
|
||||
|
||||
(def ^:private test-db-specs
|
||||
(cond-> [test-derby test-h2-mem test-h2 test-hsql test-sqlite]
|
||||
|
|
@ -83,8 +80,6 @@
|
|||
|
||||
(defn derby? [] (= "derby" (:dbtype @test-db-spec)))
|
||||
|
||||
(defn h2? [] (str/starts-with? (:dbtype @test-db-spec) "h2"))
|
||||
|
||||
(defn hsqldb? [] (= "hsqldb" (:dbtype @test-db-spec)))
|
||||
|
||||
(defn jtds? [] (= "jtds" (:dbtype @test-db-spec)))
|
||||
|
|
@ -185,10 +180,7 @@
|
|||
(if (xtdb?) ; no DDL for creation
|
||||
(do
|
||||
(try
|
||||
(do-commands con ["ERASE FROM fruit WHERE true"])
|
||||
(catch Throwable _))
|
||||
(try
|
||||
(do-commands con ["ERASE FROM btest WHERE true"])
|
||||
(do-commands con ["DELETE FROM fruit WHERE true"])
|
||||
(catch Throwable _))
|
||||
(sql/insert-multi! con :fruit
|
||||
[:_id :name :appearance :cost]
|
||||
|
|
|
|||
|
|
@ -1,10 +1,17 @@
|
|||
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2019-2024 Sean Corfield, all rights reserved
|
||||
|
||||
(ns next.jdbc.transaction-test
|
||||
"Stub test namespace for transaction handling."
|
||||
(:require [next.jdbc.specs :as specs]
|
||||
[next.jdbc.transaction]))
|
||||
(: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]))
|
||||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
||||
(use-fixtures :once with-test-db)
|
||||
|
||||
(specs/instrument)
|
||||
|
|
|
|||
|
|
@ -1,19 +1,14 @@
|
|||
;; copyright (c) 2020-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2020-2024 Sean Corfield, all rights reserved
|
||||
|
||||
(ns next.jdbc.types-test
|
||||
"Some tests for the type-assist functions."
|
||||
(:require [lazytest.core :refer [defdescribe describe it expect]]
|
||||
(:require [clojure.test :refer [deftest is]]
|
||||
[next.jdbc.types :refer [as-varchar]]))
|
||||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
||||
(defdescribe as-varchar-tests
|
||||
(deftest as-varchar-test
|
||||
(let [v (as-varchar "Hello")]
|
||||
(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)))))))
|
||||
(is (= "Hello" (v)))
|
||||
(is (contains? (meta v) 'next.jdbc.prepare/set-parameter))
|
||||
(is (fn? (get (meta v) 'next.jdbc.prepare/set-parameter)))))
|
||||
|
|
|
|||
|
|
@ -1,21 +1,19 @@
|
|||
;; copyright (c) 2019-2025 Sean Corfield, all rights reserved
|
||||
;; copyright (c) 2019-2024 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]
|
||||
[lazytest.core :refer [around defdescribe it ok?]]
|
||||
[lazytest.experimental.interfaces.clojure-test :refer [deftest is testing
|
||||
thrown?]]
|
||||
[clojure.test :refer [deftest is testing use-fixtures]]
|
||||
[next.jdbc :as jdbc]
|
||||
[next.jdbc.connection :as c]
|
||||
[next.jdbc.prepare :as prep]
|
||||
[next.jdbc.result-set :as rs]
|
||||
[next.jdbc.specs :as specs]
|
||||
[next.jdbc.test-fixtures
|
||||
:refer [col-kw column db default-options derby? ds h2? hsqldb?
|
||||
index jtds? mssql? mysql? postgres? sqlite? stored-proc?
|
||||
:refer [col-kw column db default-options derby? ds hsqldb? index
|
||||
jtds? mssql? mysql? postgres? sqlite? stored-proc?
|
||||
with-test-db xtdb?]]
|
||||
[next.jdbc.types :as types])
|
||||
(:import
|
||||
|
|
@ -25,22 +23,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)
|
||||
|
||||
(defdescribe spec-tests
|
||||
"sanity checks on instrumented function calls"
|
||||
{:context [(around [f] (with-test-db f))]}
|
||||
(deftest spec-tests
|
||||
(let [db-spec {:dbtype "h2:mem" :dbname "clojure_test"}]
|
||||
(it "succeeds with a basic db-spec"
|
||||
(ok? #(jdbc/get-datasource db-spec))
|
||||
(ok? #(jdbc/get-connection db-spec)))
|
||||
;; some sanity checks on instrumented function calls:
|
||||
(jdbc/get-datasource db-spec)
|
||||
(jdbc/get-connection db-spec)
|
||||
;; and again with options:
|
||||
(let [db-spec' (jdbc/with-options db-spec {})]
|
||||
(it "succeeds with an option-wrapped db-spec"
|
||||
(ok? #(jdbc/get-datasource db-spec'))
|
||||
(ok? #(jdbc/get-connection db-spec'))))))
|
||||
(jdbc/get-datasource db-spec')
|
||||
(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"
|
||||
|
|
@ -365,7 +363,6 @@ 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
|
||||
|
|
@ -482,7 +479,6 @@ 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) ["
|
||||
|
|
@ -505,42 +501,15 @@ 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")]
|
||||
(when-not (or (hsqldb?) (derby?))
|
||||
(testing "literal TRUE select"
|
||||
(is (= {(column :V) (if (or (sqlite?) (mysql?) (mssql?)) 1 true)}
|
||||
(jdbc/execute-one! (ds) [(str "SELECT " lit-t " AS V")]))))
|
||||
(testing "literal FALSE select"
|
||||
(is (= {(column :V) (if (or (sqlite?) (mysql?) (mssql?)) 0 false)}
|
||||
(jdbc/execute-one! (ds) [(str "SELECT " lit-f " AS V")])))))
|
||||
(testing "literal TRUE insert"
|
||||
(jdbc/execute-one!
|
||||
(ds)
|
||||
[(str "insert into btest (" (if (xtdb?) "_id" "name") ",is_it,twiddle)"
|
||||
" values ('lit_t'," lit-t ","
|
||||
(if (or (derby?) (sqlite?) (h2?) (mssql?) (xtdb?)) "1" "b'1'")
|
||||
")")]))
|
||||
(testing "literal FALSE insert"
|
||||
(jdbc/execute-one!
|
||||
(ds)
|
||||
[(str "insert into btest (" (if (xtdb?) "_id" "name") ",is_it,twiddle)"
|
||||
" values ('lit_f'," lit-f ","
|
||||
(if (or (derby?) (sqlite?) (h2?) (mssql?) (xtdb?)) "0" "b'0'")
|
||||
")")]))
|
||||
(testing "BIT/BOOLEAN value insertion"
|
||||
(when-not (xtdb?)
|
||||
(doseq [[n b] [["zero" 0] ["one" 1] ["false" false] ["true" true]]
|
||||
:let [v-bit (if (number? b) b (if b 1 0))
|
||||
v-bool (if (number? b) (pos? b) b)]]
|
||||
(jdbc/execute-one!
|
||||
(ds)
|
||||
[(str "insert into btest ("
|
||||
(if (xtdb?) "_id" "name")
|
||||
",is_it,twiddle) values (?,?,?)")
|
||||
["insert into btest (name,is_it,twiddle) values (?,?,?)"
|
||||
n
|
||||
(if (or (postgres?) (xtdb?))
|
||||
(if (postgres?)
|
||||
(types/as-boolean b)
|
||||
b) ; 0, 1, false, true are all acceptable
|
||||
(cond (hsqldb?)
|
||||
|
|
@ -548,20 +517,18 @@ VALUES ('Pear', 'green', 49, 47)
|
|||
(postgres?)
|
||||
(types/as-other v-bit) ; really postgres??
|
||||
:else
|
||||
v-bit)])))
|
||||
(testing "BOOLEAN results from SELECT"
|
||||
v-bit)]))
|
||||
(let [data (jdbc/execute! (ds) ["select * from btest"]
|
||||
(default-options))]
|
||||
(if (sqlite?)
|
||||
(is (every? number? (map (column :BTEST/IS_IT) data)))
|
||||
(is (every? boolean? (map (column :BTEST/IS_IT) data))))
|
||||
(if (or (sqlite?) (derby?) (xtdb?))
|
||||
(if (or (sqlite?) (derby?))
|
||||
(is (every? number? (map (column :BTEST/TWIDDLE) data)))
|
||||
(is (every? boolean? (map (column :BTEST/TWIDDLE) data))))))
|
||||
(testing "BOOLEAN read column by index"
|
||||
(is (every? boolean? (map (column :BTEST/TWIDDLE) data)))))
|
||||
(let [data (jdbc/execute! (ds) ["select * from btest"]
|
||||
(cond-> (default-options)
|
||||
(or (sqlite?) (xtdb?))
|
||||
(sqlite?)
|
||||
(assoc :builder-fn
|
||||
(rs/builder-adapter
|
||||
rs/as-maps
|
||||
|
|
@ -569,11 +536,8 @@ VALUES ('Pear', 'green', 49, 47)
|
|||
(let [rsm ^ResultSetMetaData (:rsmeta builder)]
|
||||
(rs/read-column-by-index
|
||||
;; we only use bit and bool for
|
||||
;; sqlite (not boolean), and
|
||||
;; int8 and bool for xtdb:
|
||||
(if (#{"BIT" "BOOL"
|
||||
"int8" "bool"}
|
||||
(.getColumnTypeName rsm i))
|
||||
;; sqlite (not boolean)
|
||||
(if (#{"BIT" "BOOL"} (.getColumnTypeName rsm i))
|
||||
(.getBoolean rs i)
|
||||
(.getObject rs i))
|
||||
rsm
|
||||
|
|
@ -581,21 +545,19 @@ VALUES ('Pear', 'green', 49, 47)
|
|||
(is (every? boolean? (map (column :BTEST/IS_IT) data)))
|
||||
(if (derby?)
|
||||
(is (every? number? (map (column :BTEST/TWIDDLE) data)))
|
||||
(is (every? boolean? (map (column :BTEST/TWIDDLE) data))))))
|
||||
(testing "BOOLEAN via coercion"
|
||||
(is (every? boolean? (map (column :BTEST/TWIDDLE) data)))))
|
||||
(let [data (reduce (fn [acc row]
|
||||
(conj acc (cond-> (select-keys row [:is_it :twiddle])
|
||||
(sqlite?)
|
||||
(update :is_it pos?)
|
||||
(or (sqlite?) (derby?) (xtdb?))
|
||||
(or (sqlite?) (derby?))
|
||||
(update :twiddle pos?))))
|
||||
[]
|
||||
(jdbc/plan (ds) ["select * from btest"]))]
|
||||
(is (every? boolean? (map :is_it data)))
|
||||
(is (every? boolean? (map :twiddle data))))))))
|
||||
(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]
|
||||
|
|
@ -698,7 +660,6 @@ 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]
|
||||
|
|
@ -739,16 +700,9 @@ INSERT INTO fruit (name, appearance) VALUES (?,?)
|
|||
(jdbc/execute-one! (ds) [(str "delete from fruit where " (index) " > 4")])))))
|
||||
(is (= 4 (count (jdbc/execute! (ds) ["select * from fruit"])))))
|
||||
(testing "batch with-logging"
|
||||
(let [tracker (atom {:opts 0, :log1 0 :log2 0})
|
||||
;; opts and log2 never get invoked with batch/prepare -- because
|
||||
;; no fn opts are invoked on that path, and no post-logging is done:
|
||||
track-fn (fn ([k] (fn [& _] (swap! tracker update k inc)))
|
||||
([k f] (fn [& args] (swap! tracker update k inc) (apply f args))))]
|
||||
(is (= {:opts 0, :log1 0 :log2 0} @tracker))
|
||||
(is (= [1 1 1 1 1 1 1 1 1 13]
|
||||
(try
|
||||
;; wrapping a non-connection will lose the wrapper:
|
||||
(let [result (jdbc/execute-batch! (jdbc/with-options (ds) {:builder-fn (track-fn :opts rs/as-maps)})
|
||||
(let [result (jdbc/execute-batch! (jdbc/with-logging (ds) println println)
|
||||
"INSERT INTO fruit (name, appearance) VALUES (?,?)"
|
||||
[["fruit1" "one"]
|
||||
["fruit2" "two"]
|
||||
|
|
@ -763,108 +717,7 @@ INSERT INTO fruit (name, appearance) VALUES (?,?)
|
|||
(conj result (count (jdbc/execute! (ds) ["select * from fruit"]))))
|
||||
(finally
|
||||
(jdbc/execute-one! (ds) [(str "delete from fruit where " (index) " > 4")])))))
|
||||
(is (= {:opts 0, :log1 0 :log2 0} @tracker))
|
||||
(is (= [1 1 1 1 1 1 1 1 1 13]
|
||||
(try
|
||||
;; wrapping a non-connection will lose the wrapper:
|
||||
(let [result (jdbc/execute-batch! (jdbc/with-logging (ds) {:builder-fn (track-fn :opts rs/as-maps)})
|
||||
"INSERT INTO fruit (name, appearance) VALUES (?,?)"
|
||||
[["fruit1" "one"]
|
||||
["fruit2" "two"]
|
||||
["fruit3" "three"]
|
||||
["fruit4" "four"]
|
||||
["fruit5" "five"]
|
||||
["fruit6" "six"]
|
||||
["fruit7" "seven"]
|
||||
["fruit8" "eight"]
|
||||
["fruit9" "nine"]]
|
||||
{})]
|
||||
(conj result (count (jdbc/execute! (ds) ["select * from fruit"]))))
|
||||
(finally
|
||||
(jdbc/execute-one! (ds) [(str "delete from fruit where " (index) " > 4")])))))
|
||||
(is (= {:opts 0, :log1 0 :log2 0} @tracker))
|
||||
(is (= [1 1 1 1 1 1 1 1 1 13]
|
||||
(try
|
||||
(with-open [con (jdbc/get-connection (ds))]
|
||||
(let [result (jdbc/execute-batch! (jdbc/with-options con {:builder-fn (track-fn :opts rs/as-maps)})
|
||||
"INSERT INTO fruit (name, appearance) VALUES (?,?)"
|
||||
[["fruit1" "one"]
|
||||
["fruit2" "two"]
|
||||
["fruit3" "three"]
|
||||
["fruit4" "four"]
|
||||
["fruit5" "five"]
|
||||
["fruit6" "six"]
|
||||
["fruit7" "seven"]
|
||||
["fruit8" "eight"]
|
||||
["fruit9" "nine"]]
|
||||
{})]
|
||||
(conj result (count (jdbc/execute! (ds) ["select * from fruit"])))))
|
||||
(finally
|
||||
(jdbc/execute-one! (ds) [(str "delete from fruit where " (index) " > 4")])))))
|
||||
(is (= {:opts 0, :log1 0 :log2 0} @tracker))
|
||||
(is (= [1 1 1 1 1 1 1 1 1 13]
|
||||
(try
|
||||
(with-open [con (jdbc/get-connection (ds))]
|
||||
(let [result (jdbc/execute-batch! (jdbc/with-logging con (track-fn :log1) (track-fn :log2))
|
||||
"INSERT INTO fruit (name, appearance) VALUES (?,?)"
|
||||
[["fruit1" "one"]
|
||||
["fruit2" "two"]
|
||||
["fruit3" "three"]
|
||||
["fruit4" "four"]
|
||||
["fruit5" "five"]
|
||||
["fruit6" "six"]
|
||||
["fruit7" "seven"]
|
||||
["fruit8" "eight"]
|
||||
["fruit9" "nine"]]
|
||||
{})]
|
||||
(conj result (count (jdbc/execute! (ds) ["select * from fruit"])))))
|
||||
(finally
|
||||
(jdbc/execute-one! (ds) [(str "delete from fruit where " (index) " > 4")])))))
|
||||
(is (= {:opts 0, :log1 1 :log2 0} @tracker))
|
||||
(is (= [1 1 1 1 1 1 1 1 1 13]
|
||||
(try
|
||||
(with-open [con (jdbc/get-connection (ds))]
|
||||
(let [result (jdbc/execute-batch! (jdbc/with-options
|
||||
(jdbc/with-logging con (track-fn :log1) (track-fn :log2))
|
||||
{:builder-fn (track-fn :opts rs/as-maps)})
|
||||
"INSERT INTO fruit (name, appearance) VALUES (?,?)"
|
||||
[["fruit1" "one"]
|
||||
["fruit2" "two"]
|
||||
["fruit3" "three"]
|
||||
["fruit4" "four"]
|
||||
["fruit5" "five"]
|
||||
["fruit6" "six"]
|
||||
["fruit7" "seven"]
|
||||
["fruit8" "eight"]
|
||||
["fruit9" "nine"]]
|
||||
{})]
|
||||
(conj result (count (jdbc/execute! (ds) ["select * from fruit"])))))
|
||||
(finally
|
||||
(jdbc/execute-one! (ds) [(str "delete from fruit where " (index) " > 4")])))))
|
||||
(is (= {:opts 0, :log1 2 :log2 0} @tracker))
|
||||
(is (= [1 1 1 1 1 1 1 1 1 13]
|
||||
(try
|
||||
(with-open [con (jdbc/get-connection (ds))]
|
||||
(let [result (jdbc/execute-batch! (jdbc/with-logging
|
||||
(jdbc/with-options con
|
||||
{:builder-fn (track-fn :opts rs/as-maps)})
|
||||
(track-fn :log1) (track-fn :log2))
|
||||
"INSERT INTO fruit (name, appearance) VALUES (?,?)"
|
||||
[["fruit1" "one"]
|
||||
["fruit2" "two"]
|
||||
["fruit3" "three"]
|
||||
["fruit4" "four"]
|
||||
["fruit5" "five"]
|
||||
["fruit6" "six"]
|
||||
["fruit7" "seven"]
|
||||
["fruit8" "eight"]
|
||||
["fruit9" "nine"]]
|
||||
{})]
|
||||
(conj result (count (jdbc/execute! (ds) ["select * from fruit"])))))
|
||||
(finally
|
||||
(jdbc/execute-one! (ds) [(str "delete from fruit where " (index) " > 4")])))))
|
||||
(is (= {:opts 0, :log1 3 :log2 0} @tracker))
|
||||
(is (= 4 (count (jdbc/execute! (ds) ["select * from fruit"]))))))
|
||||
(is (= 4 (count (jdbc/execute! (ds) ["select * from fruit"])))))
|
||||
(testing "small batch insert"
|
||||
(is (= [1 1 1 1 1 1 1 1 1 13]
|
||||
(try
|
||||
|
|
@ -955,7 +808,6 @@ 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))
|
||||
|
|
@ -1014,7 +866,6 @@ 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))
|
||||
|
|
@ -1041,7 +892,6 @@ 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
|
||||
|
|
@ -1090,7 +940,6 @@ 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"])))]
|
||||
|
|
@ -1112,7 +961,6 @@ 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
|
||||
|
|
@ -1133,7 +981,6 @@ 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
|
||||
|
|
|
|||
Loading…
Reference in a new issue