Skip to content

Commit

Permalink
update store-identity to correctly determine equivalence of configs (#26
Browse files Browse the repository at this point in the history
)

* update store-identity to correctly determine equivalence of configs

* bugfix: retain config
  • Loading branch information
alekcz authored Nov 9, 2023
1 parent 5427039 commit 886d141
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 14 deletions.
2 changes: 1 addition & 1 deletion build.clj
Original file line number Diff line number Diff line change
Expand Up @@ -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.2.%s" (b/git-count-revs nil)))
(def version (format "0.3.%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))
Expand Down
2 changes: 1 addition & 1 deletion deps.edn
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{:deps {org.clojure/clojure {:mvn/version "1.11.1" :scope "provided"}
io.replikativ/konserve-jdbc {:mvn/version "0.2.82"}
io.replikativ/datahike {:mvn/version "0.6.1552" :scope "provided"}}
io.replikativ/datahike {:mvn/version "0.6.1554" :scope "provided"}}
:paths ["src"]
:aliases {:test {:extra-paths ["test"]
:extra-deps {lambdaisland/kaocha {:mvn/version "1.84.1335"}
Expand Down
37 changes: 25 additions & 12 deletions src/datahike_jdbc/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,41 @@
(:require [datahike.store :refer [empty-store delete-store connect-store default-config config-spec release-store store-identity]]
[datahike.config :refer [map-from-env]]
[konserve-jdbc.core :as k]
[clojure.spec.alpha :as s]))
[next.jdbc.connection :as connection]
[clojure.spec.alpha :as s]
[clojure.string :as str]))

(defn prepare-config [cfg]
;; next.jdbc does not officially support the credentials in the format: driver://user:password@host/db
;; connection/uri->db-spec makes is possible but is rough around the edges
;; https://github.com/seancorfield/next-jdbc/issues/229
(if (contains? cfg :jdbcUrl)
(merge
(dissoc cfg :jdbcUrl)
(-> cfg :jdbcUrl connection/uri->db-spec
(update :dbtype #(str/replace % #"postgres$" "postgresql"))
(update :port #(if (pos? %) % (-> connection/dbtypes (get (:dbtype %)) :port)))))
cfg))

(defmethod store-identity :jdbc [store-config]
(let [{:keys [jdbcUrl dbtype host port dbname table]} store-config]
(if jdbcUrl
[:jdbc jdbcUrl table]
[:jdbc dbtype host port dbname table])))
;; the store signature is made up of the dbtype, dbname, and table
(let [{:keys [dbtype _host _port dbname table]} (prepare-config store-config)]
[:jdbc dbtype dbname table]))

(defmethod empty-store :jdbc [store-config]
(k/connect-store store-config))
(k/connect-store (prepare-config store-config)))

(defmethod delete-store :jdbc [store-config]
(k/delete-store store-config))
(k/delete-store (prepare-config store-config)))

(defmethod connect-store :jdbc [store-config]
(k/connect-store store-config))
(k/connect-store (prepare-config store-config)))

(defmethod default-config :jdbc [config]
(merge
(map-from-env :datahike-store-config {:dbtype "h2:mem"
:dbname "datahike"})
config))
;; with the introduction of the store-identity config data should derived from inputs and not set to default values
(let [env-config (prepare-config (map-from-env :datahike-store-config {}))
passed-config (prepare-config config)]
(merge env-config passed-config)))

(s/def :datahike.store.jdbc/backend #{:jdbc})
(s/def :datahike.store.jdbc/dbtype #{"h2" "h2:mem" "hsqldb" "jtds:sqlserver" "mysql" "oracle:oci" "oracle:thin" "postgresql" "redshift" "sqlite" "sqlserver"})
Expand Down
52 changes: 52 additions & 0 deletions test/datahike_jdbc/core_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,55 @@
(d/delete-database config2)
(is (not (d/database-exists? config)))
(is (not (d/database-exists? config2))))))

(deftest ^:integration test-signature
(let [config {:store {:backend :jdbc
:dbtype "postgresql"
:host "localhost"
:dbname "config-test"
:user "alice"
:password "foo"
:table "samezies"}
:schema-flexibility :read
:keep-history? false}
config2 {:store {:backend :jdbc
:jdbcUrl "postgresql://alice:foo@localhost/config-test"
:table "samezies"}
:schema-flexibility :read
:keep-history? false}
config3 {:store {:backend :jdbc
:jdbcUrl "postgresql://alice:[email protected]/config-test"
:table "samezies"}
:schema-flexibility :read
:keep-history? false}
config4 {:store {:backend :jdbc
:jdbcUrl "postgresql://alice:[email protected]/config-test"
:table "different"}
:schema-flexibility :read
:keep-history? false}
_ (d/delete-database config)]
(is (not (d/database-exists? config)))
(let [_ (d/create-database config)
conn (d/connect config)
conn2 (d/connect config2)
conn3 (d/connect config2)]
(is (not (d/database-exists? config4)))

(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]] @conn2)
#{[3] [2] [1]}))

(is (= (d/q '[:find ?e :where [?e :name]] @conn3)
#{[3] [2] [1]}))

(d/release conn)
(is (d/database-exists? config))
(is (d/database-exists? config2))
(is (d/database-exists? config3))
(d/delete-database config)
(is (not (d/database-exists? config)))
(is (not (d/database-exists? config2)))
(is (not (d/database-exists? config3))))))

0 comments on commit 886d141

Please sign in to comment.