mirror of https://github.com/logseq/logseq
Fix children blocks having stale :block/path-refs
when parent block's refs change. Fixes #5759, fixes #5992, fixes #6990, fixes #8430 and fixes #4116pull/9309/head
parent
aba0391ac1
commit
f70fbaf5e0
|
@ -41,14 +41,36 @@
|
||||||
[(:db/id (:block/page block))]
|
[(:db/id (:block/page block))]
|
||||||
(map :db/id (:block/refs block))
|
(map :db/id (:block/refs block))
|
||||||
parents-refs))
|
parents-refs))
|
||||||
|
;; Usually has changed as new-refs has page id while old-refs doesn't
|
||||||
refs-changed? (not= old-refs new-refs)
|
refs-changed? (not= old-refs new-refs)
|
||||||
children (db-model/get-block-children-ids repo (:block/uuid block))
|
children (db-model/get-block-children-ids repo (:block/uuid block))
|
||||||
children-refs (map (fn [id]
|
;; Builds map of children ids to their parent id and :block/refs ids
|
||||||
(let [entity (db/entity [:block/uuid id])]
|
children-maps (into {}
|
||||||
{:db/id (:db/id entity)
|
(map (fn [id]
|
||||||
:block/path-refs (concat
|
(let [entity (db/entity [:block/uuid id])]
|
||||||
(map :db/id (:block/path-refs entity))
|
[(:db/id entity)
|
||||||
new-refs)})) children)]
|
{:parent-id (get-in entity [:block/parent :db/id])
|
||||||
|
:block-ref-ids (map :db/id (:block/refs entity))}]))
|
||||||
|
children))
|
||||||
|
children-refs (map (fn [[id {:keys [block-ref-ids] :as child-map}]]
|
||||||
|
{:db/id id
|
||||||
|
;; Recalculate :block/path-refs as db contains stale data for this attribute
|
||||||
|
:block/path-refs
|
||||||
|
(set/union
|
||||||
|
;; Refs from top-level parent
|
||||||
|
new-refs
|
||||||
|
;; Refs from current block
|
||||||
|
block-ref-ids
|
||||||
|
;; Refs from parents in between top-level
|
||||||
|
;; parent and current block
|
||||||
|
(loop [parent-refs #{}
|
||||||
|
parent-id (:parent-id child-map)]
|
||||||
|
(if-let [parent (children-maps parent-id)]
|
||||||
|
(recur (into parent-refs (:block-ref-ids parent))
|
||||||
|
(:parent-id parent))
|
||||||
|
;; exits when top-level parent is reached
|
||||||
|
parent-refs)))})
|
||||||
|
children-maps)]
|
||||||
(swap! *computed-ids set/union (set (cons (:block/uuid block) children)))
|
(swap! *computed-ids set/union (set (cons (:block/uuid block) children)))
|
||||||
(util/concat-without-nil
|
(util/concat-without-nil
|
||||||
[(when (and (seq new-refs)
|
[(when (and (seq new-refs)
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
(ns frontend.modules.outliner.pipeline-test
|
||||||
|
(:require [cljs.test :refer [deftest is use-fixtures testing]]
|
||||||
|
[datascript.core :as d]
|
||||||
|
[frontend.state :as state]
|
||||||
|
[frontend.db :as db]
|
||||||
|
[frontend.modules.outliner.pipeline :as pipeline]
|
||||||
|
[frontend.test.helper :as test-helper :refer [load-test-files]]))
|
||||||
|
|
||||||
|
(use-fixtures :each {:before (fn []
|
||||||
|
;; Set current-repo explicitly since it's not the default
|
||||||
|
(state/set-current-repo! test-helper/test-db)
|
||||||
|
(test-helper/start-test-db!))
|
||||||
|
:after (fn []
|
||||||
|
(state/set-current-repo! nil)
|
||||||
|
(test-helper/destroy-test-db!))})
|
||||||
|
|
||||||
|
(defn- get-blocks [db]
|
||||||
|
(->> (d/q '[:find (pull ?b [* {:block/path-refs [:block/name :db/id]}])
|
||||||
|
:in $
|
||||||
|
:where [?b :block/content] [(missing? $ ?b :block/pre-block?)]]
|
||||||
|
db)
|
||||||
|
(map first)))
|
||||||
|
|
||||||
|
(deftest compute-block-path-refs
|
||||||
|
(load-test-files [{:file/path "pages/page1.md"
|
||||||
|
:file/content "prop:: #bar
|
||||||
|
- parent #foo
|
||||||
|
- child #baz
|
||||||
|
- grandchild #bing"}])
|
||||||
|
(testing "when a block's :refs change, descendants of block have correct :block/path-refs"
|
||||||
|
(let [conn (db/get-db test-helper/test-db false)
|
||||||
|
blocks (get-blocks @conn)
|
||||||
|
;; Update parent block to replace #foo with #bar
|
||||||
|
new-tag-id (:db/id (d/entity @conn [:block/name "bar"]))
|
||||||
|
modified-blocks (map #(if (= "parent #foo" (:block/content %))
|
||||||
|
(assoc %
|
||||||
|
:block/refs [{:db/id new-tag-id}]
|
||||||
|
:block/path-refs [{:db/id new-tag-id}])
|
||||||
|
%)
|
||||||
|
blocks)
|
||||||
|
refs-tx (pipeline/compute-block-path-refs {:tx-meta {:outliner-op :save-block}} modified-blocks)
|
||||||
|
_ (d/transact! conn (concat (map (fn [m] [:db/retract (:db/id m) :block/path-refs]) refs-tx)
|
||||||
|
refs-tx))
|
||||||
|
updated-blocks (->> (get-blocks @conn)
|
||||||
|
(map #(hash-map :block/content (:block/content %)
|
||||||
|
:path-ref-names (mapv :block/name (:block/path-refs %)))))]
|
||||||
|
(is (= [;; still have old parent content b/c we're only testing :block/path-refs updates
|
||||||
|
{:block/content "parent #foo"
|
||||||
|
:path-ref-names ["page1" "bar"]}
|
||||||
|
{:block/content "child #baz"
|
||||||
|
:path-ref-names ["page1" "bar" "baz"]}
|
||||||
|
{:block/content "grandchild #bing"
|
||||||
|
:path-ref-names ["page1" "bar" "baz" "bing"]}]
|
||||||
|
updated-blocks)))))
|
Loading…
Reference in New Issue