Browse Source

:art: Automatically loads and indexes from the file system when a block is not found https://github.com/siyuan-note/siyuan/issues/10772

Daniel 1 year ago
parent
commit
b3d581718b
1 changed files with 58 additions and 2 deletions
  1. 58 2
      kernel/model/tree.go

+ 58 - 2
kernel/model/tree.go

@@ -18,8 +18,8 @@ package model
 
 
 import (
 import (
 	"errors"
 	"errors"
-	"github.com/siyuan-note/siyuan/kernel/task"
 	"io/fs"
 	"io/fs"
+	"os"
 	"path"
 	"path"
 	"path/filepath"
 	"path/filepath"
 	"strings"
 	"strings"
@@ -31,6 +31,8 @@ import (
 	"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/filesys"
 	"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/treenode"
 	"github.com/siyuan-note/siyuan/kernel/util"
 	"github.com/siyuan-note/siyuan/kernel/util"
 )
 )
@@ -162,10 +164,64 @@ func LoadTreeByBlockID(id string) (ret *parse.Tree, err error) {
 			return
 			return
 		}
 		}
 
 
-		return nil, ErrBlockNotFound
+		// 尝试从文件系统加载
+		searchTreeInFilesystem(id)
+		bt = treenode.GetBlockTree(id)
+		if nil == bt {
+			return nil, ErrTreeNotFound
+		}
 	}
 	}
 
 
 	luteEngine := util.NewLute()
 	luteEngine := util.NewLute()
 	ret, err = filesys.LoadTree(bt.BoxID, bt.Path, luteEngine)
 	ret, err = filesys.LoadTree(bt.BoxID, bt.Path, luteEngine)
 	return
 	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()
+}