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() +}