From b3d581718b360a5a4facdccdf23e4fa0e0b6de7e Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Thu, 28 Mar 2024 11:27:02 +0800 Subject: [PATCH] :art: Automatically loads and indexes from the file system when a block is not found https://github.com/siyuan-note/siyuan/issues/10772 --- kernel/model/tree.go | 60 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/kernel/model/tree.go b/kernel/model/tree.go index 659b323aa..aede8e6c5 100644 --- a/kernel/model/tree.go +++ b/kernel/model/tree.go @@ -18,8 +18,8 @@ package model import ( "errors" - "github.com/siyuan-note/siyuan/kernel/task" "io/fs" + "os" "path" "path/filepath" "strings" @@ -31,6 +31,8 @@ import ( "github.com/siyuan-note/filelock" "github.com/siyuan-note/logging" "github.com/siyuan-note/siyuan/kernel/filesys" + "github.com/siyuan-note/siyuan/kernel/sql" + "github.com/siyuan-note/siyuan/kernel/task" "github.com/siyuan-note/siyuan/kernel/treenode" "github.com/siyuan-note/siyuan/kernel/util" ) @@ -162,10 +164,64 @@ func LoadTreeByBlockID(id string) (ret *parse.Tree, err error) { return } - return nil, ErrBlockNotFound + // 尝试从文件系统加载 + searchTreeInFilesystem(id) + bt = treenode.GetBlockTree(id) + if nil == bt { + return nil, ErrTreeNotFound + } } luteEngine := util.NewLute() ret, err = filesys.LoadTree(bt.BoxID, bt.Path, luteEngine) return } + +func searchTreeInFilesystem(rootID string) { + msdID := util.PushMsg(Conf.language(45), 7000) + defer util.PushClearMsg(msdID) + + var treePath string + filepath.Walk(util.DataDir, func(path string, info fs.FileInfo, err error) error { + if info.IsDir() { + if strings.HasPrefix(info.Name(), ".") { + return filepath.SkipDir + } + return nil + } + + if !strings.HasSuffix(info.Name(), ".sy") { + return nil + } + + baseName := filepath.Base(path) + if rootID+".sy" != baseName { + return nil + } + + treePath = path + return filepath.SkipAll + }) + + if "" == treePath { + return + } + + boxID := strings.TrimPrefix(treePath, util.DataDir) + boxID = boxID[1:] + boxID = boxID[:strings.Index(boxID, string(os.PathSeparator))] + treePath = strings.TrimPrefix(treePath, util.DataDir) + treePath = strings.TrimPrefix(treePath, string(os.PathSeparator)) + treePath = strings.TrimPrefix(treePath, boxID) + treePath = filepath.ToSlash(treePath) + + tree, err := filesys.LoadTree(boxID, treePath, util.NewLute()) + if nil != err { + logging.LogErrorf("load tree [%s] failed: %s", treePath, err) + return + } + + treenode.IndexBlockTree(tree) + sql.IndexTreeQueue(tree) + sql.WaitForWritingDatabase() +}