From 44b373159e79eb43d27168154ba322930599b431 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Wed, 26 Apr 2023 15:18:18 +0800 Subject: [PATCH 1/4] fix: delete sqlite db when prepare failed resolved #7467 --- src/electron/electron/search.cljs | 98 +++++++++++++++---------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/src/electron/electron/search.cljs b/src/electron/electron/search.cljs index c473e1c053..5dac810ac2 100644 --- a/src/electron/electron/search.cljs +++ b/src/electron/electron/search.cljs @@ -28,14 +28,21 @@ [repo] (get @databases (sanitize-db-name repo))) +(declare delete-db!) + (defn prepare - [^object db sql] + [db-name ^object db sql] (when db - (.prepare db sql))) + (try + (.prepare db sql) + (catch :default e + ;; case 1: vtable constructor failed: blocks_fts https://github.com/logseq/logseq/issues/7467 + (delete-db! db-name) + (throw e))))) (defn add-blocks-fts-triggers! "Table bindings of blocks tables and the blocks FTS virtual tables" - [db] + [db db-name] (let [triggers [;; add "CREATE TRIGGER IF NOT EXISTS blocks_ad AFTER DELETE ON blocks BEGIN @@ -55,12 +62,12 @@ VALUES (new.id, new.uuid, new.content, new.page); END;"]] (doseq [trigger triggers] - (let [stmt (prepare db trigger)] + (let [stmt (prepare db-name db trigger)] (.run ^object stmt))))) (defn add-pages-fts-triggers! "Table bindings of pages tables and the pages FTS virtual tables" - [db] + [db db-name] (let [triggers [;; add "CREATE TRIGGER IF NOT EXISTS pages_ad AFTER DELETE ON pages BEGIN @@ -80,12 +87,12 @@ VALUES (new.id, new.uuid, new.content); END;"]] (doseq [trigger triggers] - (let [stmt (prepare db trigger)] + (let [stmt (prepare db-name db trigger)] (.run ^object stmt))))) (defn create-blocks-table! - [db] - (let [stmt (prepare db "CREATE TABLE IF NOT EXISTS blocks ( + [db db-name] + (let [stmt (prepare db-name db "CREATE TABLE IF NOT EXISTS blocks ( id INTEGER PRIMARY KEY, uuid TEXT NOT NULL, content TEXT NOT NULL, @@ -93,21 +100,21 @@ (.run ^object stmt))) (defn create-blocks-fts-table! - [db] - (let [stmt (prepare db "CREATE VIRTUAL TABLE IF NOT EXISTS blocks_fts USING fts5(uuid, content, page)")] + [db db-name] + (let [stmt (prepare db-name db "CREATE VIRTUAL TABLE IF NOT EXISTS blocks_fts USING fts5(uuid, content, page)")] (.run ^object stmt))) (defn create-pages-table! - [db] - (let [stmt (prepare db "CREATE TABLE IF NOT EXISTS pages ( + [db db-name] + (let [stmt (prepare db-name db "CREATE TABLE IF NOT EXISTS pages ( id INTEGER PRIMARY KEY, uuid TEXT NOT NULL, content TEXT NOT NULL)")] (.run ^object stmt))) (defn create-pages-fts-table! - [db] - (let [stmt (prepare db "CREATE VIRTUAL TABLE IF NOT EXISTS pages_fts USING fts5(uuid, content)")] + [db db-name] + (let [stmt (prepare db-name db "CREATE VIRTUAL TABLE IF NOT EXISTS pages_fts USING fts5(uuid, content)")] (.run ^object stmt))) (defn get-search-dir @@ -136,12 +143,12 @@ [db-name] (let [[db-sanitized-name db-full-path] (get-db-full-path db-name)] (try (let [db (sqlite3 db-full-path nil)] - (create-blocks-table! db) - (create-blocks-fts-table! db) - (create-pages-table! db) - (create-pages-fts-table! db) - (add-blocks-fts-triggers! db) - (add-pages-fts-triggers! db) + (create-blocks-table! db db-name) + (create-blocks-fts-table! db db-name) + (create-pages-table! db db-name) + (create-pages-fts-table! db db-name) + (add-blocks-fts-triggers! db db-name) + (add-pages-fts-triggers! db db-name) (swap! databases assoc db-sanitized-name db)) (catch :default e (logger/error (str e ": " db-name)) @@ -170,7 +177,7 @@ (if-let [db (get-db repo)] ;; TODO: what if a CONFLICT on uuid ;; Should update all values on id conflict - (let [insert (prepare db "INSERT INTO pages (id, uuid, content) VALUES (@id, @uuid, @content) ON CONFLICT (id) DO UPDATE SET (uuid, content) = (@uuid, @content)") + (let [insert (prepare repo db "INSERT INTO pages (id, uuid, content) VALUES (@id, @uuid, @content) ON CONFLICT (id) DO UPDATE SET (uuid, content) = (@uuid, @content)") insert-many (.transaction ^object db (fn [pages] (doseq [page pages] @@ -184,7 +191,7 @@ [repo ids] (when-let [db (get-db repo)] (let [sql (str "DELETE from pages WHERE id IN " (clj-list->sql ids)) - stmt (prepare db sql)] + stmt (prepare repo db sql)] (.run ^object stmt)))) (defn upsert-blocks! @@ -192,7 +199,7 @@ (if-let [db (get-db repo)] ;; TODO: what if a CONFLICT on uuid ;; Should update all values on id conflict - (let [insert (prepare db "INSERT INTO blocks (id, uuid, content, page) VALUES (@id, @uuid, @content, @page) ON CONFLICT (id) DO UPDATE SET (uuid, content, page) = (@uuid, @content, @page)") + (let [insert (prepare repo db "INSERT INTO blocks (id, uuid, content, page) VALUES (@id, @uuid, @content, @page) ON CONFLICT (id) DO UPDATE SET (uuid, content, page) = (@uuid, @content, @page)") insert-many (.transaction ^object db (fn [blocks] (doseq [block blocks] @@ -206,20 +213,13 @@ [repo ids] (when-let [db (get-db repo)] (let [sql (str "DELETE from blocks WHERE id IN " (clj-list->sql ids)) - stmt (prepare db sql)] + stmt (prepare repo db sql)] (.run ^object stmt)))) -;; (defn search-blocks-fts -;; [q] -;; (when-not (string/blank? q) -;; (let [stmt (prepare @database -;; "select id, uuid, content from blocks_fts where content match ? ORDER BY rank")] -;; (js->clj (.all ^object stmt q) :keywordize-keys true)))) - (defn- search-blocks-aux - [database sql input page limit] + [repo database sql input page limit] (try - (let [stmt (prepare database sql)] + (let [stmt (prepare repo database sql)] (js->clj (if page (.all ^object stmt (int page) input limit) @@ -264,12 +264,12 @@ matched-result (->> (map (fn [match-input] - (search-blocks-aux database match-sql match-input page limit)) + (search-blocks-aux repo database match-sql match-input page limit)) match-inputs) (apply concat))] (->> (concat matched-result - (search-blocks-aux database non-match-sql non-match-input page limit)) + (search-blocks-aux repo database non-match-sql non-match-input page limit)) (distinct-by :rowid) (take limit) (vec)))))) @@ -299,8 +299,8 @@ snippet)})) (defn- search-pages-aux - [database sql input limit] - (let [stmt (prepare database sql)] + [repo database sql input limit] + (let [stmt (prepare repo database sql)] (try (doall (map search-pages-res-unpack (-> (.raw ^object stmt) @@ -329,12 +329,12 @@ matched-result (->> (map (fn [match-input] - (search-pages-aux database match-sql match-input limit)) + (search-pages-aux repo database match-sql match-input limit)) match-inputs) (apply concat))] (->> (concat matched-result - (search-pages-aux database non-match-sql non-match-input limit)) + (search-pages-aux repo database non-match-sql non-match-input limit)) (distinct-by :id) (take limit) (vec)))))) @@ -342,23 +342,29 @@ (defn truncate-blocks-table! [repo] (when-let [database (get-db repo)] - (let [stmt (prepare database + (let [stmt (prepare repo database "delete from blocks;") _ (.run ^object stmt) - stmt (prepare database + stmt (prepare repo database "delete from blocks_fts;")] (.run ^object stmt)))) (defn truncate-pages-table! [repo] (when-let [database (get-db repo)] - (let [stmt (prepare database + (let [stmt (prepare repo database "delete from pages;") _ (.run ^object stmt) - stmt (prepare database + stmt (prepare repo database "delete from pages_fts;")] (.run ^object stmt)))) +(defn query + [repo sql] + (when-let [database (get-db repo)] + (let [stmt (prepare repo database sql)] + (.all ^object stmt)))) + (defn delete-db! [repo] (when-let [database (get-db repo)] @@ -367,9 +373,3 @@ (logger/info "Delete search indice: " db-full-path) (fs/unlinkSync db-full-path) (swap! databases dissoc db-name)))) - -(defn query - [repo sql] - (when-let [database (get-db repo)] - (let [stmt (prepare database sql)] - (.all ^object stmt)))) From 245008dc26c8f72e281254b3eebdc59c23fe45f0 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Wed, 26 Apr 2023 15:39:08 +0800 Subject: [PATCH 2/4] enhance: rebuild search index when prepare failed --- src/electron/electron/search.cljs | 5 ++++- src/main/electron/listener.cljs | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/electron/electron/search.cljs b/src/electron/electron/search.cljs index 5dac810ac2..441c0d2e0c 100644 --- a/src/electron/electron/search.cljs +++ b/src/electron/electron/search.cljs @@ -6,7 +6,8 @@ [clojure.string :as string] ["electron" :refer [app]] [electron.logger :as logger] - [medley.core :as medley])) + [medley.core :as medley] + [electron.utils :as utils])) (defonce databases (atom nil)) @@ -36,8 +37,10 @@ (try (.prepare db sql) (catch :default e + (logger/error (str "SQLite prepare failed: " e ": " db-name)) ;; case 1: vtable constructor failed: blocks_fts https://github.com/logseq/logseq/issues/7467 (delete-db! db-name) + (utils/send-to-renderer "rebuildSearchIndice" {}) (throw e))))) (defn add-blocks-fts-triggers! diff --git a/src/main/electron/listener.cljs b/src/main/electron/listener.cljs index 34d6878b2f..983514b6ec 100644 --- a/src/main/electron/listener.cljs +++ b/src/main/electron/listener.cljs @@ -17,6 +17,7 @@ [frontend.handler.route :as route-handler] [frontend.handler.ui :as ui-handler] [frontend.handler.user :as user] + [frontend.handler.search :as search-handler] [frontend.state :as state] [frontend.ui :as ui] [logseq.common.path :as path] @@ -76,6 +77,11 @@ (let [repo (bean/->clj data)] (repo-handler/remove-repo! repo)))) + (safe-api-call "rebuildSearchIndice" + (fn [_data] + (prn "Rebuild search indices") + (search-handler/rebuild-indices!))) + (safe-api-call "setGitUsernameAndEmail" (fn [] (state/pub-event! [:modal/set-git-username-and-email]))) From 1f0822b33292e7b7aab44bd4b49ba22ec9b3efdf Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Wed, 26 Apr 2023 16:09:55 +0800 Subject: [PATCH 3/4] enhance: move db-name to the last parameter --- src/electron/electron/search.cljs | 46 +++++++++++++++---------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/src/electron/electron/search.cljs b/src/electron/electron/search.cljs index 441c0d2e0c..3f79fcfebd 100644 --- a/src/electron/electron/search.cljs +++ b/src/electron/electron/search.cljs @@ -32,7 +32,7 @@ (declare delete-db!) (defn prepare - [db-name ^object db sql] + [^object db sql db-name] (when db (try (.prepare db sql) @@ -65,7 +65,7 @@ VALUES (new.id, new.uuid, new.content, new.page); END;"]] (doseq [trigger triggers] - (let [stmt (prepare db-name db trigger)] + (let [stmt (prepare db trigger db-name)] (.run ^object stmt))))) (defn add-pages-fts-triggers! @@ -90,34 +90,36 @@ VALUES (new.id, new.uuid, new.content); END;"]] (doseq [trigger triggers] - (let [stmt (prepare db-name db trigger)] + (let [stmt (prepare db trigger db-name)] (.run ^object stmt))))) (defn create-blocks-table! [db db-name] - (let [stmt (prepare db-name db "CREATE TABLE IF NOT EXISTS blocks ( + (let [stmt (prepare db "CREATE TABLE IF NOT EXISTS blocks ( id INTEGER PRIMARY KEY, uuid TEXT NOT NULL, content TEXT NOT NULL, - page INTEGER)")] + page INTEGER)" + db-name)] (.run ^object stmt))) (defn create-blocks-fts-table! [db db-name] - (let [stmt (prepare db-name db "CREATE VIRTUAL TABLE IF NOT EXISTS blocks_fts USING fts5(uuid, content, page)")] + (let [stmt (prepare db "CREATE VIRTUAL TABLE IF NOT EXISTS blocks_fts USING fts5(uuid, content, page)" db-name)] (.run ^object stmt))) (defn create-pages-table! [db db-name] - (let [stmt (prepare db-name db "CREATE TABLE IF NOT EXISTS pages ( + (let [stmt (prepare db "CREATE TABLE IF NOT EXISTS pages ( id INTEGER PRIMARY KEY, uuid TEXT NOT NULL, - content TEXT NOT NULL)")] + content TEXT NOT NULL)" + db-name)] (.run ^object stmt))) (defn create-pages-fts-table! [db db-name] - (let [stmt (prepare db-name db "CREATE VIRTUAL TABLE IF NOT EXISTS pages_fts USING fts5(uuid, content)")] + (let [stmt (prepare db "CREATE VIRTUAL TABLE IF NOT EXISTS pages_fts USING fts5(uuid, content)" db-name)] (.run ^object stmt))) (defn get-search-dir @@ -180,7 +182,7 @@ (if-let [db (get-db repo)] ;; TODO: what if a CONFLICT on uuid ;; Should update all values on id conflict - (let [insert (prepare repo db "INSERT INTO pages (id, uuid, content) VALUES (@id, @uuid, @content) ON CONFLICT (id) DO UPDATE SET (uuid, content) = (@uuid, @content)") + (let [insert (prepare db "INSERT INTO pages (id, uuid, content) VALUES (@id, @uuid, @content) ON CONFLICT (id) DO UPDATE SET (uuid, content) = (@uuid, @content)" repo) insert-many (.transaction ^object db (fn [pages] (doseq [page pages] @@ -194,7 +196,7 @@ [repo ids] (when-let [db (get-db repo)] (let [sql (str "DELETE from pages WHERE id IN " (clj-list->sql ids)) - stmt (prepare repo db sql)] + stmt (prepare db sql repo)] (.run ^object stmt)))) (defn upsert-blocks! @@ -202,7 +204,7 @@ (if-let [db (get-db repo)] ;; TODO: what if a CONFLICT on uuid ;; Should update all values on id conflict - (let [insert (prepare repo db "INSERT INTO blocks (id, uuid, content, page) VALUES (@id, @uuid, @content, @page) ON CONFLICT (id) DO UPDATE SET (uuid, content, page) = (@uuid, @content, @page)") + (let [insert (prepare db "INSERT INTO blocks (id, uuid, content, page) VALUES (@id, @uuid, @content, @page) ON CONFLICT (id) DO UPDATE SET (uuid, content, page) = (@uuid, @content, @page)" repo) insert-many (.transaction ^object db (fn [blocks] (doseq [block blocks] @@ -216,13 +218,13 @@ [repo ids] (when-let [db (get-db repo)] (let [sql (str "DELETE from blocks WHERE id IN " (clj-list->sql ids)) - stmt (prepare repo db sql)] + stmt (prepare db sql repo)] (.run ^object stmt)))) (defn- search-blocks-aux [repo database sql input page limit] (try - (let [stmt (prepare repo database sql)] + (let [stmt (prepare database sql repo)] (js->clj (if page (.all ^object stmt (int page) input limit) @@ -303,7 +305,7 @@ (defn- search-pages-aux [repo database sql input limit] - (let [stmt (prepare repo database sql)] + (let [stmt (prepare database sql repo)] (try (doall (map search-pages-res-unpack (-> (.raw ^object stmt) @@ -345,27 +347,23 @@ (defn truncate-blocks-table! [repo] (when-let [database (get-db repo)] - (let [stmt (prepare repo database - "delete from blocks;") + (let [stmt (prepare database "delete from blocks;" repo) _ (.run ^object stmt) - stmt (prepare repo database - "delete from blocks_fts;")] + stmt (prepare database "delete from blocks_fts;" repo)] (.run ^object stmt)))) (defn truncate-pages-table! [repo] (when-let [database (get-db repo)] - (let [stmt (prepare repo database - "delete from pages;") + (let [stmt (prepare database "delete from pages;" repo) _ (.run ^object stmt) - stmt (prepare repo database - "delete from pages_fts;")] + stmt (prepare database "delete from pages_fts;" repo)] (.run ^object stmt)))) (defn query [repo sql] (when-let [database (get-db repo)] - (let [stmt (prepare repo database sql)] + (let [stmt (prepare database sql repo)] (.all ^object stmt)))) (defn delete-db! From 08bb7372a6b120d1e5d17929dd209a714130547d Mon Sep 17 00:00:00 2001 From: charlie Date: Mon, 24 Apr 2023 16:08:14 +0800 Subject: [PATCH 4/4] enhance(ux): keep the item position from the installed plugins list when toggling enable/disable button --- src/main/frontend/components/plugins.cljs | 26 +++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/main/frontend/components/plugins.cljs b/src/main/frontend/components/plugins.cljs index ae07c2ebd3..2d7d462d3d 100644 --- a/src/main/frontend/components/plugins.cljs +++ b/src/main/frontend/components/plugins.cljs @@ -23,6 +23,12 @@ (declare open-waiting-updates-modal!) (defonce PER-PAGE-SIZE 15) +(def *dirties-toggle-items (atom {})) + +(defn- clear-dirties-states! + [] + (reset! *dirties-toggle-items {})) + (rum/defcs installed-themes < (rum/local [] ::themes) @@ -272,7 +278,9 @@ (ui/toggle (not disabled?) (fn [] - (js-invoke js/LSPluginCore (if disabled? "enable" "disable") id)) + (js-invoke js/LSPluginCore (if disabled? "enable" "disable") id) + (when (nil? (get @*dirties-toggle-items (keyword id))) + (swap! *dirties-toggle-items assoc (keyword id) (not disabled?)))) true)]]) (defn get-open-plugin-readme-handler @@ -796,11 +804,15 @@ filtered-plugins) sorted-plugins (if default-filter-by? (->> filtered-plugins - (reduce #(let [k (if (get-in %2 [:settings :disabled]) 1 0)] + (reduce #(let [disabled? (get-in %2 [:settings :disabled]) + old-dirty (get @*dirties-toggle-items (keyword (:id %2))) + k (if (if (boolean? old-dirty) (not old-dirty) disabled?) 1 0)] (update %1 k conj %2)) [[] []]) (#(update % 0 (fn [coll] (sort-by :iir coll)))) (flatten)) - filtered-plugins) + (do + (clear-dirties-states!) + filtered-plugins)) fn-query-flag (fn [] (string/join "_" (map #(str @%) [*filter-by *sort-by *search-key *category]))) str-query-flag (fn-query-flag) @@ -1120,9 +1132,15 @@ *el-ref (rum/create-ref)] (rum/use-effect! - #(state/load-app-user-cfgs) + (fn [] + (state/load-app-user-cfgs) + #(clear-dirties-states!)) []) + (rum/use-effect! + #(clear-dirties-states!) + [market?]) + [:div.cp__plugins-page {:ref *el-ref :tab-index "-1"}