Selaa lähdekoodia

fix: db missing addresses

This commit uses sql to ensure deleting addresses are not referenced
in any row.
Tienson Qin 5 kuukautta sitten
vanhempi
sitoutus
789834a9af
4 muutettua tiedostoa jossa 29 lisäystä ja 14 poistoa
  1. 1 1
      deps.edn
  2. 1 1
      deps/db/deps.edn
  3. 1 1
      deps/outliner/deps.edn
  4. 26 11
      src/main/frontend/worker/db_worker.cljs

+ 1 - 1
deps.edn

@@ -5,7 +5,7 @@
                                          :sha     "5d672bf84ed944414b9f61eeb83808ead7be9127"}
 
   datascript/datascript                 {:git/url "https://github.com/logseq/datascript" ;; fork
-                                         :sha     "4b1f15f05a6b4a718a62c247956206480e361ea6"}
+                                         :sha     "94b68a02ad8e7354c84c1b3cf3a1b33e19258f41"}
 
   datascript-transit/datascript-transit {:mvn/version "0.3.0"}
   borkdude/rewrite-edn                  {:mvn/version "0.4.9"}

+ 1 - 1
deps/db/deps.edn

@@ -1,7 +1,7 @@
 {:deps
  ;; These nbb-logseq deps are kept in sync with https://github.com/logseq/nbb-logseq/blob/main/bb.edn
  {datascript/datascript {:git/url "https://github.com/logseq/datascript" ;; fork
-                         :sha     "4b1f15f05a6b4a718a62c247956206480e361ea6"}
+                         :sha     "94b68a02ad8e7354c84c1b3cf3a1b33e19258f41"}
   datascript-transit/datascript-transit {:mvn/version "0.3.0"
                                          :exclusions [datascript/datascript]}
   cljs-bean/cljs-bean         {:mvn/version "1.5.0"}

+ 1 - 1
deps/outliner/deps.edn

@@ -1,7 +1,7 @@
 {:deps
  ;; These nbb-logseq deps are kept in sync with https://github.com/logseq/nbb-logseq/blob/main/bb.edn
  {datascript/datascript {:git/url "https://github.com/logseq/datascript" ;; fork
-                         :sha     "4b1f15f05a6b4a718a62c247956206480e361ea6"}
+                         :sha     "94b68a02ad8e7354c84c1b3cf3a1b33e19258f41"}
   com.cognitect/transit-cljs {:mvn/version "0.8.280"}
 
   ;; Any other deps should be added here and to nbb.edn

+ 26 - 11
src/main/frontend/worker/db_worker.cljs

@@ -188,6 +188,21 @@
                                                :db-schema-version (str version-in-db)}}))))
     missing-addresses))
 
+(def get-to-delete-unused-addresses-sql
+  "WITH to_delete(addr) AS (
+     SELECT value
+     FROM json_each(?)
+   ),
+  referenced(addr) AS (
+    SELECT json_each.value
+    FROM kvs
+    JOIN json_each(kvs.addresses)
+    WHERE kvs.addr NOT IN (SELECT addr FROM to_delete)
+      AND json_each.value IN (SELECT addr FROM to_delete)
+  )
+  SELECT addr FROM to_delete
+  WHERE addr NOT IN (SELECT addr FROM referenced)")
+
 (defn upsert-addr-content!
   "Upsert addr+data-seq. Update sqlite-cli/upsert-addr-content! when making changes"
   [db data delete-addrs*]
@@ -198,19 +213,19 @@
                          (.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}))))
     (when (seq delete-addrs)
-      (.transaction db (fn [tx]
-                         (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]}))))
+      (let [result (.exec db #js {:sql get-to-delete-unused-addresses-sql
+                                  :bind (js/JSON.stringify (clj->js delete-addrs))
+                                  :rowMode "array"})
+            non-refed-addrs (map #(aget % 0) result)]
+        (when (seq non-refed-addrs)
+          (.transaction db (fn [tx]
+                             (doseq [addr non-refed-addrs]
+                               (.exec tx #js {:sql "Delete from kvs where addr = ?"
+                                              :bind #js [addr]}))))))
       (let [missing-addrs (when worker-util/dev?
                             (seq (find-missing-addresses nil db {:delete-addrs delete-addrs})))]
-        (if (seq missing-addrs)
-          (worker-util/post-message :notification [(str "Bug!! Missing addresses: " missing-addrs) :error false])
-          (when (seq delete-addrs)
-            (.transaction db (fn [tx]
-                               (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]}))))))))))
+        (when (seq missing-addrs)
+          (worker-util/post-message :notification [(str "Bug!! Missing addresses: " missing-addrs) :error false]))))))
 
 (defn restore-data-from-addr
   "Update sqlite-cli/restore-data-from-addr when making changes"