fix: invalid blocks caused by separating classes and properties

This commit is contained in:
Tienson Qin
2025-06-26 18:20:29 +08:00
parent 593aca94c0
commit 2635301951
2 changed files with 81 additions and 33 deletions

View File

@@ -239,9 +239,17 @@
tag-properties (->> (d/datoms db :avet :logseq.property.class/properties id)
(mapcat (fn [d]
[[:db/retract (:e d) (:a d) (:v d)]
[:db/add (:e d) (:a d) [:block/uuid (:block/uuid new-property)]]])))]
[:db/add (:e d) (:a d) [:block/uuid (:block/uuid new-property)]]])))
other-properties-tx (mapcat
(fn [ident]
(->> (d/datoms db :avet ident id)
(mapcat (fn [d]
[[:db/retract (:e d) (:a d) (:v d)]
[:db/add (:e d) (:a d) [:block/uuid (:block/uuid new-property)]]]))))
[:logseq.property.view/group-by-property :logseq.property.table/pinned-columns])]
(concat [new-property]
tag-properties
other-properties-tx
retract-property-attrs
(mapcat
(fn [d]

View File

@@ -5,42 +5,82 @@
[logseq.db :as ldb]
[logseq.db.frontend.validate :as db-validate]))
(defn- get-property-by-title
[db title]
(when title
(some->> (first (ldb/page-exists? db title [:logseq.class/Property]))
(d/entity db))))
(defn- fix-invalid-blocks!
[conn errors]
(let [tx-data (mapcat
(fn [{:keys [entity dispatch-key]}]
(let [entity (d/entity @conn (:db/id entity))]
(cond
(and (= dispatch-key :block) (nil? (:block/title entity)))
[[:db/retractEntity (:db/id entity)]]
(and (= dispatch-key :block) (nil? (:block/page entity)))
(let [latest-journal-id (:db/id (first (ldb/get-latest-journals @conn)))
page-id (:db/id (:block/page (:block/parent entity)))]
(let [db @conn
fix-tx-data (mapcat
(fn [{:keys [entity dispatch-key]}]
(let [entity (d/entity db (:db/id entity))]
(cond
page-id
[[:db/add (:db/id entity) :block/page page-id]]
latest-journal-id
[[:db/add (:db/id entity) :block/page latest-journal-id]
[:db/add (:db/id entity) :block/parent latest-journal-id]]
:else
(js/console.error (str "Don't know where to put the block " (:db/id entity)))))
(and (= dispatch-key :block) (nil? (:block/title entity)))
[[:db/retractEntity (:db/id entity)]]
(:block.temp/fully-loaded? entity)
[[:db/retract (:db/id entity) :block.temp/fully-loaded?]]
(and (:block/page entity) (not (:block/parent entity)))
[[:db/add (:db/id entity) :block/parent (:db/id (:block/page entity))]]
(and (not (:block/page entity)) (not (:block/parent entity)) (not (:block/name entity)))
[[:db/retractEntity (:db/id entity)]]
(and (= dispatch-key :property-value-block) (:block/title entity))
[[:db/retract (:db/id entity) :block/title]]
(and (ldb/class? entity) (not (:logseq.property.class/extends entity)))
[[:db/add (:db/id entity) :logseq.property.class/extends :logseq.class/Root]]
(and (or (ldb/class? entity) (ldb/property? entity)) (ldb/internal-page? entity))
[[:db/retract (:db/id entity) :block/tags :logseq.class/Page]]
:else
nil)))
errors)]
(and (= dispatch-key :block) (nil? (:block/page entity)))
(let [latest-journal-id (:db/id (first (ldb/get-latest-journals db)))
page-id (:db/id (:block/page (:block/parent entity)))]
(cond
page-id
[[:db/add (:db/id entity) :block/page page-id]]
latest-journal-id
[[:db/add (:db/id entity) :block/page latest-journal-id]
[:db/add (:db/id entity) :block/parent latest-journal-id]]
:else
(js/console.error (str "Don't know where to put the block " (:db/id entity)))))
(and (= dispatch-key :block)
(some (fn [k] (= "user.class" (namespace k))) (keys (:logseq.property.table/sized-columns entity))))
(let [new-value (->> (keep (fn [[k v]]
(if (= "user.class" (namespace k))
(when-let [property (get-property-by-title db (:block/title (d/entity db k)))]
[(:db/ident property) v])
[k v]))
(:logseq.property.table/sized-columns entity))
(into {}))]
[[:db/add (:db/id entity) :logseq.property.table/sized-columns new-value]])
(:block.temp/fully-loaded? entity)
[[:db/retract (:db/id entity) :block.temp/fully-loaded?]]
(and (:block/page entity) (not (:block/parent entity)))
[[:db/add (:db/id entity) :block/parent (:db/id (:block/page entity))]]
(and (not (:block/page entity)) (not (:block/parent entity)) (not (:block/name entity)))
[[:db/retractEntity (:db/id entity)]]
(and (= dispatch-key :property-value-block) (:block/title entity))
[[:db/retract (:db/id entity) :block/title]]
(and (ldb/class? entity) (not (:logseq.property.class/extends entity)))
[[:db/add (:db/id entity) :logseq.property.class/extends :logseq.class/Root]]
(and (or (ldb/class? entity) (ldb/property? entity)) (ldb/internal-page? entity))
[[:db/retract (:db/id entity) :block/tags :logseq.class/Page]]
:else
nil)))
errors)
class-as-properties (concat
(mapcat
(fn [ident]
(->> (d/datoms db :avet ident)
(mapcat (fn [d]
(let [entity (d/entity db (:v d))]
(when (ldb/class? entity)
(if-let [property (get-property-by-title db (:block/title entity))]
[[:db/retract (:e d) (:a d) (:v d)]
[:db/add (:e d) (:a d) (:db/id property)]]
[[:db/retract (:e d) (:a d) (:v d)]])))))))
[:logseq.property.view/group-by-property :logseq.property.table/pinned-columns])
(->> (d/datoms db :eavt)
(filter (fn [d] (= (namespace (:a d)) "user.class")))
(mapcat (fn [d]
(let [class-title (:block/title (d/entity db (:a d)))
property (get-property-by-title db class-title)]
(if property
[[:db/retract (:e d) (:a d) (:v d)]
[:db/add (:e d) (:db/ident property) (:v d)]]
[[:db/retract (:e d) (:a d) (:v d)]]))))))
tx-data (concat fix-tx-data class-as-properties)]
(when (seq tx-data)
(ldb/transact! conn tx-data {:fix-db? true}))))