diff --git a/deps/db/src/logseq/db/sqlite/db.cljs b/deps/db/src/logseq/db/sqlite/db.cljs index a91de44e92..2df1bf942b 100644 --- a/deps/db/src/logseq/db/sqlite/db.cljs +++ b/deps/db/src/logseq/db/sqlite/db.cljs @@ -15,13 +15,29 @@ ;; Reference same sqlite default class in cljs + nbb without needing .cljc (def sqlite (if (find-ns 'nbb.core) (aget sqlite3 "default") sqlite3)) +;; sqlite databases +(defonce databases (atom nil)) +;; datascript conns +(defonce conns (atom nil)) + +(defn close! + [] + (when @databases + (doseq [[_ database] @databases] + (.close database)) + (reset! databases nil))) + (defn sanitize-db-name [db-name] (-> db-name (string/replace sqlite-util/db-version-prefix "") (string/replace "/" "_") (string/replace "\\" "_") - (string/replace ":" "_"))) ;; windows + (string/replace ":" "_"))) + +(defn get-conn + [repo] + (get @conns (sanitize-db-name repo))) (defn get-db-full-path [graphs-dir db-name] @@ -76,9 +92,16 @@ needed sqlite tables if not created and returns a datascript connection that's connected to the sqlite db" [graphs-dir db-name] - (let [[_db-sanitized-name db-full-path] (get-db-full-path graphs-dir db-name) + (let [[db-sanitized-name db-full-path] (get-db-full-path graphs-dir db-name) db (new sqlite db-full-path nil)] (sqlite-common-db/create-kvs-table! db) + (swap! databases assoc db-sanitized-name db) (let [storage (new-sqlite-storage db) conn (sqlite-common-db/get-storage-conn storage)] + (swap! conns assoc db-sanitized-name conn) conn))) + +(defn transact! + [repo tx-data tx-meta] + (when-let [conn (get-conn repo)] + (d/transact! conn tx-data tx-meta))) diff --git a/src/electron/electron/core.cljs b/src/electron/electron/core.cljs index c7116f41c7..09913b0df0 100644 --- a/src/electron/electron/core.cljs +++ b/src/electron/electron/core.cljs @@ -308,6 +308,7 @@ (defn main [] (if-not (.requestSingleInstanceLock app) (do + (db/close!) (search/close!) (.quit app)) (let [privileges {:standard true @@ -337,6 +338,7 @@ (logger/debug "window-all-closed" "Quitting...") (try (fs-watcher/close-watcher!) + (db/close!) (search/close!) (catch :default e (logger/error "window-all-closed" e))) diff --git a/src/electron/electron/db.cljs b/src/electron/electron/db.cljs index 1de65a5fbc..09b272616d 100644 --- a/src/electron/electron/db.cljs +++ b/src/electron/electron/db.cljs @@ -3,10 +3,12 @@ (:require ["path" :as node-path] ["fs-extra" :as fs] ["electron" :refer [app]] - ;; [electron.logger :as logger] + [electron.logger :as logger] [logseq.db.sqlite.db :as sqlite-db] [electron.backup-file :as backup-file])) +(def close! sqlite-db/close!) + (defn get-graphs-dir [] (let [path (.getPath ^object app "home")] @@ -23,6 +25,14 @@ (fs/ensureDirSync graph-dir) graph-dir)) +(defn open-db! + [db-name] + (let [graphs-dir (get-graphs-dir)] + (try (sqlite-db/open-db! graphs-dir db-name) + (catch :default e + (js/console.error e) + (logger/error (str e ": " db-name)))))) + (defn save-db! [db-name data] (let [graph-dir (ensure-graph-dir! db-name) @@ -50,4 +60,4 @@ new-path)] (when (fs/existsSync path) (fs/ensureDirSync unlinked) - (fs/moveSync path new-path')))) \ No newline at end of file + (fs/moveSync path new-path')))) diff --git a/src/electron/electron/handler.cljs b/src/electron/electron/handler.cljs index 756cbb28b8..4d86a56aa9 100644 --- a/src/electron/electron/handler.cljs +++ b/src/electron/electron/handler.cljs @@ -32,8 +32,10 @@ [electron.window :as win] [electron.handler-interface :refer [handle]] [logseq.db.sqlite.util :as sqlite-util] + [logseq.db.sqlite.db :as sqlite-db] [logseq.common.graph :as common-graph] - [promesa.core :as p])) + [promesa.core :as p] + [clojure.edn :as edn])) (defmethod handle :mkdir [_window [_ dir]] (fs/mkdirSync dir)) @@ -225,14 +227,6 @@ (fs-extra/ensureDirSync dir) dir)) -(defn- get-db-based-graphs-dir - [] - (let [dir (if utils/ci? - (.resolve node-path js/__dirname "../tmp/graphs") - (.join node-path (.homedir os) "logseq" "graphs"))] - (fs-extra/ensureDirSync dir) - dir)) - ;; TODO: move file based graphs to "~/logseq/graphs" too (defn- get-file-based-graphs "Returns all graph names in the cache directory (starting with `logseq_local_`)" @@ -243,20 +237,9 @@ (map #(node-path/basename % ".transit")) (map graph-name->path)))) -(defn- get-db-based-graphs - "Returns all graph names in the cache directory" - [] - (let [dir (get-db-based-graphs-dir)] - (->> (common-graph/read-directories dir) - (remove (fn [s] (= s db/unlinked-graphs-dir))) - (map graph-name->path) - (map (fn [s] (str sqlite-util/db-version-prefix s)))))) - (defn- get-graphs [] - (concat - (get-file-based-graphs) - (get-db-based-graphs))) + (get-file-based-graphs)) ;; TODO support alias mechanism (defn get-graph-name @@ -366,6 +349,18 @@ (db/ensure-graph-dir! repo) (db/save-db! repo data)) +(defmethod handle :db-open [_window [_ repo]] + (db/ensure-graph-dir! repo) + (db/open-db! repo) + nil) + +(defmethod handle :db-transact [_window [_ repo tx-data-str tx-meta-str]] + (when-let [conn (sqlite-db/get-conn repo)] + (let [tx-data (edn/read-string tx-data-str) + tx-meta (edn/read-string tx-meta-str)] + (sqlite-db/transact! repo tx-data tx-meta) + (:max-tx @conn)))) + ;; DB related IPCs End (defn clear-cache! diff --git a/src/main/frontend/db_worker.cljs b/src/main/frontend/db_worker.cljs index 46addccdde..8f30e35660 100644 --- a/src/main/frontend/db_worker.cljs +++ b/src/main/frontend/db_worker.cljs @@ -18,6 +18,14 @@ (defonce *datascript-conns (atom nil)) (defonce *opfs-pools (atom nil)) +(defn sanitize-db-name + [db-name] + (-> db-name + (string/replace " " "_") + (string/replace "/" "_") + (string/replace "\\" "_") + (string/replace ":" "_"))) + (defn- get-sqlite-conn [repo] (get @*sqlite-conns repo)) @@ -33,7 +41,7 @@ (defn- js dbs))) (createOrOpenDB @@ -224,6 +232,11 @@ (p/let [_ (close-other-dbs! repo)] (create-or-open-db! repo))) + (getMaxTx + [_this repo] + (when-let [conn (get-datascript-conn repo)] + (:max-tx @conn))) + (transact [_this repo tx-data tx-meta] (when-let [conn (get-datascript-conn repo)] diff --git a/src/main/frontend/handler.cljs b/src/main/frontend/handler.cljs index 21c9ed1a5c..ec6bfa7906 100644 --- a/src/main/frontend/handler.cljs +++ b/src/main/frontend/handler.cljs @@ -49,8 +49,7 @@ [cljs-bean.core :as bean] [frontend.handler.test :as test] [frontend.db.rtc.op-mem-layer :as op-mem-layer] - [frontend.persist-db.browser :as db-browser] - [frontend.persist-db :as persist-db])) + [frontend.persist-db.browser :as db-browser])) (defn- set-global-error-notification! [] @@ -247,7 +246,6 @@ _ (mobile-util/hide-splash) ;; hide splash as early as ui is stable repo (or (state/get-current-repo) (:url (first repos))) _ (restore-and-setup! repo repos)] - (persist-db/run-export-periodically!) (when (mobile-util/native-platform?) (state/restore-mobile-theme!))) (p/catch (fn [e] diff --git a/src/main/frontend/persist_db.cljs b/src/main/frontend/persist_db.cljs index fcd260d516..3d703d48a2 100644 --- a/src/main/frontend/persist_db.cljs +++ b/src/main/frontend/persist_db.cljs @@ -1,11 +1,9 @@ (ns frontend.persist-db - "Backend of DB based graph" - (:require [frontend.persist-db.browser :as browser] - [frontend.persist-db.protocol :as protocol] - [promesa.core :as p] - [frontend.config :as config] - [frontend.state :as state] - [frontend.util :as util])) + "Backend of DB based graph" + (:require [frontend.persist-db.browser :as browser] + [frontend.persist-db.protocol :as protocol] + [promesa.core :as p] + [electron.ipc :as ipc])) (defonce opfs-db (browser/->InBrowser)) @@ -35,28 +33,30 @@ ([repo] (