From 54270391faa65bd840415f4d3e0ae13848390bfe Mon Sep 17 00:00:00 2001 From: Alexander Oloo Date: Wed, 25 Oct 2023 02:42:32 +0200 Subject: [PATCH] breaking: update konserve to enable multitenancy and unbundle jdbc drivers from jar (#25) --- .gitignore | 3 ++- README.md | 4 ++++ build.clj | 2 +- deps.edn | 12 +++++++--- src/datahike_jdbc/core.clj | 10 ++++---- test/datahike_jdbc/core_test.cljc | 40 +++++++++++++++++++++++++++++++ 6 files changed, 62 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 89b4032..5cf78b2 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,8 @@ pom.xml.asc .nrepl-port .cpcache/ temp/ -datahike.mv.db +*.mv.db +*.trace.db .idea/ datahike-jdbc.iml .clj-kondo/ diff --git a/README.md b/README.md index dfa9d3e..29f9f1e 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,8 @@ It is also possible to pass a configuration url via `:jdbcUrl` like it is mentio Arguments not mentioned will be passed downstream to the corresponding jdbc-driver so every configuration option available should be working. +BREAKING CHANGE: datahike-jdbc versions after 0.1.45 no longer include actual JDBC drivers. Before you upgrade please make sure your application provides the necessary dependencies. + ## Prerequisites For this backend to work you need to choose a database that is supported by JDBC. Please have a look at the docs for [clojure.java.jdbc](https://github.com/clojure/java.jdbc/). For the sake @@ -51,6 +53,7 @@ On your local machine your setup prerequisites could look something like this: 2. A running instance of PostgreSQL that you can connect to. 3. [A JDK to run your Clojure on](https://clojure.org/guides/getting_started) 4. [Leiningen, Boot or Clojure CLI to run your code or a REPL](https://leiningen.org/#install) +5. The JDBC drivers you wish to use added as a dependency (since `0.2.x`) We will stick with Leiningen for this manual. If you want to use MySQL or H2 for a try, please have a look into the tests to see how to configure these backend stores. @@ -83,6 +86,7 @@ keyword `:jdbc`. If you want to use other backends than JDBC please refer to the :port 5432 :user "alice" :password "foo" + :table "my_first_application" ;; defaults to konserve :dbname "config-test"}}) ;; Create a database at this place, by default configuration we have a strict diff --git a/build.clj b/build.clj index 1c4d98b..567f809 100644 --- a/build.clj +++ b/build.clj @@ -8,7 +8,7 @@ (def org "replikativ") (def lib 'io.replikativ/datahike-jdbc) (def current-commit (b/git-process {:git-args "rev-parse HEAD"})) -(def version (format "0.1.%s" (b/git-count-revs nil))) +(def version (format "0.2.%s" (b/git-count-revs nil))) (def class-dir "target/classes") (def basis (b/create-basis {:project "deps.edn"})) (def jar-file (format "target/%s-%s.jar" (name lib) version)) diff --git a/deps.edn b/deps.edn index 916e098..e0ae974 100644 --- a/deps.edn +++ b/deps.edn @@ -1,9 +1,15 @@ {:deps {org.clojure/clojure {:mvn/version "1.11.1" :scope "provided"} - io.replikativ/konserve-jdbc {:mvn/version "0.1.79"}} + io.replikativ/konserve-jdbc {:mvn/version "0.2.82"} + io.replikativ/datahike {:mvn/version "0.6.1552" :scope "provided"}} :paths ["src"] :aliases {:test {:extra-paths ["test"] - :extra-deps {lambdaisland/kaocha {:mvn/version "1.84.1335"} - io.replikativ/datahike {:mvn/version "0.6.1541"}} + :extra-deps {lambdaisland/kaocha {:mvn/version "1.84.1335"} + com.h2database/h2 {:mvn/version "2.1.214"} + com.microsoft.sqlserver/mssql-jdbc {:mvn/version "9.4.1.jre11"} + mysql/mysql-connector-java {:mvn/version "8.0.25"} + org.apache.derby/derby {:mvn/version "10.16.1.1"} + org.postgresql/postgresql {:mvn/version "42.6.0"} + org.xerial/sqlite-jdbc {:mvn/version "3.41.2.2"}} :main-opts ["-m" "kaocha.runner"]} :format {:extra-deps {cljfmt/cljfmt {:mvn/version "0.9.2"}} diff --git a/src/datahike_jdbc/core.clj b/src/datahike_jdbc/core.clj index c716db7..b6cb89a 100644 --- a/src/datahike_jdbc/core.clj +++ b/src/datahike_jdbc/core.clj @@ -5,10 +5,10 @@ [clojure.spec.alpha :as s])) (defmethod store-identity :jdbc [store-config] - (let [{:keys [jdbcUrl dbtype host port dbname]} store-config] + (let [{:keys [jdbcUrl dbtype host port dbname table]} store-config] (if jdbcUrl - [:jdbc jdbcUrl] - [:jdbc dbtype host port dbname]))) + [:jdbc jdbcUrl table] + [:jdbc dbtype host port dbname table]))) (defmethod empty-store :jdbc [store-config] (k/connect-store store-config)) @@ -36,6 +36,7 @@ (s/def :datahike.store.jdbc/classname string?) (s/def :datahike.store.jdbc/user string?) (s/def :datahike.store.jdbc/password string?) +(s/def :datahike.store.jdbc/table string?) (s/def ::jdbc (s/keys :req-un [:datahike.store.jdbc/backend] :opt-un [:datahike.store.jdbc/dbtype :datahike.store.jdbc/jdbcUrl @@ -46,7 +47,8 @@ :datahike.store.jdbc/port :datahike.store.jdbc/classname :datahike.store.jdbc/user - :datahike.store.jdbc/password])) + :datahike.store.jdbc/password + :datahike.store.jdbc/table])) (defmethod config-spec :jdbc [_] ::jdbc) diff --git a/test/datahike_jdbc/core_test.cljc b/test/datahike_jdbc/core_test.cljc index 61802e8..82d5ee5 100644 --- a/test/datahike_jdbc/core_test.cljc +++ b/test/datahike_jdbc/core_test.cljc @@ -143,3 +143,43 @@ (is (d/database-exists?)) (d/delete-database) (is (not (d/database-exists?)))))) + +(deftest ^:integration test-table + (let [config {:store {:backend :jdbc + :dbtype "mysql" + :user "alice" + :password "foo" + :dbname "config-test" + :table "wonderland"} + :schema-flexibility :write + :keep-history? false} + config2 (assoc-in config [:store :table] "tea_party") + _ (d/delete-database config) + _ (d/delete-database config2)] + (is (not (d/database-exists? config))) + (is (not (d/database-exists? config2))) + (let [_ (d/create-database config) + _ (d/create-database config2) + conn (d/connect config) + conn2 (d/connect config2)] + (d/transact conn [{:db/ident :name + :db/valueType :db.type/string + :db/cardinality :db.cardinality/one} + {:db/ident :age + :db/valueType :db.type/long + :db/cardinality :db.cardinality/one}]) + (d/transact conn [{:db/id 1, :name "Ivan", :age 15} + {:db/id 2, :name "Petr", :age 37} + {:db/id 3, :name "Ivan", :age 37} + {:db/id 4, :age 15}]) + (is (= (d/q '[:find ?e :where [?e :name]] @conn) + #{[3] [2] [1]})) + (is (empty? (d/q '[:find ?e :where [?e :name]] @conn2))) + (d/release conn) + (d/release conn2) + (is (d/database-exists? config)) + (d/delete-database config) + (is (d/database-exists? config2)) + (d/delete-database config2) + (is (not (d/database-exists? config))) + (is (not (d/database-exists? config2))))))