From 4c174a100c3b8685b3438d6323f630f89c65ac42 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Fri, 15 Mar 2024 19:13:38 +0800 Subject: [PATCH 1/3] :art: Upgrade to FSRS-4.5 https://github.com/siyuan-note/siyuan/issues/10607 --- kernel/go.mod | 6 +++--- kernel/go.sum | 14 ++++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/kernel/go.mod b/kernel/go.mod index 308f4f08b..a947d3c88 100644 --- a/kernel/go.mod +++ b/kernel/go.mod @@ -43,7 +43,7 @@ require ( github.com/mitchellh/go-ps v1.0.0 github.com/mssola/useragent v1.0.0 github.com/olahol/melody v1.1.4 - github.com/open-spaced-repetition/go-fsrs v1.1.0 + github.com/open-spaced-repetition/go-fsrs v1.2.0 github.com/panjf2000/ants/v2 v2.9.0 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/radovskyb/watcher v1.0.7 @@ -57,7 +57,7 @@ require ( github.com/siyuan-note/filelock v0.0.0-20240128091141-94d7bb3e0772 github.com/siyuan-note/httpclient v0.0.0-20240312073515-af29be1cfb4e github.com/siyuan-note/logging v0.0.0-20231208035918-61f884c854f0 - github.com/siyuan-note/riff v0.0.0-20240305012846-494c7fb46c45 + github.com/siyuan-note/riff v0.0.0-20240315100323-cc554b704bcc github.com/spf13/cast v1.6.0 github.com/steambap/captcha v1.4.1 github.com/studio-b12/gowebdav v0.9.0 @@ -156,7 +156,7 @@ require ( go.uber.org/mock v0.4.0 // indirect golang.org/x/arch v0.7.0 // indirect golang.org/x/crypto v0.21.0 // indirect - golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect + golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f // indirect golang.org/x/net v0.22.0 // indirect golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.18.0 // indirect diff --git a/kernel/go.sum b/kernel/go.sum index b5ad65851..bc06174ad 100644 --- a/kernel/go.sum +++ b/kernel/go.sum @@ -281,8 +281,8 @@ github.com/onsi/ginkgo/v2 v2.16.0 h1:7q1w9frJDzninhXxjZd+Y/x54XNjG/UlRLIYPZafsPM github.com/onsi/ginkgo/v2 v2.16.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= -github.com/open-spaced-repetition/go-fsrs v1.1.0 h1:0oqIRdLrfuI/PkXr6NikcIrNqnPxFzObJK6mZpuSfIs= -github.com/open-spaced-repetition/go-fsrs v1.1.0/go.mod h1:WpbNs4TTKZChOHFO+ME0B9femUVZsepFT5mhAioszRg= +github.com/open-spaced-repetition/go-fsrs v1.2.0 h1:cHCggDk/gEsQGyXybWn1NchrvSSzTknaN1fTpI9ihhI= +github.com/open-spaced-repetition/go-fsrs v1.2.0/go.mod h1:WpbNs4TTKZChOHFO+ME0B9femUVZsepFT5mhAioszRg= github.com/otiai10/gosseract/v2 v2.4.1 h1:G8AyBpXEeSlcq8TI85LH/pM5SXk8Djy2GEXisgyblRw= github.com/otiai10/gosseract/v2 v2.4.1/go.mod h1:1gNWP4Hgr2o7yqWfs6r5bZxAatjOIdqWxJLWsTsembk= github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs= @@ -363,8 +363,10 @@ github.com/siyuan-note/httpclient v0.0.0-20240312073515-af29be1cfb4e h1:2DeWT+8q github.com/siyuan-note/httpclient v0.0.0-20240312073515-af29be1cfb4e/go.mod h1:v/O6xcc3HomxJR1dLwENGan9RB08WqSPv4kxyzaTSUI= github.com/siyuan-note/logging v0.0.0-20231208035918-61f884c854f0 h1:+XjUr9UMXsczdO2bGA72p/k9wa2ShPb8ybi7CDBJ7HQ= github.com/siyuan-note/logging v0.0.0-20231208035918-61f884c854f0/go.mod h1:6mRFtAAvYPn3cDzqvyv+t8BVPGqpONDMMb5ywOhY1D4= -github.com/siyuan-note/riff v0.0.0-20240305012846-494c7fb46c45 h1:/ORGs2Llh98lXSiR3mt/8vZKrAOQAIB4LQkh1aslaow= -github.com/siyuan-note/riff v0.0.0-20240305012846-494c7fb46c45/go.mod h1:I/52MSsWLG0PMbbXCa7xHoT0zzlA9QW/1M4JFlxsvPY= +github.com/siyuan-note/riff v0.0.0-20240315093840-462c11a1810a h1:eTFvL5JrHZfOtWRfhR8YMI5VfxgA/yyn/TEDXcAHd/E= +github.com/siyuan-note/riff v0.0.0-20240315093840-462c11a1810a/go.mod h1:QGtzYegDWStrf0lAamdAX0DEO503xAZMU7XyJ3ftfmI= +github.com/siyuan-note/riff v0.0.0-20240315100323-cc554b704bcc h1:/xkXmPKwQZRnpJYW2WBv0VAGQeRaGN72KUqAZiar60Q= +github.com/siyuan-note/riff v0.0.0-20240315100323-cc554b704bcc/go.mod h1:QGtzYegDWStrf0lAamdAX0DEO503xAZMU7XyJ3ftfmI= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.7 h1:I6tZjLXD2Q1kjvNbIzB1wvQBsXmKXiVrhpRE8ZjP5jY= @@ -440,8 +442,8 @@ golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f h1:3CW0unweImhOzd5FmYuRsD4Y4oQFKZIjAnKbjV4WIrw= +golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8= golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= From 0daa752ba9d583b0b9cbd90232d5fd422b3ced9b Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Fri, 15 Mar 2024 19:14:57 +0800 Subject: [PATCH 2/3] :bug: Database multi-field sorting fails Fix https://github.com/siyuan-note/siyuan/issues/10616 --- kernel/av/sort.go | 106 ++++++++++++++------------------------------- kernel/av/table.go | 15 +++++++ 2 files changed, 48 insertions(+), 73 deletions(-) diff --git a/kernel/av/sort.go b/kernel/av/sort.go index fef2cd9ed..ade93d63f 100644 --- a/kernel/av/sort.go +++ b/kernel/av/sort.go @@ -44,19 +44,11 @@ func (value *Value) Compare(other *Value) int { switch value.Type { case KeyTypeBlock: if nil != value.Block && nil != other.Block { - ret := strings.Compare(value.Block.Content, other.Block.Content) - if 0 == ret { - ret = int(value.CreatedAt - other.CreatedAt) - } - return ret + return strings.Compare(value.Block.Content, other.Block.Content) } case KeyTypeText: if nil != value.Text && nil != other.Text { - ret := strings.Compare(value.Text.Content, other.Text.Content) - if 0 == ret { - ret = int(value.CreatedAt - other.CreatedAt) - } - return ret + return strings.Compare(value.Text.Content, other.Text.Content) } case KeyTypeNumber: if nil != value.Number && nil != other.Number { @@ -67,16 +59,16 @@ func (value *Value) Compare(other *Value) int { if value.Number.Content > other.Number.Content { return 1 - } else if value.Number.Content < other.Number.Content { - return -1 - } else { - return int(value.CreatedAt - other.CreatedAt) } + if value.Number.Content < other.Number.Content { + return -1 + } + return 0 } else { if other.Number.IsNotEmpty { return -1 } - return int(value.CreatedAt - other.CreatedAt) + return 0 } } case KeyTypeDate: @@ -87,37 +79,37 @@ func (value *Value) Compare(other *Value) int { } if value.Date.Content > other.Date.Content { return 1 - } else if value.Date.Content < other.Date.Content { - return -1 - } else { - return int(value.CreatedAt - other.CreatedAt) } + if value.Date.Content < other.Date.Content { + return -1 + } + return 0 } else { if other.Date.IsNotEmpty { return -1 } - return int(value.CreatedAt - other.CreatedAt) + return 0 } } case KeyTypeCreated: if nil != value.Created && nil != other.Created { if value.Created.Content > other.Created.Content { return 1 - } else if value.Created.Content < other.Created.Content { - return -1 - } else { - return int(value.CreatedAt - other.CreatedAt) } + if value.Created.Content < other.Created.Content { + return -1 + } + return 0 } case KeyTypeUpdated: if nil != value.Updated && nil != other.Updated { if value.Updated.Content > other.Updated.Content { return 1 - } else if value.Updated.Content < other.Updated.Content { - return -1 - } else { - return int(value.CreatedAt - other.CreatedAt) } + if value.Updated.Content < other.Updated.Content { + return -1 + } + return 0 } case KeyTypeSelect, KeyTypeMSelect: if nil != value.MSelect && nil != other.MSelect { @@ -129,35 +121,19 @@ func (value *Value) Compare(other *Value) int { for _, v := range other.MSelect { v2 += v.Content } - ret := strings.Compare(v1, v2) - if 0 == ret { - ret = int(value.CreatedAt - other.CreatedAt) - } - return ret + return strings.Compare(v1, v2) } case KeyTypeURL: if nil != value.URL && nil != other.URL { - ret := strings.Compare(value.URL.Content, other.URL.Content) - if 0 == ret { - ret = int(value.CreatedAt - other.CreatedAt) - } - return ret + return strings.Compare(value.URL.Content, other.URL.Content) } case KeyTypeEmail: if nil != value.Email && nil != other.Email { - ret := strings.Compare(value.Email.Content, other.Email.Content) - if 0 == ret { - ret = int(value.CreatedAt - other.CreatedAt) - } - return ret + return strings.Compare(value.Email.Content, other.Email.Content) } case KeyTypePhone: if nil != value.Phone && nil != other.Phone { - ret := strings.Compare(value.Phone.Content, other.Phone.Content) - if 0 == ret { - ret = int(value.CreatedAt - other.CreatedAt) - } - return ret + return strings.Compare(value.Phone.Content, other.Phone.Content) } case KeyTypeMAsset: if nil != value.MAsset && nil != other.MAsset { @@ -169,11 +145,7 @@ func (value *Value) Compare(other *Value) int { for _, v := range other.MAsset { v2 += v.Content } - ret := strings.Compare(v1, v2) - if 0 == ret { - ret = int(value.CreatedAt - other.CreatedAt) - } - return ret + return strings.Compare(v1, v2) } case KeyTypeTemplate: if nil != value.Template && nil != other.Template { @@ -188,13 +160,9 @@ func (value *Value) Compare(other *Value) int { if v1 < v2 { return -1 } - return int(value.CreatedAt - other.CreatedAt) + return 0 } - ret := strings.Compare(value.Template.Content, other.Template.Content) - if 0 == ret { - ret = int(value.CreatedAt - other.CreatedAt) - } - return ret + return strings.Compare(value.Template.Content, other.Template.Content) } case KeyTypeCheckbox: if nil != value.Checkbox && nil != other.Checkbox { @@ -204,7 +172,7 @@ func (value *Value) Compare(other *Value) int { if !value.Checkbox.Checked && other.Checkbox.Checked { return -1 } - return int(value.CreatedAt - other.CreatedAt) + return 0 } case KeyTypeRelation: if nil != value.Relation && nil != other.Relation { @@ -231,13 +199,9 @@ func (value *Value) Compare(other *Value) int { if v1 < v2 { return -1 } - return int(value.CreatedAt - other.CreatedAt) + return 0 } - ret := strings.Compare(vContent, oContent) - if 0 == ret { - ret = int(value.CreatedAt - other.CreatedAt) - } - return ret + return strings.Compare(vContent, oContent) } case KeyTypeRollup: if nil != value.Rollup && nil != other.Rollup { @@ -263,14 +227,10 @@ func (value *Value) Compare(other *Value) int { if v1 < v2 { return -1 } - return int(value.CreatedAt - other.CreatedAt) + return 0 } - ret := strings.Compare(vContent, oContent) - if 0 == ret { - ret = int(value.CreatedAt - other.CreatedAt) - } - return ret + return strings.Compare(vContent, oContent) } } - return int(value.CreatedAt - other.CreatedAt) + return 0 } diff --git a/kernel/av/table.go b/kernel/av/table.go index 10fcbf369..1a57055dc 100644 --- a/kernel/av/table.go +++ b/kernel/av/table.go @@ -208,6 +208,7 @@ func (table *Table) SortRows() { }) sort.Slice(editedRows, func(i, j int) bool { + sorted := true for _, colIndexSort := range colIndexSorts { val1 := editedRows[i].Cells[colIndexSort.Index].Value if nil == val1 { @@ -221,14 +222,28 @@ func (table *Table) SortRows() { result := val1.Compare(val2) if 0 == result { + sorted = false continue } + sorted = true if colIndexSort.Order == SortOrderAsc { return 0 > result } return 0 < result } + + if !sorted { + key1 := editedRows[i].GetBlockValue() + if nil == key1 { + return false + } + key2 := editedRows[j].GetBlockValue() + if nil == key2 { + return false + } + return key1.CreatedAt < key2.CreatedAt + } return false }) From 095dfc2b3504e43a431e1aee68ec7d551f207745 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Fri, 15 Mar 2024 19:34:59 +0800 Subject: [PATCH 3/3] :technologist: Add internal kernel API `/api/block/getBlocksIndexes` Fix https://github.com/siyuan-note/siyuan/issues/10608 --- kernel/api/block.go | 18 ++++++++++++++++++ kernel/api/router.go | 1 + kernel/model/blockinfo.go | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/kernel/api/block.go b/kernel/api/block.go index 6054bcf06..7d242a6cd 100644 --- a/kernel/api/block.go +++ b/kernel/api/block.go @@ -436,6 +436,24 @@ func getBlockIndex(c *gin.Context) { ret.Data = index } +func getBlocksIndexes(c *gin.Context) { + ret := gulu.Ret.NewResult() + defer c.JSON(http.StatusOK, ret) + + arg, ok := util.JsonArg(c, ret) + if !ok { + return + } + + idsArg := arg["ids"].([]interface{}) + var ids []string + for _, id := range idsArg { + ids = append(ids, id.(string)) + } + index := model.GetBlocksIndexes(ids) + ret.Data = index +} + func getBlockInfo(c *gin.Context) { ret := gulu.Ret.NewResult() defer c.JSON(http.StatusOK, ret) diff --git a/kernel/api/router.go b/kernel/api/router.go index 6d3fbef6a..f59849480 100644 --- a/kernel/api/router.go +++ b/kernel/api/router.go @@ -168,6 +168,7 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/block/getTailChildBlocks", model.CheckAuth, getTailChildBlocks) ginServer.Handle("POST", "/api/block/getBlockBreadcrumb", model.CheckAuth, getBlockBreadcrumb) ginServer.Handle("POST", "/api/block/getBlockIndex", model.CheckAuth, getBlockIndex) + ginServer.Handle("POST", "/api/block/getBlocksIndexes", model.CheckAuth, getBlocksIndexes) ginServer.Handle("POST", "/api/block/getRefIDs", model.CheckAuth, getRefIDs) ginServer.Handle("POST", "/api/block/getRefIDsByFileAnnotationID", model.CheckAuth, getRefIDsByFileAnnotationID) ginServer.Handle("POST", "/api/block/getBlockDefIDsByRefText", model.CheckAuth, getBlockDefIDsByRefText) diff --git a/kernel/model/blockinfo.go b/kernel/model/blockinfo.go index f59ccc993..5b9ca044b 100644 --- a/kernel/model/blockinfo.go +++ b/kernel/model/blockinfo.go @@ -274,6 +274,39 @@ func GetBlockIndex(id string) (ret int) { return } +func GetBlocksIndexes(ids []string) (ret map[string]int) { + ret = map[string]int{} + if 1 > len(ids) { + return + } + + tree, _ := LoadTreeByBlockID(ids[0]) + if nil == tree { + return + } + + idx := 0 + nodesIndexes := map[string]int{} + ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus { + if !entering { + return ast.WalkContinue + } + + if !n.IsChildBlockOf(tree.Root, 1) { + return ast.WalkContinue + } + + nodesIndexes[n.ID] = idx + idx++ + return ast.WalkContinue + }) + + for _, id := range ids { + ret[id] = nodesIndexes[id] + } + return +} + type BlockPath struct { ID string `json:"id"` Name string `json:"name"`