Skip to content

Commit

Permalink
allow table to be passed to store using db-spec (#19)
Browse files Browse the repository at this point in the history
* allow table to be passed to store using db-spec
* update readme, add function signature to match new standard for store connections, add test for new signature
  • Loading branch information
alekcz authored Oct 20, 2023
1 parent db3f692 commit 007ff48
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 14 deletions.
65 changes: 55 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,45 @@ Add to your dependencies:
(map byte (slurp input-stream)))
{:sync? false}))
```
## Multitenancy
To enable the use of the same JDBC database for multiple stores all jdbc specs accept a table name.
The table can specified separately or passed in the `db-spec`.

``` clojure
(def pg-cfg {:dbtype "postgresql"
:jdbcUrl "postgresql://user:password@localhost/konserve"})

(def store-a (connect-jdbc-store pg-cfg :table "this_application" :opts {:sync? true}))
(def store-b (connect-jdbc-store pg-cfg :table "that_application" :opts {:sync? true}))

(def pg-cfg-a {:dbtype "postgresql"
:jdbcUrl "postgresql://user:password@localhost/konserve"
:table "this_application"})


(def pg-cfg-b {:dbtype "postgresql"
:jdbcUrl "postgresql://user:password@localhost/konserve"
:table "that_application"})


(def also-store-a (connect-jdbc-store pg-cfg-a :opts {:sync? true}))
(def also-store-b (connect-jdbc-store pg-cfg-b :opts {:sync? true}))
```
In terms of priority a table specified using the keyword argument takes priority, followed
by the one specified in the `db-spec`. If no table is specified `konserve` is used as the table name.

``` clojure
(def cfg-a {:dbtype "postgresql"
:jdbcUrl "postgresql://user:password@localhost/konserve"})

(def cfg-b {:dbtype "postgresql"
:jdbcUrl "postgresql://user:password@localhost/konserve"
:table "water"})

(def store-a (connect-jdbc-store cfg-a :opts {:sync? true})) ;; table name => konserve
(def store-b (connect-jdbc-store cfg-b :opts {:sync? true})) ;; table name => water
(def store-c (connect-jdbc-store cfg-b :table "fire" :opts {:sync? true})) ;;table name => fire
``````

## Supported Databases

Expand All @@ -90,21 +129,27 @@ Fully supported so far are the following databases:
1) PostgreSQL

``` clojure
(def pg {:dbtype "postgresql"
:dbname "konserve"
:host "localhost"
:user "konserve"
:password "password"})
(def pg-cfg {:dbtype "postgresql"
:dbname "konserve"
:host "localhost"
:user "user"
:password "password"})

(def pg-url {:dbtype "postgresql"
:jdbcUrl "postgresql://user:password@localhost/konserve"})
```

2) MySQL

``` clojure
(def mysql {:dbtype "mysql"
:dbname "konserve"
:host "localhost"
:user "konserve"
:password "password"})
(def mysql-cfg {:dbtype "mysql"
:dbname "konserve"
:host "localhost"
:user "user"
:password "password"})

(def mysql-url {:dbtype "mysql"
:jdbcUrl "mysql://user:password@localhost/konserve"})
```

3) SQlite
Expand Down
9 changes: 6 additions & 3 deletions src/konserve_jdbc/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,9 @@
new-spec)))

(defn connect-store [db-spec & {:keys [table opts]
:or {table default-table}
:as params}]
(let [db-spec (prepare-spec db-spec)]
(let [table (or table (:table db-spec) default-table)
db-spec (prepare-spec db-spec)]
(when-not (:dbtype db-spec)
(throw (ex-info ":dbtype must be explicitly declared" {:options dbtypes})))

Expand Down Expand Up @@ -309,6 +309,8 @@
(dissoc params :opts :config))]
(connect-default-store backing config))))

(def connect-jdbc-store connect-store) ;; this is the new standard approach for store. Old signature remains for backwards compatability.

(defn release
"Must be called after work on database has finished in order to close connection"
[store env]
Expand All @@ -317,8 +319,9 @@
(.close ^PooledDataSource (:connection ^JDBCTable (:backing store)))
(remove-from-pool (:db-spec ^JDBCTable (:backing store))))))

(defn delete-store [db-spec & {:keys [table opts] :or {table default-table}}]
(defn delete-store [db-spec & {:keys [table opts]}]
(let [complete-opts (merge {:sync? true} opts)
table (or table (:table db-spec) default-table)
connection (jdbc/get-connection (prepare-spec db-spec))
backing (JDBCTable. db-spec connection table)]
(-delete-store backing complete-opts)))
Expand Down
26 changes: 25 additions & 1 deletion test/konserve_jdbc/core_mysql_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
(:require [clojure.test :refer [deftest is testing use-fixtures]]
[clojure.core.async :refer [<!!]]
[konserve.compliance-test :refer [compliance-test]]
[konserve-jdbc.core :refer [connect-store release delete-store]]))
[konserve-jdbc.core :refer [connect-store release delete-store connect-jdbc-store]]
[konserve.core :as k]))

(def db-spec
{:dbtype "mysql"
Expand Down Expand Up @@ -37,3 +38,26 @@
(compliance-test store))
(release store {:sync? true})
(delete-store jdbc-url :opts {:sync? true})))

(deftest table-test
(let [jdbc-url2 (assoc jdbc-url :table "convenient_table")
_ (delete-store jdbc-url :table "convenient_table" :opts {:sync? true})
store (connect-store jdbc-url :table "convenient_table" :opts {:sync? true})
store2 (connect-store jdbc-url2 :opts {:sync? true})
store3 (connect-store jdbc-url2 :table "priority_table" :opts {:sync? true})
_ (k/assoc-in store [:bar] 42 {:sync? true})]
(testing "Testing multiple stores in single db with synchronous store"
(is (= (k/get-in store [:bar] nil {:sync? true})
(k/get-in store2 [:bar] nil {:sync? true})))
(is (not= (k/get-in store2 [:bar] nil {:sync? true})
(k/get-in store3 [:bar] nil {:sync? true}))))
(release store {:sync? true})
(delete-store jdbc-url :opts {:sync? true})))

(deftest connect-jdbc-store-test
(let [_ (delete-store jdbc-url :table "compliance_test" :opts {:sync? true})
store (connect-jdbc-store jdbc-url :table "compliance_test" :opts {:sync? true})]
(testing "Compliance test with synchronous store"
(compliance-test store))
(release store {:sync? true})
(delete-store jdbc-url :opts {:sync? true})))

0 comments on commit 007ff48

Please sign in to comment.