Sfoglia il codice sorgente

wip: impl datascript storage based on sqlite-opfs

Andelf 2 anni fa
parent
commit
ca24545b53
2 ha cambiato i file con 87 aggiunte e 23 eliminazioni
  1. 72 2
      src/main/frontend/db_worker.cljs
  2. 15 21
      src/main/frontend/persist_db/browser.cljs

+ 72 - 2
src/main/frontend/db_worker.cljs

@@ -3,10 +3,54 @@
   (:require ["@logseq/sqlite" :as sqlite-db :default wasm-bindgen-init]
             ["comlink" :as Comlink]
             [promesa.core :as p]
-            [shadow.cljs.modern :refer [defclass]]))
+            [datascript.storage :refer [IStorage]]
+            [cljs.cache :as cache]
+            [cljs.reader :as reader]
+            [datascript.core :as d]
+            [logseq.db.frontend.schema :as db-schema]
+            [shadow.cljs.modern :refer [defclass]]
+            [datascript.transit :as dt]
+            [clojure.edn :as edn]))
 
 (def *wasm-loaded (atom false))
 
+;; datascript conns
+(defonce conns (atom nil))
+
+(defn get-conn
+  [repo]
+  (get @conns repo))
+
+(defn upsert-addr-content!
+  "Upsert addr+data-seq"
+  [repo data]
+  (.upsert_addr_content sqlite-db repo data))
+
+(defn restore-data-from-addr
+  [repo addr]
+  (.get_content_by_addr sqlite-db repo addr))
+
+
+(defn new-sqlite-storage
+  [repo {:keys [threshold]
+         :or {threshold 4096}}]
+  (let [_cache (cache/lru-cache-factory {} :threshold threshold)]
+    (reify IStorage
+      (-store [_ addr+data-seq]
+        (let [data (->>
+                    (map
+                     (fn [[addr data]]
+                       #js {:addr addr
+                            :content (pr-str data)})
+                     addr+data-seq)
+                    (to-array))]
+          (upsert-addr-content! repo data)
+          {:result "ok"}))
+
+      (-restore [_ addr]
+        (let [content (restore-data-from-addr repo addr)]
+          (edn/read-string content))))))
+
 #_:clj-kondo/ignore
 (defclass SQLiteDB
   (extends js/Object)
@@ -51,7 +95,33 @@
    (p/do!
     (.ensure_init sqlite-db)
     (.init_db sqlite-db repo) ;; close another and init this one
-    (.new_db sqlite-db repo)))
+    (.new_db sqlite-db repo)
+    (let [db-name repo
+          storage (new-sqlite-storage db-name {})
+          conn (or (d/restore-conn storage)
+                   (d/create-conn db-schema/schema-for-db-based-graph {:storage storage}))]
+      (swap! conns assoc db-name conn)
+      nil)))
+
+  (transact
+   [_this repo tx-data tx-meta]
+   (when-let [conn (get-conn repo)]
+     (try
+       (let [tx-data (reader/read-string tx-data)
+             tx-meta (reader/read-string tx-meta)]
+         (d/transact! conn tx-data tx-meta))
+       (catch :default e
+         (prn :debug :error)
+         (js/console.error e)))))
+
+  (getInitialData
+   [_this repo]
+   (when-let [conn (get-conn repo)]
+     (let [db @conn]
+       (->> (d/datoms db :eavt)
+              ;; (remove (fn [e] (= :block/content (:a e))))
+            vec
+            dt/write-transit-str))))
 
   (openDB
    [_this repo]

+ 15 - 21
src/main/frontend/persist_db/browser.cljs

@@ -112,7 +112,7 @@
         (p/catch (fn [error]
                    (if (string/includes? (str error) "NoModificationAllowedError")
                      (notification/show! [:div (str "Avoid opening the same graph in multi-tabs. Error: " error)] :error)
-                     (notification/show! [:div (str "SQLiteDB backend error: " error)] :error))
+                     (notification/show! [:div (str "SQLiteDB creation error: " error)] :error))
 
                    nil))))
 
@@ -127,34 +127,28 @@
     (p/let [^js sqlite (ensure-sqlite-init)]
       (.unsafeUnlinkDB sqlite repo)))
 
-  (<transact-data [_this repo upsert-blocks deleted-uuids]
-    (p->c (p/let [^js sqlite (ensure-sqlite-init)
-                  deleted (clj->js (map str deleted-uuids))
-                  _ (when (seq deleted)
-                      (.deleteBlocks sqlite repo deleted))
-                  upsert-blocks (clj->js (map ds->sqlite-block upsert-blocks))]
-            (.upsertBlocks sqlite repo upsert-blocks))))
+  (<transact-data [_this repo tx-data tx-meta]
+    (prn ::transact-data repo (count tx-data) (count tx-meta))
+    (p->c
+     (p/let [^js sqlite (ensure-sqlite-init)
+             _ (.transact sqlite repo (pr-str tx-data) (pr-str tx-meta))]
+       nil)))
 
   (<fetch-initital-data [_this repo _opts]
+    (prn ::fetch-initital-data repo)
     (-> (p/let [^js sqlite (ensure-sqlite-init)
-            ;; <fetch-initital-data is called when init/re-loading graph
-            ;; the underlying DB should be opened
-                _ (.openDB sqlite repo)
-                all-pages (.fetchAllPages sqlite repo)
-                all-blocks (.fetchAllBlocks sqlite repo)
-                journal-blocks (.fetchRecentJournals sqlite repo)
-                init-data (.fetchInitData sqlite repo)]
-
-          #js {:all-blocks all-blocks
-               :all-pages all-pages
-               :journal-blocks journal-blocks
-               :init-data init-data})
+                ;; <fetch-initital-data is called when init/re-loading graph
+                ;; the underlying DB should be opened
+                _ (.openDB sqlite repo)]
+          (.getInitialData sqlite repo))
         (p/catch (fn [error]
+                   (prn ::fuck-error)
                    (if (string/includes? (str error) "NoModificationAllowedError")
                      (notification/show! [:div (str "Avoid opening the same graph in multi-tabs. Error: " error)] :error)
-                     (notification/show! [:div (str "SQLiteDB backend error: " error)] :error))
+                     (notification/show! [:div (str "SQLiteDB fetch error: " error)] :error))
 
                    {}))))
+
   (<fetch-blocks-excluding [_this repo exclude-uuids _opts]
     (p/let [^js sqlite (ensure-sqlite-init)]
       (.fetchBlocksExcluding sqlite repo (clj->js exclude-uuids)))))