From 21fbcc50907702756e3c0d5644676b6df9cf09cd Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Tue, 14 Nov 2023 10:02:03 +0800 Subject: [PATCH] :art: Kernel API `createDocWithMd` supports concurrent calls https://github.com/siyuan-note/siyuan/issues/9644 --- kernel/model/file.go | 156 +++++++++++++++++++++++-------------------- 1 file changed, 84 insertions(+), 72 deletions(-) diff --git a/kernel/model/file.go b/kernel/model/file.go index 6318a51bb..1d8dfd80d 100644 --- a/kernel/model/file.go +++ b/kernel/model/file.go @@ -25,6 +25,7 @@ import ( "sort" "strconv" "strings" + "sync" "time" "unicode/utf8" @@ -1008,7 +1009,12 @@ func createTreeTx(tree *parse.Tree) { PerformTransactions(&[]*Transaction{transaction}) } +var createDocLock = sync.Mutex{} + func CreateDocByMd(boxID, p, title, md string, sorts []string) (tree *parse.Tree, err error) { + createDocLock.Lock() + defer createDocLock.Unlock() + box := Conf.Box(boxID) if nil == box { err = errors.New(Conf.Language(0)) @@ -1027,6 +1033,9 @@ func CreateDocByMd(boxID, p, title, md string, sorts []string) (tree *parse.Tree } func CreateWithMarkdown(boxID, hPath, md, parentID, id string) (retID string, err error) { + createDocLock.Lock() + defer createDocLock.Unlock() + box := Conf.Box(boxID) if nil == box { err = errors.New(Conf.Language(0)) @@ -1040,6 +1049,81 @@ func CreateWithMarkdown(boxID, hPath, md, parentID, id string) (retID string, er return } +func CreateDailyNote(boxID string) (p string, existed bool, err error) { + createDocLock.Lock() + defer createDocLock.Unlock() + + box := Conf.Box(boxID) + if nil == box { + err = ErrBoxNotFound + return + } + + boxConf := box.GetConf() + if "" == boxConf.DailyNoteSavePath || "/" == boxConf.DailyNoteSavePath { + err = errors.New(Conf.Language(49)) + return + } + + hPath, err := RenderGoTemplate(boxConf.DailyNoteSavePath) + if nil != err { + return + } + + WaitForWritingFiles() + + existRoot := treenode.GetBlockTreeRootByHPath(box.ID, hPath) + if nil != existRoot { + existed = true + p = existRoot.Path + return + } + + id, err := createDocsByHPath(box.ID, hPath, "", "", "") + if nil != err { + return + } + + var dom string + if "" != boxConf.DailyNoteTemplatePath { + tplPath := filepath.Join(util.DataDir, "templates", boxConf.DailyNoteTemplatePath) + if !filelock.IsExist(tplPath) { + logging.LogWarnf("not found daily note template [%s]", tplPath) + } else { + dom, err = renderTemplate(tplPath, id, false) + if nil != err { + logging.LogWarnf("render daily note template [%s] failed: %s", boxConf.DailyNoteTemplatePath, err) + } + } + } + if "" != dom { + var tree *parse.Tree + tree, err = loadTreeByBlockID(id) + if nil == err { + tree.Root.FirstChild.Unlink() + + luteEngine := util.NewLute() + newTree := luteEngine.BlockDOM2Tree(dom) + var children []*ast.Node + for c := newTree.Root.FirstChild; nil != c; c = c.Next { + children = append(children, c) + } + for _, c := range children { + tree.Root.AppendChild(c) + } + tree.Root.SetIALAttr("updated", util.CurrentTimeSecondsStr()) + if err = indexWriteJSONQueue(tree); nil != err { + return + } + } + } + IncSync() + + b := treenode.GetBlockTree(id) + p = b.Path + return +} + func GetHPathByPath(boxID, p string) (hPath string, err error) { if "/" == p { hPath = "/" @@ -1414,78 +1498,6 @@ func RenameDoc(boxID, p, title string) (err error) { return } -func CreateDailyNote(boxID string) (p string, existed bool, err error) { - box := Conf.Box(boxID) - if nil == box { - err = ErrBoxNotFound - return - } - - boxConf := box.GetConf() - if "" == boxConf.DailyNoteSavePath || "/" == boxConf.DailyNoteSavePath { - err = errors.New(Conf.Language(49)) - return - } - - hPath, err := RenderGoTemplate(boxConf.DailyNoteSavePath) - if nil != err { - return - } - - WaitForWritingFiles() - - existRoot := treenode.GetBlockTreeRootByHPath(box.ID, hPath) - if nil != existRoot { - existed = true - p = existRoot.Path - return - } - - id, err := createDocsByHPath(box.ID, hPath, "", "", "") - if nil != err { - return - } - - var dom string - if "" != boxConf.DailyNoteTemplatePath { - tplPath := filepath.Join(util.DataDir, "templates", boxConf.DailyNoteTemplatePath) - if !filelock.IsExist(tplPath) { - logging.LogWarnf("not found daily note template [%s]", tplPath) - } else { - dom, err = renderTemplate(tplPath, id, false) - if nil != err { - logging.LogWarnf("render daily note template [%s] failed: %s", boxConf.DailyNoteTemplatePath, err) - } - } - } - if "" != dom { - var tree *parse.Tree - tree, err = loadTreeByBlockID(id) - if nil == err { - tree.Root.FirstChild.Unlink() - - luteEngine := util.NewLute() - newTree := luteEngine.BlockDOM2Tree(dom) - var children []*ast.Node - for c := newTree.Root.FirstChild; nil != c; c = c.Next { - children = append(children, c) - } - for _, c := range children { - tree.Root.AppendChild(c) - } - tree.Root.SetIALAttr("updated", util.CurrentTimeSecondsStr()) - if err = indexWriteJSONQueue(tree); nil != err { - return - } - } - } - IncSync() - - b := treenode.GetBlockTree(id) - p = b.Path - return -} - func createDoc(boxID, p, title, dom string) (tree *parse.Tree, err error) { title = gulu.Str.RemoveInvisible(title) if 512 < utf8.RuneCountInString(title) {