Skip to content

Commit

Permalink
Extracted datascript.conn
Browse files Browse the repository at this point in the history
  • Loading branch information
tonsky committed Oct 22, 2023
1 parent dceae72 commit 296881c
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 153 deletions.
2 changes: 1 addition & 1 deletion project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
*print-namespace-maps* false
;; *unchecked-math* :warn-on-boxed
}
:jvm-opts ["-Xmx2g" "-server"]
:jvm-opts ["-Xmx2g" "-server" "-Dclojure.main.report=stderr"]

:cljsbuild {
:builds [
Expand Down
147 changes: 147 additions & 0 deletions src/datascript/conn.cljc
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
(ns datascript.conn
(:require
[datascript.db :as db #?@(:cljs [:refer [FilteredDB]])]
[datascript.storage :as storage]
[me.tonsky.persistent-sorted-set :as set])
#?(:clj
(:import
[datascript.db FilteredDB])))

(defn with
([db tx-data] (with db tx-data nil))
([db tx-data tx-meta]
{:pre [(db/db? db)]}
(if (instance? FilteredDB db)
(throw (ex-info "Filtered DB cannot be modified" {:error :transaction/filtered}))
(db/transact-tx-data (db/->TxReport db db [] {} tx-meta) tx-data))))

(defn conn? [conn]
(and #?(:clj (instance? clojure.lang.IDeref conn)
:cljs (satisfies? cljs.core/IDeref conn))
(db/db? @conn)))

(defn conn-from-db [db]
{:pre [(db/db? db)]}
(if-some [storage (storage/storage db)]
(do
(storage/store db)
(atom db
:meta {:listeners (atom {})
:tx-tail (atom [])
:db-last-stored (atom db)}))
(atom db
:meta {:listeners (atom {})})))

(defn conn-from-datoms
([datoms]
(conn-from-db (db/init-db datoms nil {})))
([datoms schema]
(conn-from-db (db/init-db datoms schema {})))
([datoms schema opts]
(conn-from-db (db/init-db datoms schema (storage/maybe-adapt-storage opts)))))

(defn create-conn
([]
(conn-from-db (db/empty-db nil {})))
([schema]
(conn-from-db (db/empty-db schema {})))
([schema opts]
(conn-from-db (db/empty-db schema (storage/maybe-adapt-storage opts)))))

#?(:clj
(defn restore-conn
([storage]
(restore-conn storage {}))
([storage opts]
(when-some [[db tail] (storage/restore-impl storage opts)]
(atom (storage/db-with-tail db tail)
:meta {:listeners (atom {})
:tx-tail (atom tail)
:db-last-stored (atom db)})))))

(defn ^:no-doc -transact! [conn tx-data tx-meta]
{:pre [(conn? conn)]}
(let [*report (atom nil)]
(swap! conn
(fn [db]
(let [r (with db tx-data tx-meta)]
(reset! *report r)
(:db-after r))))
#?(:clj
(when-some [storage (storage/storage @conn)]
(let [{db :db-after
datoms :tx-data} @*report
settings (set/settings (:eavt db))
*tx-tail (:tx-tail (meta conn))
tx-tail' (swap! *tx-tail conj datoms)]
(if (> (transduce (map count) + 0 tx-tail') (:branching-factor settings))
;; overflow tail
(do
(storage/store-impl! db (storage/storage-adapter db) false)
(reset! *tx-tail [])
(reset! (:db-last-stored (meta conn)) db))
;; just update tail
(storage/store-tail db tx-tail')))))
@*report))

(defn transact!
([conn tx-data] (transact! conn tx-data nil))
([conn tx-data tx-meta]
{:pre [(conn? conn)]}
(let [report (-transact! conn tx-data tx-meta)]
(doseq [[_ callback] (some-> (:listeners (meta conn)) (deref))]
(callback report))
report)))

(defn reset-conn!
([conn db]
(reset-conn! conn db nil))
([conn db tx-meta]
{:pre [(conn? conn)
(db/db? db)]}
(let [db-before @conn
report (db/map->TxReport
{:db-before db-before
:db-after db
:tx-data (concat
(map #(assoc % :added false) (db/-datoms db-before :eavt nil nil nil nil))
(db/-datoms db :eavt nil nil nil nil))
:tx-meta tx-meta})]
#?(:clj
(when-some [storage (storage/storage db-before)]
(storage/store db)
(reset! (:tx-tail (meta conn)) [])
(reset! (:db-last-stored (meta conn)) db)))
(reset! conn db)
(doseq [[_ callback] (some-> (:listeners (meta conn)) (deref))]
(callback report))
db)))

(defn reset-schema! [conn schema]
{:pre [(conn? conn)]}
(let [db (swap! conn db/with-schema schema)]
#?(:clj
(when-some [storage (storage/storage @conn)]
(storage/store-impl! db (storage/storage-adapter db) true)
(reset! (:tx-tail (meta conn)) [])
(reset! (:db-last-stored (meta conn)) db)))
db))

(defn- atom? [a]
#?(:cljs (instance? Atom a)
:clj (instance? clojure.lang.IAtom a)))

(defn listen!
([conn callback]
(listen! conn (rand) callback))
([conn key callback]
{:pre [(conn? conn)
(atom? (:listeners (meta conn)))]}
(swap! (:listeners (meta conn)) assoc key callback)
key))

(defn unlisten!
[conn key]
{:pre [(conn? conn)
(atom? (:listeners (meta conn)))]}
(swap! (:listeners (meta conn)) dissoc key))
Loading

0 comments on commit 296881c

Please sign in to comment.