Skip to content

Commit

Permalink
:h2 support
Browse files Browse the repository at this point in the history
  • Loading branch information
tonsky committed Aug 28, 2023
1 parent bfeecd0 commit 0e3b148
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 54 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# WIP

- Support `:postgresql`
- Support `:postgresql`, `:h2`

# 0.1.0

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ or
Currently supported `:dbtype`-s:

- `:sqlite`
- `:h2`
- `:postgresql`

If needed, you can close connection through storage:
Expand Down
3 changes: 3 additions & 0 deletions deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
:sqlite
{:extra-deps
{org.xerial/sqlite-jdbc {:mvn/version "3.42.0.0"}}}
:h2
{:extra-deps
{com.h2database/h2 {:mvn/version "2.2.220"}}}
:postgresql
{:extra-deps
{org.postgresql/postgresql {:mvn/version "42.6.0"}}}}}
Expand Down
2 changes: 1 addition & 1 deletion script/repl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
set -o errexit -o nounset -o pipefail
cd "`dirname $0`/.."

clj -A:dev:test:sqlite:postgresql -M -m user
clj -A:dev:test:sqlite:h2:postgresql -M -m user
67 changes: 49 additions & 18 deletions src/datascript/storage/sql/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,27 @@
(with-open [stmt (.createStatement conn)]
(.execute stmt sql)))

(defn store-impl [^Connection conn opts addr+data-seq]
(defmulti store-impl
(fn [conn opts addr+data-seq]
(:dbtype opts)))

(defmethod store-impl :h2 [^Connection conn opts addr+data-seq]
(let [{:keys [table binary? freeze-str freeze-bytes batch-size]} opts
sql (str "merge into " table " key (addr) values (?, ?)")]
(with-tx conn
(with-open [stmt (.prepareStatement conn sql)]
(doseq [part (partition-all batch-size addr+data-seq)]
(doseq [[addr data] part]
(.setLong stmt 1 addr)
(if binary?
(let [content ^bytes (freeze-bytes data)]
(.setBytes stmt 2 content))
(let [content ^String (freeze-str data)]
(.setString stmt 2 content)))
(.addBatch stmt))
(.executeBatch stmt))))))

(defmethod store-impl :default [^Connection conn opts addr+data-seq]
(let [{:keys [table binary? freeze-str freeze-bytes batch-size]} opts
sql (str
"insert into " table " (addr, content) "
Expand All @@ -42,7 +62,7 @@
(.setString stmt 2 content)
(.setString stmt 3 content)))
(.addBatch stmt))
(.executeBatch stmt))))))
(.executeBatch stmt))))))

(defn restore-impl [^Connection conn opts addr]
(let [{:keys [table binary? thaw-str thaw-bytes]} opts
Expand Down Expand Up @@ -72,6 +92,31 @@
(.addBatch stmt))
(.executeBatch stmt)))))

(defmulti ddl
(fn [opts]
(:dbtype opts)))

(defmethod ddl :sqlite [{:keys [table binary?]}]
(str
"create table if not exists " table
" (addr INTEGER primary key, "
" content " (if binary? "BLOB" "TEXT") ")"))

(defmethod ddl :h2 [{:keys [table binary?]}]
(str
"create table if not exists " table
" (addr BIGINT primary key, "
" content " (if binary? "BINARY VARYING" "CHARACTER VARYING") ")"))

(defmethod ddl :postgresql [{:keys [table binary?]}]
(str
"create table if not exists " table
" (addr BIGINT primary key, "
" content " (if binary? "BYTEA" "TEXT") ")"))

(defmethod ddl :default [{:keys [dbtype]}]
(throw (IllegalArgumentException. (str "Unsupported :dbtype " (pr-str dbtype)))))

(defn merge-opts [opts]
(let [opts (merge
{:freeze-str pr-str
Expand All @@ -80,22 +125,8 @@
:table "datascript"}
opts)
opts (assoc opts
:binary? (boolean (and (:freeze-bytes opts) (:thaw-bytes opts))))
type (:dbtype opts)
ddl (case type
:sqlite
(str
"create table if not exists " (:table opts)
" (addr INTEGER primary key, "
" content " (if (:binary? opts) "BLOB" "TEXT") ")")
:postgresql
(str
"create table if not exists " (:table opts)
" (addr BIGINT primary key, "
" content " (if (:binary? opts) "BYTEA" "TEXT") ")")
(throw (IllegalArgumentException. (str "Unsupported :dbtype " (pr-str type)))))
opts (merge {:ddl ddl} opts)]
opts))
:binary? (boolean (and (:freeze-bytes opts) (:thaw-bytes opts))))]
(merge {:ddl (ddl opts)} opts)))

(defn make
([conn]
Expand Down
3 changes: 3 additions & 0 deletions test/datascript/storage/sql/test_core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,6 @@
_ (d/store db storage)
db' (d/restore storage)]
(is (= db db')))))))

(comment
(t/run-all-tests))
19 changes: 19 additions & 0 deletions test/datascript/storage/sql/test_h2.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
(ns datascript.storage.sql.test-h2
(:require
[clojure.test :as t :refer [deftest is are testing]]
[datascript.core :as d]
[datascript.storage.sql.core :as storage-sql]
[datascript.storage.sql.test-core :as test-core])
(:import
[java.nio.file Files Path]
[java.sql DriverManager]))

(deftest test-h2 []
(test-core/test-storage
{:dbtype :h2
:connect-fn #(DriverManager/getConnection "jdbc:h2:./target/db.h2")
:reset-fn #(Files/deleteIfExists (Path/of "target/db.h2" (make-array String 0)))}))

(comment
(t/run-test-var #'test-h2)
(t/run-tests *ns*))
33 changes: 2 additions & 31 deletions test/datascript/storage/sql/test_postgresql.clj
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,6 @@
:connect-fn
#(DriverManager/getConnection "jdbc:postgresql:test_datascript")}))

; (t/run-test-var #'test-sqlite)

; (t/run-tests *ns*)

(comment
(def conn
(DriverManager/getConnection "jdbc:postgresql:tonsky"))

(str
"create table if not exists " (:table opts)
" (addr BIGINT primary key, "
" content " (if (:binary? opts) "BYTEA" "TEXT") ")")

(with-open [conn (DriverManager/getConnection "jdbc:postgresql:test_datascript")]
(storage-sql/make conn {:dbtype :postgresql}))

(def ^bytes bts (.getBytes "Hello" "UTF-8"))

(with-open [conn (DriverManager/getConnection "jdbc:postgresql:test_datascript")]
(with-open [stmt (.prepareStatement conn "insert into datascript (addr, content) values (?, ?)")]
(.setLong stmt 1 2)
(.setBytes stmt 2 bts)
(.execute stmt)))

(with-open [conn (DriverManager/getConnection "jdbc:postgresql:test_datascript")]
(with-open [stmt (.prepareStatement conn "select content from datascript where addr = ?")]
(.setLong stmt 1 2)
(with-open [rs (.executeQuery stmt)]
(when (.next rs)
(let [bs ^bytes (.getBytes rs 1)]
[(java.util.Arrays/toString bs) (String. bs "UTF-8")])))))
)
(t/run-test-var #'test-postgresql)
(t/run-tests *ns*))
6 changes: 3 additions & 3 deletions test/datascript/storage/sql/test_sqlite.clj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
:connect-fn #(DriverManager/getConnection "jdbc:sqlite:target/db.sqlite")
:reset-fn #(Files/deleteIfExists (Path/of "target/db.sqlite" (make-array String 0)))}))

; (t/run-test-var #'test-sqlite)

; (t/run-tests *ns*)
(comment
(t/run-test-var #'test-sqlite)
(t/run-tests *ns*))

0 comments on commit 0e3b148

Please sign in to comment.