|
@@ -34,7 +34,6 @@ import (
|
|
"github.com/88250/lute/editor"
|
|
"github.com/88250/lute/editor"
|
|
"github.com/88250/lute/lex"
|
|
"github.com/88250/lute/lex"
|
|
"github.com/88250/lute/parse"
|
|
"github.com/88250/lute/parse"
|
|
- "github.com/emirpasic/gods/sets/hashset"
|
|
|
|
"github.com/siyuan-note/filelock"
|
|
"github.com/siyuan-note/filelock"
|
|
"github.com/siyuan-note/logging"
|
|
"github.com/siyuan-note/logging"
|
|
"github.com/siyuan-note/siyuan/kernel/av"
|
|
"github.com/siyuan-note/siyuan/kernel/av"
|
|
@@ -384,8 +383,8 @@ func (tx *Transaction) doMove(operation *Operation) (ret *TxErr) {
|
|
if err = tx.writeTree(targetTree); err != nil {
|
|
if err = tx.writeTree(targetTree); err != nil {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
- task.AppendAsyncTaskWithDelay(task.SetDefRefCount, 1*time.Second, pushSetDefRefCount, srcTree.ID, srcTree.ID)
|
|
|
|
- task.AppendAsyncTaskWithDelay(task.SetDefRefCount, 1*time.Second, pushSetDefRefCount, targetTree.ID, srcNode.ID)
|
|
|
|
|
|
+ task.AppendAsyncTaskWithDelay(task.SetDefRefCount, 1*time.Second, refreshRefCount, srcTree.ID, srcTree.ID)
|
|
|
|
+ task.AppendAsyncTaskWithDelay(task.SetDefRefCount, 1*time.Second, refreshRefCount, targetTree.ID, srcNode.ID)
|
|
}
|
|
}
|
|
return
|
|
return
|
|
}
|
|
}
|
|
@@ -465,8 +464,8 @@ func (tx *Transaction) doMove(operation *Operation) (ret *TxErr) {
|
|
if err = tx.writeTree(targetTree); err != nil {
|
|
if err = tx.writeTree(targetTree); err != nil {
|
|
return &TxErr{code: TxErrCodeWriteTree, msg: err.Error(), id: id}
|
|
return &TxErr{code: TxErrCodeWriteTree, msg: err.Error(), id: id}
|
|
}
|
|
}
|
|
- task.AppendAsyncTaskWithDelay(task.SetDefRefCount, 1*time.Second, pushSetDefRefCount, srcTree.ID, srcTree.ID)
|
|
|
|
- task.AppendAsyncTaskWithDelay(task.SetDefRefCount, 1*time.Second, pushSetDefRefCount, targetTree.ID, srcNode.ID)
|
|
|
|
|
|
+ task.AppendAsyncTaskWithDelay(task.SetDefRefCount, 1*time.Second, refreshRefCount, srcTree.ID, srcTree.ID)
|
|
|
|
+ task.AppendAsyncTaskWithDelay(task.SetDefRefCount, 1*time.Second, refreshRefCount, targetTree.ID, srcNode.ID)
|
|
}
|
|
}
|
|
return
|
|
return
|
|
}
|
|
}
|
|
@@ -770,7 +769,7 @@ func (tx *Transaction) doDelete(operation *Operation) (ret *TxErr) {
|
|
if nil != defTree {
|
|
if nil != defTree {
|
|
defNode := treenode.GetNodeInTree(defTree, defID)
|
|
defNode := treenode.GetNodeInTree(defTree, defID)
|
|
if nil != defNode {
|
|
if nil != defNode {
|
|
- task.AppendAsyncTaskWithDelay(task.SetDefRefCount, 1*time.Second, pushSetDefRefCount, defTree.ID, defNode.ID)
|
|
|
|
|
|
+ task.AppendAsyncTaskWithDelay(task.SetDefRefCount, 1*time.Second, refreshRefCount, defTree.ID, defNode.ID)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1089,7 +1088,7 @@ func (tx *Transaction) doInsert(operation *Operation) (ret *TxErr) {
|
|
if nil != defTree {
|
|
if nil != defTree {
|
|
defNode := treenode.GetNodeInTree(defTree, defID)
|
|
defNode := treenode.GetNodeInTree(defTree, defID)
|
|
if nil != defNode {
|
|
if nil != defNode {
|
|
- task.AppendAsyncTaskWithDelay(task.SetDefRefCount, 1*time.Second, pushSetDefRefCount, defTree.ID, defNode.ID)
|
|
|
|
|
|
+ task.AppendAsyncTaskWithDelay(task.SetDefRefCount, 1*time.Second, refreshRefCount, defTree.ID, defNode.ID)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1187,7 +1186,7 @@ func (tx *Transaction) doUpdate(operation *Operation) (ret *TxErr) {
|
|
if nil != defTree {
|
|
if nil != defTree {
|
|
defNode := treenode.GetNodeInTree(defTree, defID)
|
|
defNode := treenode.GetNodeInTree(defTree, defID)
|
|
if nil != defNode {
|
|
if nil != defNode {
|
|
- task.AppendAsyncTaskWithDelay(task.SetDefRefCount, 1*time.Second, pushSetDefRefCount, defTree.ID, defNode.ID)
|
|
|
|
|
|
+ task.AppendAsyncTaskWithDelay(task.SetDefRefCount, 1*time.Second, refreshRefCount, defTree.ID, defNode.ID)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1240,24 +1239,6 @@ func getRefDefIDs(node *ast.Node) (refDefIDs []string) {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
-func pushSetDefRefCount(rootID, blockID string) {
|
|
|
|
- sql.WaitForWritingDatabase()
|
|
|
|
-
|
|
|
|
- bt := treenode.GetBlockTree(blockID)
|
|
|
|
- if nil == bt {
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- refCounts := sql.QueryRootChildrenRefCount(bt.RootID)
|
|
|
|
- refCount := refCounts[blockID]
|
|
|
|
- var rootRefCount int
|
|
|
|
- for _, count := range refCounts {
|
|
|
|
- rootRefCount += count
|
|
|
|
- }
|
|
|
|
- refIDs, _, _ := GetBlockRefIDs(blockID)
|
|
|
|
- util.PushSetDefRefCount(rootID, blockID, refIDs, refCount, rootRefCount)
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
func upsertAvBlockRel(node *ast.Node) {
|
|
func upsertAvBlockRel(node *ast.Node) {
|
|
var avIDs []string
|
|
var avIDs []string
|
|
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
|
|
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
|
|
@@ -1514,125 +1495,6 @@ func (tx *Transaction) writeTree(tree *parse.Tree) (err error) {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
-// refreshDynamicRefText 用于刷新块引用的动态锚文本。
|
|
|
|
-// 该实现依赖了数据库缓存,导致外部调用时可能需要阻塞等待数据库写入后才能获取到 refs
|
|
|
|
-func refreshDynamicRefText(updatedDefNode *ast.Node, updatedTree *parse.Tree) {
|
|
|
|
- changedDefs := map[string]*ast.Node{updatedDefNode.ID: updatedDefNode}
|
|
|
|
- changedTrees := map[string]*parse.Tree{updatedTree.ID: updatedTree}
|
|
|
|
- refreshDynamicRefTexts(changedDefs, changedTrees)
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// refreshDynamicRefTexts 用于批量刷新块引用的动态锚文本。
|
|
|
|
-// 该实现依赖了数据库缓存,导致外部调用时可能需要阻塞等待数据库写入后才能获取到 refs
|
|
|
|
-func refreshDynamicRefTexts(updatedDefNodes map[string]*ast.Node, updatedTrees map[string]*parse.Tree) {
|
|
|
|
- // 1. 更新引用的动态锚文本
|
|
|
|
- treeRefNodeIDs := map[string]*hashset.Set{}
|
|
|
|
- var changedParentNodes []*ast.Node
|
|
|
|
- for _, updateNode := range updatedDefNodes {
|
|
|
|
- refs, parentNodes := getRefsCacheByDefNode(updateNode)
|
|
|
|
- for _, ref := range refs {
|
|
|
|
- if refIDs, ok := treeRefNodeIDs[ref.RootID]; !ok {
|
|
|
|
- refIDs = hashset.New()
|
|
|
|
- refIDs.Add(ref.BlockID)
|
|
|
|
- treeRefNodeIDs[ref.RootID] = refIDs
|
|
|
|
- } else {
|
|
|
|
- refIDs.Add(ref.BlockID)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if 0 < len(parentNodes) {
|
|
|
|
- changedParentNodes = append(changedParentNodes, parentNodes...)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if 0 < len(changedParentNodes) {
|
|
|
|
- for _, parent := range changedParentNodes {
|
|
|
|
- updatedDefNodes[parent.ID] = parent
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- changedRefTree := map[string]*parse.Tree{}
|
|
|
|
-
|
|
|
|
- for refTreeID, refNodeIDs := range treeRefNodeIDs {
|
|
|
|
- refTree, ok := updatedTrees[refTreeID]
|
|
|
|
- if !ok {
|
|
|
|
- var err error
|
|
|
|
- refTree, err = LoadTreeByBlockID(refTreeID)
|
|
|
|
- if err != nil {
|
|
|
|
- continue
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- var refTreeChanged bool
|
|
|
|
- ast.Walk(refTree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
|
|
|
- if !entering {
|
|
|
|
- return ast.WalkContinue
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if n.IsBlock() && refNodeIDs.Contains(n.ID) {
|
|
|
|
- changed, changedDefNodes := updateRefText(n, updatedDefNodes)
|
|
|
|
- if !refTreeChanged && changed {
|
|
|
|
- refTreeChanged = true
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 推送动态锚文本节点刷新
|
|
|
|
- for _, defNode := range changedDefNodes {
|
|
|
|
- if "ref-d" == defNode.refType {
|
|
|
|
- task.AppendAsyncTaskWithDelay(task.SetRefDynamicText, 200*time.Millisecond, util.PushSetRefDynamicText, refTreeID, n.ID, defNode.id, defNode.refText)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return ast.WalkContinue
|
|
|
|
- }
|
|
|
|
- return ast.WalkContinue
|
|
|
|
- })
|
|
|
|
-
|
|
|
|
- if refTreeChanged {
|
|
|
|
- changedRefTree[refTreeID] = refTree
|
|
|
|
- sql.UpdateRefsTreeQueue(refTree)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 2. 更新属性视图主键内容
|
|
|
|
- for _, updatedDefNode := range updatedDefNodes {
|
|
|
|
- avs := updatedDefNode.IALAttr(av.NodeAttrNameAvs)
|
|
|
|
- if "" == avs {
|
|
|
|
- continue
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- avIDs := strings.Split(avs, ",")
|
|
|
|
- for _, avID := range avIDs {
|
|
|
|
- attrView, parseErr := av.ParseAttributeView(avID)
|
|
|
|
- if nil != parseErr {
|
|
|
|
- continue
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- changedAv := false
|
|
|
|
- blockValues := attrView.GetBlockKeyValues()
|
|
|
|
- if nil == blockValues {
|
|
|
|
- continue
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- for _, blockValue := range blockValues.Values {
|
|
|
|
- if blockValue.Block.ID == updatedDefNode.ID {
|
|
|
|
- newContent := getNodeRefText(updatedDefNode)
|
|
|
|
- if newContent != blockValue.Block.Content {
|
|
|
|
- blockValue.Block.Content = newContent
|
|
|
|
- changedAv = true
|
|
|
|
- }
|
|
|
|
- break
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if changedAv {
|
|
|
|
- av.SaveAttributeView(attrView)
|
|
|
|
- ReloadAttrView(avID)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 3. 保存变更
|
|
|
|
- for _, tree := range changedRefTree {
|
|
|
|
- indexWriteTreeUpsertQueue(tree)
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
func getRefsCacheByDefNode(updateNode *ast.Node) (ret []*sql.Ref, changedParentNodes []*ast.Node) {
|
|
func getRefsCacheByDefNode(updateNode *ast.Node) (ret []*sql.Ref, changedParentNodes []*ast.Node) {
|
|
ret = sql.GetRefsCacheByDefID(updateNode.ID)
|
|
ret = sql.GetRefsCacheByDefID(updateNode.ID)
|
|
if nil != updateNode.Parent && ast.NodeDocument != updateNode.Parent.Type &&
|
|
if nil != updateNode.Parent && ast.NodeDocument != updateNode.Parent.Type &&
|