https://github.com/replikativ/konserve-jdbc
A JDBC backend for konserve.
https://github.com/replikativ/konserve-jdbc
clojure jdbc konserve
Last synced: 5 months ago
JSON representation
A JDBC backend for konserve.
- Host: GitHub
- URL: https://github.com/replikativ/konserve-jdbc
- Owner: replikativ
- License: epl-2.0
- Created: 2021-10-05T07:50:05.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2025-06-19T16:55:19.000Z (about 1 year ago)
- Last Synced: 2025-07-30T01:55:47.915Z (11 months ago)
- Topics: clojure, jdbc, konserve
- Language: Clojure
- Homepage:
- Size: 112 KB
- Stars: 2
- Watchers: 2
- Forks: 5
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yaml
- License: LICENSE
Awesome Lists containing this project
README
# konserve-jdbc
A [JDBC](https://github.com/clojure/java.jdbc) backend for [konserve](https://github.com/replikativ/konserve).
## Usage
Add to your dependencies:
[](http://clojars.org/org.replikativ/konserve-jdbc)
### Configuration
Supports all [JDBC-compatible databases](https://clojure.org/guides/deps_and_cli).
``` clojure
(require '[konserve-jdbc.core] ;; Registers the :jdbc backend
'[konserve.core :as k])
;; SQLite
(def sqlite-config
{:backend :jdbc
:dbtype "sqlite"
:dbname "./tmp/konserve.db"
:table "store"
:id #uuid "550e8400-e29b-41d4-a716-446655440000"})
;; PostgreSQL
(def postgres-config
{:backend :jdbc
:dbtype "postgresql"
:dbname "mydb"
:host "localhost"
:user "postgres"
:password "password"
:table "konserve"
:id #uuid "550e8400-e29b-41d4-a716-446655440001"})
;; MySQL
(def mysql-config
{:backend :jdbc
:dbtype "mysql"
:dbname "mydb"
:host "localhost"
:user "root"
:password "password"
:table "konserve"
:id #uuid "550e8400-e29b-41d4-a716-446655440002"})
(def store (k/create-store sqlite-config {:sync? true}))
```
For API usage (assoc-in, get-in, delete-store, etc.), see the [konserve documentation](https://github.com/replikativ/konserve).
## Multitenancy
Multiple independent stores can be housed in the same database. Each store has:
- `:id` - The virtual/global identifier for the store (required, UUID)
- `:table` - The physical database table where data is stored (optional, defaults to "konserve")
``` clojure
(def db {:dbtype "postgresql"
:dbname "konserve"
:host "localhost"
:user "user"
:password "password"})
;; Store A - uses table "app_a"
(def store-a-config
(assoc db
:backend :jdbc
:table "app_a"
:id #uuid "11111111-1111-1111-1111-111111111111"))
;; Store B - uses table "app_b"
(def store-b-config
(assoc db
:backend :jdbc
:table "app_b"
:id #uuid "22222222-2222-2222-2222-222222222222"))
;; Store C - uses default "konserve" table with different ID
(def store-c-config
(assoc db
:backend :jdbc
:id #uuid "33333333-3333-3333-3333-333333333333"))
```
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"
:id #uuid "11111111-1111-1111-1111-111111111111"})
(def cfg-b {:dbtype "postgresql"
:jdbcUrl "postgresql://user:password@localhost/konserve"
:table "water"
:id #uuid "22222222-2222-2222-2222-222222222222"})
(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
``````
## Multi-key Operations
This backend supports atomic multi-key operations (`multi-assoc`, `multi-get`, `multi-dissoc`), allowing you to read, write, or delete multiple keys in a single operation. All operations use JDBC transactions for atomicity.
``` clojure
;; Write multiple keys atomically
(k/multi-assoc store {:user1 {:name "Alice"}
:user2 {:name "Bob"}}
{:sync? true})
;; Read multiple keys in one request
(k/multi-get store [:user1 :user2 :user3] {:sync? true})
;; => {:user1 {:name "Alice"}, :user2 {:name "Bob"}}
;; Note: Returns sparse map - only found keys are included
;; Delete multiple keys atomically
(k/multi-dissoc store [:user1 :user2] {:sync? true})
;; => {:user1 true, :user2 true}
;; Returns map indicating which keys existed before deletion
;; Async versions
(