From ff539bab034c9bcc5cbb6a6b4db27f819165b8ef Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sun, 27 Jul 2025 19:08:27 +0800 Subject: [PATCH 1/9] :art: Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 --- kernel/model/attribute_view.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 6fd98f5c8..026361fcf 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -3175,6 +3175,9 @@ func removeAttributeViewBlock(srcIDs []string, avID string, tx *Transaction) (er } err = av.SaveAttributeView(attrView) + if nil != err { + return + } historyDir, err := GetHistoryDir(HistoryOpUpdate) if err != nil { From d0662b5fde1902d74930504927f0922b2bd8d7dc Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sun, 27 Jul 2025 19:34:17 +0800 Subject: [PATCH 2/9] :art: Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 --- kernel/av/av.go | 15 +++++++++++++++ kernel/model/attribute_view.go | 17 ++++------------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/kernel/av/av.go b/kernel/av/av.go index a575ab446..5f9ea004b 100644 --- a/kernel/av/av.go +++ b/kernel/av/av.go @@ -220,6 +220,21 @@ func (view *View) GetGroup(groupID string) *View { return nil } +// GetGroupKey 获取分组视图的分组字段。 +func (view *View) GetGroupKey(attrView *AttributeView) (ret *Key) { + if nil == view.Group || "" == view.Group.Field { + return + } + + for _, kv := range attrView.KeyValues { + if kv.Key.ID == view.Group.Field { + ret = kv.Key + return + } + } + return +} + // GroupCalc 描述了分组计算规则和结果的结构。 type GroupCalc struct { Field string `json:"field"` // 字段 ID diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 026361fcf..f9d9152c9 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -3063,7 +3063,7 @@ func addAttributeViewBlock(now int64, avID, blockID, groupID, previousBlockID, a } // 如果存在分组条件,则将分组条件应用到新添加的块上 - groupKey := getViewGroupKey(view, attrView) + groupKey := view.GetGroupKey(attrView) if nil != view && nil != groupKey { if !filterKeyIDs[groupKey.ID] /* 过滤条件应用过的话就不重复处理了 */ && "" != groupID { if groupView := view.GetGroup(groupID); nil != groupView { @@ -3868,6 +3868,7 @@ func updateAttributeViewColTemplate(operation *Operation) (err error) { } } + regenAttrViewViewGroups(attrView, operation.ID) err = av.SaveAttributeView(attrView) return } @@ -4524,7 +4525,7 @@ func updateAttributeViewValue(tx *Transaction, attrView *av.AttributeView, keyID func regenAttrViewViewGroups(attrView *av.AttributeView, keyID string) { for _, view := range attrView.Views { - groupKey := getViewGroupKey(view, attrView) + groupKey := view.GetGroupKey(attrView) if nil == groupKey { continue } @@ -4549,17 +4550,6 @@ func regenAttrViewViewGroups(attrView *av.AttributeView, keyID string) { } } -func getViewGroupKey(view *av.View, attrView *av.AttributeView) *av.Key { - if nil == view.Group { - return nil - } - if "" == view.Group.Field { - return nil - } - ret, _ := attrView.GetKey(view.Group.Field) - return ret -} - func unbindBlockAv(tx *Transaction, avID, blockID string) { node, tree, err := getNodeByBlockID(tx, blockID) if err != nil { @@ -4753,6 +4743,7 @@ func removeAttributeViewColumnOption(operation *Operation) (err error) { break } + regenAttrViewViewGroups(attrView, operation.ID) err = av.SaveAttributeView(attrView) return } From e91a8b06197262a056873f7d48e309292bf7ee9f Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sun, 27 Jul 2025 19:34:42 +0800 Subject: [PATCH 3/9] :art: Clean code --- kernel/model/auth.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/kernel/model/auth.go b/kernel/model/auth.go index 79022d226..e1551ff70 100644 --- a/kernel/model/auth.go +++ b/kernel/model/auth.go @@ -46,8 +46,7 @@ const ( var ( accountsMap = AccountsMap{} - - key = make([]byte, 32) + jwtKey = make([]byte, 32) ) func GetBasicAuthAccount(username string) *Account { @@ -69,7 +68,7 @@ func InitAccounts() { } func InitJWT() { - if _, err := rand.Read(key); err != nil { + if _, err := rand.Read(jwtKey); err != nil { logging.LogErrorf("generate JWT signing key failed: %s", err) return } @@ -87,7 +86,7 @@ func InitJWT() { ClaimsKeyRole: RoleReader, }, ) - if token, err := t.SignedString(key); err != nil { + if token, err := t.SignedString(jwtKey); err != nil { logging.LogErrorf("JWT signature failed: %s", err) return } else { @@ -101,7 +100,7 @@ func ParseJWT(tokenString string) (*jwt.Token, error) { return jwt.Parse( tokenString, func(token *jwt.Token) (interface{}, error) { - return key, nil + return jwtKey, nil }, jwt.WithIssuer(iss), jwt.WithSubject(sub), From cf0467a7ac4ef3601b224e313a894d599a0cb5d6 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sun, 27 Jul 2025 19:36:46 +0800 Subject: [PATCH 4/9] :art: Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 --- kernel/model/attribute_view.go | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index f9d9152c9..c12f05b4e 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -4862,6 +4862,7 @@ func updateAttributeViewColumnOption(operation *Operation) (err error) { } } + regenAttrViewViewGroups(attrView, operation.ID) err = av.SaveAttributeView(attrView) return } From 15a17393b3aa5a7c4273adf4b18e441e1657b00b Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sun, 27 Jul 2025 19:50:14 +0800 Subject: [PATCH 5/9] :art: Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 --- kernel/model/attribute_view.go | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index c12f05b4e..6e7165e59 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -1606,10 +1606,7 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { case av.GroupMethodValue: if av.GroupOrderMan != group.Order { sort.SliceStable(items, func(i, j int) bool { - if av.GroupOrderAsc == group.Order { - return items[i].GetValue(group.Field).String(false) < items[j].GetValue(group.Field).String(false) - } - return items[i].GetValue(group.Field).String(false) > items[j].GetValue(group.Field).String(false) + return items[i].GetValue(group.Field).String(false) < items[j].GetValue(group.Field).String(false) }) } case av.GroupMethodRangeNum: @@ -1619,17 +1616,11 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { rangeStart, rangeEnd = group.Range.NumStart, group.Range.NumStart+group.Range.NumStep sort.SliceStable(items, func(i, j int) bool { - if av.GroupOrderAsc == group.Order { - return items[i].GetValue(group.Field).Number.Content < items[j].GetValue(group.Field).Number.Content - } - return items[i].GetValue(group.Field).Number.Content > items[j].GetValue(group.Field).Number.Content + return items[i].GetValue(group.Field).Number.Content < items[j].GetValue(group.Field).Number.Content }) case av.GroupMethodDateDay, av.GroupMethodDateWeek, av.GroupMethodDateMonth, av.GroupMethodDateYear, av.GroupMethodDateRelative: sort.SliceStable(items, func(i, j int) bool { - if av.GroupOrderAsc == group.Order { - return items[i].GetValue(group.Field).Date.Content < items[j].GetValue(group.Field).Date.Content - } - return items[i].GetValue(group.Field).Date.Content > items[j].GetValue(group.Field).Date.Content + return items[i].GetValue(group.Field).Date.Content < items[j].GetValue(group.Field).Date.Content }) } @@ -1761,10 +1752,11 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { if av.GroupOrderMan != view.Group.Order { sort.SliceStable(view.Groups, func(i, j int) bool { + iName, jName := view.Groups[i].Name, view.Groups[j].Name if av.GroupOrderAsc == view.Group.Order { - return view.Groups[i].Name < view.Groups[j].Name + return util.NaturalCompare(iName, jName) } - return view.Groups[i].Name > view.Groups[j].Name + return !util.NaturalCompare(iName, jName) }) } From f970f5c8482ecc02f690f27ac2067db8bd8a9fe9 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sun, 27 Jul 2025 20:10:56 +0800 Subject: [PATCH 6/9] :art: Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 --- kernel/model/attribute_view.go | 44 ++++++++++++++++------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 6e7165e59..aa637aff0 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -1573,6 +1573,19 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { return } + // 临时记录每个分组视图的状态,以便后面重新生成分组后可以恢复这些状态 + type GroupState struct { + Folded bool + Hidden int + } + groupStates := map[string]*GroupState{} + for _, groupView := range view.Groups { + groupStates[groupView.Name] = &GroupState{ + Folded: groupView.GroupFolded, + Hidden: groupView.GroupHidden, + } + } + group := view.Group view.Groups = nil viewable := sql.RenderView(attrView, view, "") @@ -1586,21 +1599,6 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { return } - // 如果是按日期分组,则需要记录每个分组视图的一些状态字段,以便后面重新计算分组后可以恢复这些状态 - type GroupState struct { - Folded bool - Hidden int - } - groupStates := map[string]*GroupState{} - if isGroupByDate(view) { - for _, groupView := range view.Groups { - groupStates[groupView.Name] = &GroupState{ - Folded: groupView.GroupFolded, - Hidden: groupView.GroupHidden, - } - } - } - var rangeStart, rangeEnd float64 switch group.Method { case av.GroupMethodValue: @@ -1738,15 +1736,13 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { view.Groups = append(view.Groups, v) } - if isGroupByDate(view) { - view.GroupUpdated = time.Now().UnixMilli() + view.GroupUpdated = time.Now().UnixMilli() - // 则恢复分组视图状态 - for _, groupView := range view.Groups { - if state, ok := groupStates[groupView.Name]; ok { - groupView.GroupFolded = state.Folded - groupView.GroupHidden = state.Hidden - } + // 则恢复分组视图状态 + for _, groupView := range view.Groups { + if state, ok := groupStates[groupView.Name]; ok { + groupView.GroupFolded = state.Folded + groupView.GroupHidden = state.Hidden } } @@ -1756,7 +1752,7 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { if av.GroupOrderAsc == view.Group.Order { return util.NaturalCompare(iName, jName) } - return !util.NaturalCompare(iName, jName) + return util.NaturalCompare(jName, iName) }) } From 08af24ae9e593a875d2eee2cc7941694a6856327 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sun, 27 Jul 2025 20:14:18 +0800 Subject: [PATCH 7/9] :art: Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 --- kernel/model/attribute_view.go | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index aa637aff0..60a52d9f0 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -295,6 +295,7 @@ func SetAttributeViewGroup(avID, blockID string, group *av.ViewGroup) (err error } err = av.SaveAttributeView(attrView) + ReloadAttrView(avID) return } From 9a72ef1472ae0c4c2c3cad42c0e88070586c1046 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sun, 27 Jul 2025 20:26:32 +0800 Subject: [PATCH 8/9] :art: Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 --- kernel/model/attribute_view.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 60a52d9f0..94281e755 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -63,18 +63,19 @@ func sortAttributeViewGroup(avID, blockID, previousGroupID, groupID string) (err return err } - var group *av.View + var groupView *av.View var index, previousIndex int for i, g := range view.Groups { if g.ID == groupID { - group = g + groupView = g index = i break } } - if nil == group { + if nil == groupView { return } + view.Group.Order = av.GroupOrderMan view.Groups = append(view.Groups[:index], view.Groups[index+1:]...) for i, g := range view.Groups { @@ -83,7 +84,7 @@ func sortAttributeViewGroup(avID, blockID, previousGroupID, groupID string) (err break } } - view.Groups = util.InsertElem(view.Groups, previousIndex, group) + view.Groups = util.InsertElem(view.Groups, previousIndex, groupView) err = av.SaveAttributeView(attrView) return @@ -3080,7 +3081,7 @@ func addAttributeViewBlock(now int64, avID, blockID, groupID, previousBlockID, a if av.KeyTypeSelect == groupKey.Type || av.KeyTypeMSelect == groupKey.Type { // 因为单选或多选只能按选项分组,并且可能存在空白分组(前面可能找不到临近项) ,所以单选或多选类型的分组字段使用分组值内容对应的选项 - if opt := groupKey.GetOption(groupView.GroupValue); nil != opt { + if opt := groupKey.GetOption(groupView.GroupValue); nil != opt && av.GroupValueDefault != groupView.GroupValue { newValue.MSelect[0].Content = opt.Name newValue.MSelect[0].Color = opt.Color } From 0f2e044c7e18f63f1cf9021ffbfe4ed6ff482f3b Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sun, 27 Jul 2025 20:26:42 +0800 Subject: [PATCH 9/9] :art: Clean code --- kernel/model/box.go | 2 +- kernel/model/conf.go | 2 +- kernel/model/index.go | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/model/box.go b/kernel/model/box.go index a1b658692..b38b1a6b7 100644 --- a/kernel/model/box.go +++ b/kernel/model/box.go @@ -690,7 +690,7 @@ func fullReindex() { sql.IndexIgnoreCached = false openedBoxes := Conf.GetOpenedBoxes() for _, openedBox := range openedBoxes { - index(openedBox.ID) + indexBox(openedBox.ID) } LoadFlashcards() debug.FreeOSMemory() diff --git a/kernel/model/conf.go b/kernel/model/conf.go index d224fc01d..c1dd5403a 100644 --- a/kernel/model/conf.go +++ b/kernel/model/conf.go @@ -870,7 +870,7 @@ func InitBoxes() { box.UpdateHistoryGenerated() // 初始化历史生成时间为当前时间 if !initialized { - index(box.ID) + indexBox(box.ID) } } diff --git a/kernel/model/index.go b/kernel/model/index.go index 23d4ab5cb..c9721623b 100644 --- a/kernel/model/index.go +++ b/kernel/model/index.go @@ -120,7 +120,7 @@ func unindex(boxID string) { func (box *Box) Index() { task.AppendTask(task.DatabaseIndexRef, removeBoxRefs, box.ID) - task.AppendTask(task.DatabaseIndex, index, box.ID) + task.AppendTask(task.DatabaseIndex, indexBox, box.ID) task.AppendTask(task.DatabaseIndexRef, IndexRefs) go func() { sql.FlushQueue() @@ -132,7 +132,7 @@ func removeBoxRefs(boxID string) { sql.DeleteBoxRefsQueue(boxID) } -func index(boxID string) { +func indexBox(boxID string) { box := Conf.Box(boxID) if nil == box { return