Address #21 by adding next.jdbc.specs

Docs still need to be updated for this!
This commit is contained in:
Sean Corfield 2019-05-21 21:45:05 -07:00
parent 45f25d1912
commit adf5a03e05
4 changed files with 157 additions and 1 deletions

View file

@ -11,4 +11,5 @@
The following changes have been committed to the **master** branch and will be in the next release (Beta 1):
* Set up CircleCI testing (just local DBs for now).
* Address #21 by adding `next.jdbc.specs` -- still need to update the docs!
* Fix #19 by caching loaded database driver classes.

149
src/next/jdbc/specs.clj Normal file
View file

@ -0,0 +1,149 @@
;; copyright (c) 2019 Sean Corfield, all rights reserved
(ns next.jdbc.specs
(:require [clojure.spec.alpha :as s]
[clojure.spec.test.alpha :as st]
[next.jdbc :as jdbc]
[next.jdbc.sql :as sql])
(:import (java.sql Connection PreparedStatement)
(javax.sql DataSource)))
(s/def ::dbtype string?)
(s/def ::dbname string?)
(s/def ::classname string?)
(s/def ::user string?)
(s/def ::password string?)
(s/def ::host string?)
(s/def ::port pos-int?)
(s/def ::db-spec-map (s/keys :req-un [::dbtype ::dbname]
:opt-un [::classname
::user ::password
::host ::port]))
(s/def ::connection #(instance? Connection %))
(s/def ::datasource #(instance? DataSource %))
(s/def ::prepared-statement #(instance? PreparedStatement %))
(s/def ::db-spec (s/or :db-spec ::db-spec-map
:string string?
:ds ::datasource))
(s/def ::connectable any?)
(s/def ::key-map (s/map-of keyword? any?))
(s/def ::opts-map (s/map-of keyword? any?))
(s/def ::sql-params (s/and vector?
(s/cat :sql string?
:params (s/* any?))))
(s/fdef jdbc/get-datasource
:args (s/cat :spec ::db-spec))
(s/fdef jdbc/get-connection
:args (s/cat :spec ::db-spec
:opts (s/? ::opts-map)))
(s/fdef jdbc/prepare
:args (s/cat :connection ::connection
:sql-params ::sql-params
:opts (s/? ::opts-map)))
(s/fdef jdbc/reducible!
:args (s/alt :prepared (s/cat :stmt ::prepared-statement)
:sql (s/cat :connectable ::connectable
:sql-params ::sql-params
:opts (s/? ::opts-map))))
(s/fdef jdbc/execute!
:args (s/alt :prepared (s/cat :stmt ::prepared-statement)
:sql (s/cat :connectable ::connectable
:sql-params ::sql-params
:opts (s/? ::opts-map))))
(s/fdef jdbc/execute-one!
:args (s/alt :prepared (s/cat :stmt ::prepared-statement)
:sql (s/cat :connectable ::connectable
:sql-params ::sql-params
:opts (s/? ::opts-map))))
(s/fdef jdbc/transact
:args (s/cat :connectable ::connectable
:f fn?
:opts (s/? ::opts-map)))
(s/fdef jdbc/with-transaction
:args (s/cat :binding (s/and vector?
(s/cat :sym simple-symbol?
:connectable ::connectable
:opts ::opts-map))
:body (s/* any?)))
(s/fdef sql/insert!
:args (s/cat :connectable ::connectable
:table keyword?
:key-map ::key-map
:opts (s/? ::opts-map)))
(s/fdef sql/insert-multi!
:args (s/and (s/cat :connectable ::connectable
:table keyword?
:cols (s/coll-of keyword? :kind vector?)
:rows (s/coll-of (s/coll-of any? :kind vector?) :kind vector?)
:opts (s/? ::opts-map))
#(apply = (count (:cols %))
(map count (:rows %)))))
(s/fdef sql/query
:args (s/cat :connectable ::connectable
:sql-params ::sql-params
:opts (s/? ::opts-map)))
(s/fdef sql/find-by-keys
:args (s/cat :connectable ::connectable
:table keyword?
:key-map (s/or :example ::key-map
:where ::sql-params)
:opts (s/? ::opts-map)))
(s/fdef sql/get-by-id
:args (s/alt :with-id (s/cat :connectable ::connectable
:table keyword?
:pk any?
:opts (s/? ::opts-map))
:pk-name (s/cat :connectable ::connectable
:table keyword?
:pk any?
:pk-name keyword?
:opts ::opts-map)))
(s/fdef sql/update!
:args (s/cat :connectable ::connectable
:table keyword?
:key-map ::key-map
:where-params (s/or :example ::key-map
:where ::sql-params)
:opts (s/? ::opts-map)))
(s/fdef sql/delete!
:args (s/cat :connectable ::connectable
:table keyword?
:where-params (s/or :example ::key-map
:where ::sql-params)
:opts (s/? ::opts-map)))
(defn instrument []
(st/instrument [`jdbc/get-datasource
`jdbc/get-connection
`jdbc/prepare
`jdbc/reducible!
`jdbc/execute!
`jdbc/execute-one!
`jdbc/transact
`jdbc/with-transaction
`sql/insert!
`sql/insert-multi!
`sql/query
`sql/find-by-keys
`sql/get-by-id
`sql/update!
`sql/delete!]))

View file

@ -6,12 +6,15 @@
At some future date, tests for the syntactic sugar functions will be added."
(:require [clojure.test :refer [deftest is testing use-fixtures]]
[next.jdbc.quoted :refer [mysql sql-server]]
[next.jdbc.specs :as specs]
[next.jdbc.sql :as sql]
[next.jdbc.test-fixtures
:refer [with-test-db ds derby? sqlite?]]))
(use-fixtures :once with-test-db)
(specs/instrument)
(deftest test-by-keys
(testing ":where clause"
(is (= (#'sql/by-keys {:a nil :b 42 :c "s"} :where {})

View file

@ -6,11 +6,14 @@
[next.jdbc :as jdbc]
[next.jdbc.test-fixtures :refer [with-test-db ds]]
[next.jdbc.prepare :as prep]
[next.jdbc.result-set :as rs])
[next.jdbc.result-set :as rs]
[next.jdbc.specs :as specs])
(:import (java.sql ResultSet ResultSetMetaData)))
(use-fixtures :once with-test-db)
(specs/instrument)
(deftest basic-tests
(testing "reducible!"
(is (= "Apple"