fix: db missing addresses

This commit uses sql to ensure deleting addresses are not referenced
in any row.
This commit is contained in:
Tienson Qin
2025-05-20 05:53:34 +08:00
parent c9c0fc9ec3
commit 789834a9af
4 changed files with 29 additions and 14 deletions

View File

@@ -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"}

2
deps/db/deps.edn vendored
View File

@@ -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"}

View File

@@ -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

View File

@@ -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"