diff --git a/src/electron/electron/search.cljs b/src/electron/electron/search.cljs index c473e1c053..3f79fcfebd 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)) @@ -28,14 +29,23 @@ [repo] (get @databases (sanitize-db-name repo))) +(declare delete-db!) + (defn prepare - [^object db sql] + [^object db sql db-name] (when db - (.prepare db sql))) + (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! "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 +65,12 @@ VALUES (new.id, new.uuid, new.content, new.page); END;"]] (doseq [trigger triggers] - (let [stmt (prepare db trigger)] + (let [stmt (prepare db trigger db-name)] (.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,34 +90,36 @@ VALUES (new.id, new.uuid, new.content); END;"]] (doseq [trigger triggers] - (let [stmt (prepare db trigger)] + (let [stmt (prepare db trigger db-name)] (.run ^object stmt))))) (defn create-blocks-table! - [db] + [db db-name] (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] - (let [stmt (prepare db "CREATE VIRTUAL TABLE IF NOT EXISTS blocks_fts USING fts5(uuid, content, page)")] + [db db-name] + (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 db-name] (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] - (let [stmt (prepare db "CREATE VIRTUAL TABLE IF NOT EXISTS pages_fts USING fts5(uuid, content)")] + [db db-name] + (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 @@ -136,12 +148,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 +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 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] @@ -184,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 db sql)] + stmt (prepare db sql repo)] (.run ^object stmt)))) (defn upsert-blocks! @@ -192,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 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] @@ -206,20 +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 db sql)] + stmt (prepare db sql repo)] (.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 database sql repo)] (js->clj (if page (.all ^object stmt (int page) input limit) @@ -264,12 +269,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 +304,8 @@ snippet)})) (defn- search-pages-aux - [database sql input limit] - (let [stmt (prepare database sql)] + [repo database sql input limit] + (let [stmt (prepare database sql repo)] (try (doall (map search-pages-res-unpack (-> (.raw ^object stmt) @@ -329,12 +334,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 +347,25 @@ (defn truncate-blocks-table! [repo] (when-let [database (get-db repo)] - (let [stmt (prepare database - "delete from blocks;") + (let [stmt (prepare database "delete from blocks;" repo) _ (.run ^object stmt) - stmt (prepare 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 database - "delete from pages;") + (let [stmt (prepare database "delete from pages;" repo) _ (.run ^object stmt) - stmt (prepare 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 database sql repo)] + (.all ^object stmt)))) + (defn delete-db! [repo] (when-let [database (get-db repo)] @@ -367,9 +374,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)))) 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]))) 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"}