Browse Source

fix: migrate kvs table

Tienson Qin 1 year ago
parent
commit
0ddde1f024

+ 1 - 1
deps/db/src/logseq/db/frontend/schema.cljs

@@ -2,7 +2,7 @@
   "Main datascript schemas for the Logseq app"
   (:require [clojure.set :as set]))
 
-(def version 13)
+(def version 12)
 ;; A page is a special block, a page can corresponds to multiple files with the same ":block/name".
 (def ^:large-vars/data-var schema
   {:db/ident        {:db/unique :db.unique/identity}

+ 38 - 23
src/main/frontend/worker/db/migrate.cljs

@@ -127,25 +127,37 @@
     (d/reset-schema! conn (update schema :block/type #(assoc % :db/cardinality :db.cardinality/one)))
     []))
 
-(defn- separate-addresses-in-kvs-table
-  [_conn _search-db ^Object sqlite-db]
-  (let [data (some->> (.exec sqlite-db #js {:sql "select addr, content from kvs where addr = 0"
-                                            :rowMode "array"})
-                      bean/->clj
-                      (map (fn [[addr content]]
-                             (let [content' (sqlite-util/transit-read content)
-                                   [content' addresses] (if (map? content')
-                                                          [(dissoc content' :addresses) (:addresses content')]
-                                                          [content' nil])]
-                               #js {:$addr addr
-                                    :$content content'
-                                    :$addresses addresses}))))]
-    (.exec sqlite-db #js [:sql "alter table kvs add column addresses JSON"])
-    (.transaction sqlite-db
-                  (fn [tx]
-                    (doseq [item data]
-                      (.exec tx #js {:sql "INSERT INTO kvs (addr, content, addresses) values ($addr, $content, $addresses) on conflict(addr) do update set content = $content, addresses = $addresses"
-                                     :bind item}))))))
+(defn- add-addresses-in-kvs-table
+  [^Object sqlite-db]
+  (let [columns (->> (.exec sqlite-db #js {:sql "SELECT NAME FROM PRAGMA_TABLE_INFO('kvs')"
+                                           :rowMode "array"})
+                     bean/->clj
+                     (map first)
+                     set)]
+    (prn :debug :columns columns)
+    (when-not (contains? columns "addresses")
+      (let [data (some->> (.exec sqlite-db #js {:sql "select addr, content from kvs"
+                                                :rowMode "array"})
+                          bean/->clj
+                          (map (fn [[addr content]]
+                                 (let [content' (sqlite-util/transit-read content)
+                                       [content' addresses] (if (map? content')
+                                                              [(dissoc content' :addresses)
+                                                               (when-let [addresses (:addresses content')]
+                                                                 (prn :debug :addresses addresses)
+                                                                 (js/JSON.stringify (bean/->js addresses)))]
+                                                              [content' nil])
+                                       content' (sqlite-util/transit-write content')]
+                                   #js {:$addr addr
+                                        :$content content'
+                                        :$addresses addresses}))))]
+        (.exec sqlite-db #js {:sql "alter table kvs add column addresses JSON"})
+        (.transaction sqlite-db
+                      (fn [tx]
+                        (doseq [item data]
+                          (prn :debug :item item)
+                          (.exec tx #js {:sql "INSERT INTO kvs (addr, content, addresses) values ($addr, $content, $addresses) on conflict(addr) do update set content = $content, addresses = $addresses"
+                                         :bind item}))))))))
 
 (def schema-version->updates
   [[3 {:properties [:logseq.property/table-sorting :logseq.property/table-filters
@@ -167,16 +179,19 @@
    [9 {:fix update-task-ident}]
    [10 {:fix update-table-properties}]
    [11 {:fix property-checkbox-type-non-ref}]
-   [12 {:fix update-block-type-many->one}]
-   [13 {:fix separate-addresses-in-kvs-table}]])
+   [12 {:fix update-block-type-many->one}]])
 
 (let [max-schema-version (apply max (map first schema-version->updates))]
   (assert (<= db-schema/version max-schema-version))
   (when (< db-schema/version max-schema-version)
     (js/console.warn (str "Current db schema-version is " db-schema/version ", max available schema-version is " max-schema-version))))
 
+(defn migrate-sqlite-db
+  [db]
+  (add-addresses-in-kvs-table db))
+
 (defn migrate
-  [conn search-db sqlite-db]
+  [conn search-db]
   (let [db @conn
         version-in-db (or (:kv/value (d/entity db :logseq.kv/schema-version)) 0)]
     (cond
@@ -208,7 +223,7 @@
                    (fn [update]
                      (when-let [fix (:fix update)]
                        (when (fn? fix)
-                         (fix conn search-db sqlite-db)))) updates)
+                         (fix conn search-db)))) updates)
             tx-data' (if db-based? (concat new-properties fixes) fixes)]
         (when (seq tx-data')
           (let [tx-data' (concat tx-data' [(sqlite-create-graph/kv :logseq.kv/schema-version db-schema/version)])]

+ 4 - 3
src/main/frontend/worker/db_worker.cljs

@@ -5,7 +5,6 @@
             [cljs-bean.core :as bean]
             [clojure.edn :as edn]
             [clojure.string :as string]
-            [clojure.set :as set]
             [datascript.core :as d]
             [datascript.storage :refer [IStorage]]
             [frontend.common.file.core :as common-file]
@@ -123,7 +122,7 @@
                                         :bind item}))))
     (when (seq delete-addrs)
       (.transaction db (fn [tx]
-                         (prn :debug :delete-addrs delete-addrs)
+                         ;; (prn :debug :delete-addrs delete-addrs)
                          (doseq [addr delete-addrs]
                            (.exec tx #js {:sql "Delete from kvs WHERE addr = ? AND NOT EXISTS (SELECT 1 FROM json_each(addresses) WHERE value = ?);"
                                           :bind #js [addr]})))))))
@@ -247,6 +246,8 @@
       (.exec db "PRAGMA locking_mode=exclusive")
       (sqlite-common-db/create-kvs-table! db)
       (sqlite-common-db/create-kvs-table! client-ops-db)
+      (db-migrate/migrate-sqlite-db db)
+      (db-migrate/migrate-sqlite-db client-ops-db)
       (search/create-tables-and-triggers! search-db)
       (let [schema (sqlite-util/get-schema repo)
             conn (sqlite-common-db/get-storage-conn storage schema)
@@ -266,7 +267,7 @@
           (catch :default _e))
 
         ;; (gc-kvs-table! db)
-        (db-migrate/migrate conn search-db db)
+        (db-migrate/migrate conn search-db)
 
         (db-listener/listen-db-changes! repo conn)))))