From ca24545b5383bc8ae408d5770bb8dac1484e72fe Mon Sep 17 00:00:00 2001 From: Andelf Date: Thu, 30 Nov 2023 02:04:55 +0800 Subject: [PATCH] wip: impl datascript storage based on sqlite-opfs --- src/main/frontend/db_worker.cljs | 74 ++++++++++++++++++++++- src/main/frontend/persist_db/browser.cljs | 36 +++++------ 2 files changed, 87 insertions(+), 23 deletions(-) diff --git a/src/main/frontend/db_worker.cljs b/src/main/frontend/db_worker.cljs index 403cbf8b29..15353dfc5b 100644 --- a/src/main/frontend/db_worker.cljs +++ b/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] diff --git a/src/main/frontend/persist_db/browser.cljs b/src/main/frontend/persist_db/browser.cljs index 00001d70ba..1b278c629a 100644 --- a/src/main/frontend/persist_db/browser.cljs +++ b/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))) - (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)))) + (c + (p/let [^js sqlite (ensure-sqlite-init) + _ (.transact sqlite repo (pr-str tx-data) (pr-str tx-meta))] + nil))) ( (p/let [^js sqlite (ensure-sqlite-init) - ;; js exclude-uuids)))))