diff --git a/kernel/api/workspace.go b/kernel/api/workspace.go index 54bcd03bb..be62245a8 100644 --- a/kernel/api/workspace.go +++ b/kernel/api/workspace.go @@ -17,7 +17,6 @@ package api import ( - "errors" "fmt" "net/http" "os" @@ -29,7 +28,6 @@ import ( "github.com/88250/gulu" "github.com/gin-gonic/gin" "github.com/gofrs/flock" - "github.com/siyuan-note/logging" "github.com/siyuan-note/siyuan/kernel/model" "github.com/siyuan-note/siyuan/kernel/util" ) @@ -64,7 +62,7 @@ func createWorkspaceDir(c *gin.Context) { return } - workspacePaths, err := readWorkspacePaths() + workspacePaths, err := util.ReadWorkspacePaths() if nil != err { ret.Code = -1 ret.Msg = err.Error() @@ -73,7 +71,7 @@ func createWorkspaceDir(c *gin.Context) { workspacePaths = append(workspacePaths, absPath) - if err = writeWorkspacePaths(workspacePaths); nil != err { + if err = util.WriteWorkspacePaths(workspacePaths); nil != err { ret.Code = -1 ret.Msg = err.Error() return @@ -91,7 +89,7 @@ func removeWorkspaceDir(c *gin.Context) { path := arg["path"].(string) - workspacePaths, err := readWorkspacePaths() + workspacePaths, err := util.ReadWorkspacePaths() if nil != err { ret.Code = -1 ret.Msg = err.Error() @@ -100,7 +98,7 @@ func removeWorkspaceDir(c *gin.Context) { workspacePaths = gulu.Str.RemoveElem(workspacePaths, path) - if err = writeWorkspacePaths(workspacePaths); nil != err { + if err = util.WriteWorkspacePaths(workspacePaths); nil != err { ret.Code = -1 ret.Msg = err.Error() return @@ -120,7 +118,7 @@ func getWorkspaces(c *gin.Context) { ret := gulu.Ret.NewResult() defer c.JSON(http.StatusOK, ret) - workspacePaths, err := readWorkspacePaths() + workspacePaths, err := util.ReadWorkspacePaths() if nil != err { ret.Code = -1 ret.Msg = err.Error() @@ -169,7 +167,7 @@ func setWorkspaceDir(c *gin.Context) { } } - workspacePaths, err := readWorkspacePaths() + workspacePaths, err := util.ReadWorkspacePaths() if nil != err { ret.Code = -1 ret.Msg = err.Error() @@ -181,7 +179,7 @@ func setWorkspaceDir(c *gin.Context) { workspacePaths = gulu.Str.RemoveElem(workspacePaths, path) workspacePaths = append(workspacePaths, path) // 切换的工作空间固定放在最后一个 - if err = writeWorkspacePaths(workspacePaths); nil != err { + if err = util.WriteWorkspacePaths(workspacePaths); nil != err { ret.Code = -1 ret.Msg = err.Error() return @@ -194,45 +192,6 @@ func setWorkspaceDir(c *gin.Context) { } } -func readWorkspacePaths() (ret []string, err error) { - ret = []string{} - workspaceConf := filepath.Join(util.HomeDir, ".config", "siyuan", "workspace.json") - data, err := os.ReadFile(workspaceConf) - if nil != err { - msg := fmt.Sprintf("read workspace conf [%s] failed: %s", workspaceConf, err) - logging.LogErrorf(msg) - err = errors.New(msg) - return - } - - if err = gulu.JSON.UnmarshalJSON(data, &ret); nil != err { - msg := fmt.Sprintf("unmarshal workspace conf [%s] failed: %s", workspaceConf, err) - logging.LogErrorf(msg) - err = errors.New(msg) - return - } - return -} - -func writeWorkspacePaths(workspacePaths []string) (err error) { - workspaceConf := filepath.Join(util.HomeDir, ".config", "siyuan", "workspace.json") - data, err := gulu.JSON.MarshalJSON(workspacePaths) - if nil != err { - msg := fmt.Sprintf("marshal workspace conf [%s] failed: %s", workspaceConf, err) - logging.LogErrorf(msg) - err = errors.New(msg) - return - } - - if err = os.WriteFile(workspaceConf, data, 0644); nil != err { - msg := fmt.Sprintf("write workspace conf [%s] failed: %s", workspaceConf, err) - logging.LogErrorf(msg) - err = errors.New(msg) - return - } - return -} - func isInvalidWorkspacePath(absPath string) bool { if "" == absPath { return true diff --git a/kernel/model/transaction.go b/kernel/model/transaction.go index c246510da..ce90b5177 100644 --- a/kernel/model/transaction.go +++ b/kernel/model/transaction.go @@ -20,6 +20,7 @@ import ( "bytes" "errors" "fmt" + "io" "os" "path" "path/filepath" @@ -1246,6 +1247,10 @@ func autoFixIndex() { boxPath := filepath.Join(util.DataDir, box.ID) var paths []string filepath.Walk(boxPath, func(path string, info os.FileInfo, err error) error { + if isFullReindexing { + return io.EOF + } + if !info.IsDir() && filepath.Ext(path) == ".sy" { p := path[len(boxPath):] p = filepath.ToSlash(p) @@ -1258,11 +1263,19 @@ func autoFixIndex() { redundantPaths := treenode.GetRedundantPaths(box.ID, paths) for _, p := range redundantPaths { + if isFullReindexing { + break + } + treenode.RemoveBlockTreesByPath(p) } missingPaths := treenode.GetNotExistPaths(box.ID, paths) for i, p := range missingPaths { + if isFullReindexing { + break + } + reindexTreeByPath(box.ID, p, i, size) } } @@ -1307,6 +1320,10 @@ func autoFixIndex() { duplicatedRootIDs := sql.GetDuplicatedRootIDs() size := len(duplicatedRootIDs) for i, rootID := range duplicatedRootIDs { + if isFullReindexing { + break + } + root := sql.GetBlock(rootID) if nil == root { continue @@ -1321,6 +1338,10 @@ func autoFixIndex() { } func reindexTreeByPath(box, p string, i, size int) { + if isFullReindexing { + return + } + tree, err := LoadTree(box, p) if nil != err { return @@ -1330,6 +1351,10 @@ func reindexTreeByPath(box, p string, i, size int) { } func reindexTree(rootID string, i, size int) { + if isFullReindexing { + return + } + root := treenode.GetBlockTree(rootID) if nil == root { logging.LogWarnf("root block not found", rootID) diff --git a/kernel/util/working.go b/kernel/util/working.go index 0ced4a24d..2b8270bf2 100644 --- a/kernel/util/working.go +++ b/kernel/util/working.go @@ -18,7 +18,9 @@ package util import ( "bytes" + "errors" "flag" + "fmt" "log" "math/rand" "mime" @@ -216,20 +218,7 @@ func initWorkspaceDir(workspaceArg string) { } workspacePaths = append(workspacePaths, WorkspaceDir) } else { - data, err := os.ReadFile(workspaceConf) - if err = gulu.JSON.UnmarshalJSON(data, &workspacePaths); nil != err { - log.Printf("unmarshal workspace conf [%s] failed: %s", workspaceConf, err) - } - - var tmp []string - for _, d := range workspacePaths { - d = strings.TrimRight(d, " \t\n") // 去掉工作空间路径尾部空格 https://github.com/siyuan-note/siyuan/issues/6353 - if gulu.File.IsDir(d) { - tmp = append(tmp, d) - } - } - workspacePaths = tmp - + workspacePaths, _ = ReadWorkspacePaths() if 0 < len(workspacePaths) { WorkspaceDir = workspacePaths[len(workspacePaths)-1] if "" != workspaceArg { @@ -253,12 +242,8 @@ func initWorkspaceDir(workspaceArg string) { } } - if data, err := gulu.JSON.MarshalJSON(workspacePaths); nil == err { - if err = os.WriteFile(workspaceConf, data, 0644); nil != err { - log.Fatalf("write workspace conf [%s] failed: %s", workspaceConf, err) - } - } else { - log.Fatalf("marshal workspace conf [%s] failed: %s", workspaceConf, err) + if err := WriteWorkspacePaths(workspacePaths); nil != err { + log.Fatalf("write workspace conf [%s] failed: %s", workspaceConf, err) } ConfDir = filepath.Join(WorkspaceDir, "conf") @@ -281,6 +266,57 @@ func initWorkspaceDir(workspaceArg string) { SnippetsPath = filepath.Join(DataDir, "snippets") } +func ReadWorkspacePaths() (ret []string, err error) { + ret = []string{} + workspaceConf := filepath.Join(HomeDir, ".config", "siyuan", "workspace.json") + data, err := os.ReadFile(workspaceConf) + if nil != err { + msg := fmt.Sprintf("read workspace conf [%s] failed: %s", workspaceConf, err) + logging.LogErrorf(msg) + err = errors.New(msg) + return + } + + if err = gulu.JSON.UnmarshalJSON(data, &ret); nil != err { + msg := fmt.Sprintf("unmarshal workspace conf [%s] failed: %s", workspaceConf, err) + logging.LogErrorf(msg) + err = errors.New(msg) + return + } + + ret = gulu.Str.RemoveDuplicatedElem(ret) + + var tmp []string + for _, d := range ret { + d = strings.TrimRight(d, " \t\n") // 去掉工作空间路径尾部空格 https://github.com/siyuan-note/siyuan/issues/6353 + if gulu.File.IsDir(d) { + tmp = append(tmp, d) + } + } + ret = tmp + return +} + +func WriteWorkspacePaths(workspacePaths []string) (err error) { + workspacePaths = gulu.Str.RemoveDuplicatedElem(workspacePaths) + workspaceConf := filepath.Join(HomeDir, ".config", "siyuan", "workspace.json") + data, err := gulu.JSON.MarshalJSON(workspacePaths) + if nil != err { + msg := fmt.Sprintf("marshal workspace conf [%s] failed: %s", workspaceConf, err) + logging.LogErrorf(msg) + err = errors.New(msg) + return + } + + if err = os.WriteFile(workspaceConf, data, 0644); nil != err { + msg := fmt.Sprintf("write workspace conf [%s] failed: %s", workspaceConf, err) + logging.LogErrorf(msg) + err = errors.New(msg) + return + } + return +} + var ( ServerPort = "0" // HTTP/WebSocket 端口,0 为使用随机端口 ReadOnly bool diff --git a/kernel/util/working_mobile.go b/kernel/util/working_mobile.go index 57dabdf4d..e998996b8 100644 --- a/kernel/util/working_mobile.go +++ b/kernel/util/working_mobile.go @@ -21,7 +21,6 @@ import ( "math/rand" "os" "path/filepath" - "strings" "time" "github.com/88250/gulu" @@ -122,20 +121,7 @@ func initWorkspaceDirMobile(workspaceBaseDir string) { } workspacePaths = append(workspacePaths, WorkspaceDir) } else { - data, err := os.ReadFile(workspaceConf) - if err = gulu.JSON.UnmarshalJSON(data, &workspacePaths); nil != err { - log.Printf("unmarshal workspace conf [%s] failed: %s", workspaceConf, err) - } - - var tmp []string - for _, d := range workspacePaths { - d = strings.TrimRight(d, " \t\n") // 去掉工作空间路径尾部空格 https://github.com/siyuan-note/siyuan/issues/6353 - if gulu.File.IsDir(d) { - tmp = append(tmp, d) - } - } - workspacePaths = tmp - + workspacePaths, _ = ReadWorkspacePaths() if 0 < len(workspacePaths) { WorkspaceDir = workspacePaths[len(workspacePaths)-1] if !gulu.File.IsDir(WorkspaceDir) { @@ -149,12 +135,8 @@ func initWorkspaceDirMobile(workspaceBaseDir string) { } } - if data, err := gulu.JSON.MarshalJSON(workspacePaths); nil == err { - if err = os.WriteFile(workspaceConf, data, 0644); nil != err { - log.Fatalf("write workspace conf [%s] failed: %s", workspaceConf, err) - } - } else { - log.Fatalf("marshal workspace conf [%s] failed: %s", workspaceConf, err) + if err := WriteWorkspacePaths(workspacePaths); nil != err { + log.Fatalf("write workspace conf [%s] failed: %s", workspaceConf, err) } ConfDir = filepath.Join(WorkspaceDir, "conf")