From be4ebe776ded66d03719eea99998331fbbb2683d Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sun, 24 Dec 2023 21:33:34 +0800 Subject: [PATCH 1/3] :art: Add Rollup column to database table view https://github.com/siyuan-note/siyuan/issues/9958 --- kernel/av/av.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/av/av.go b/kernel/av/av.go index 261d36f6f..fbf59218d 100644 --- a/kernel/av/av.go +++ b/kernel/av/av.go @@ -105,7 +105,8 @@ func NewKey(id, name, icon string, keyType KeyType) *Key { } type Rollup struct { - KeyID string `json:"keyID"` // 汇总列 ID + RelationKeyID string `json:"relationKeyID"` // 关联列 ID + KeyID string `json:"keyID"` // 目标列 ID } type Relation struct { From 93dc9f5c22565ad54608c9a9f0cc24d59926dd23 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sun, 24 Dec 2023 21:47:10 +0800 Subject: [PATCH 2/3] :art: Add Rollup column to database table view https://github.com/siyuan-note/siyuan/issues/9958 --- kernel/av/av.go | 10 +++++++-- kernel/model/attribute_view.go | 40 ++++++++++++++++++++++++++++++++++ kernel/model/transaction.go | 2 ++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/kernel/av/av.go b/kernel/av/av.go index fbf59218d..348366ce6 100644 --- a/kernel/av/av.go +++ b/kernel/av/av.go @@ -105,8 +105,14 @@ func NewKey(id, name, icon string, keyType KeyType) *Key { } type Rollup struct { - RelationKeyID string `json:"relationKeyID"` // 关联列 ID - KeyID string `json:"keyID"` // 目标列 ID + RelationKeyID string `json:"relationKeyID"` // 关联列 ID + KeyID string `json:"keyID"` // 目标列 ID + Calc *RollupCalc `json:"calc"` // 计算方式 +} + +type RollupCalc struct { + Operator CalcOperator `json:"operator"` + Result *Value `json:"result"` } type Relation struct { diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 710eecaea..581da4d3d 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -774,6 +774,46 @@ func getRowBlockValue(keyValues []*av.KeyValues) (ret *av.Value) { return } +func (tx *Transaction) doUpdateAttrViewColRollup(operation *Operation) (ret *TxErr) { + err := updateAttributeViewColRollup(operation) + if nil != err { + return &TxErr{code: TxErrWriteAttributeView, id: operation.AvID, msg: err.Error()} + } + return +} + +func updateAttributeViewColRollup(operation *Operation) (err error) { + // operation.AvID 汇总列所在 av + // operation.ID 汇总列 ID + // operation.ParentID 汇总列基于的关联列 ID + // operation.KeyID 目标列 ID + // operation.Data 计算方式 + + attrView, err := av.ParseAttributeView(operation.AvID) + if nil != err { + return + } + + rollUpKey, _ := attrView.GetKey(operation.ID) + if nil == rollUpKey { + return + } + + rollUpKey.Rollup = &av.Rollup{ + RelationKeyID: operation.ParentID, + KeyID: operation.KeyID, + } + + if "" != operation.Data { + if err = gulu.JSON.UnmarshalJSON([]byte(operation.Data.(string)), &rollUpKey.Rollup.Calc); nil != err { + return + } + } + + err = av.SaveAttributeView(attrView) + return +} + func (tx *Transaction) doUpdateAttrViewColRelation(operation *Operation) (ret *TxErr) { err := updateAttributeViewColRelation(operation) if nil != err { diff --git a/kernel/model/transaction.go b/kernel/model/transaction.go index aaa101fd1..4187e3e88 100644 --- a/kernel/model/transaction.go +++ b/kernel/model/transaction.go @@ -274,6 +274,8 @@ func performTx(tx *Transaction) (ret *TxErr) { ret = tx.doSortAttrViewView(op) case "updateAttrViewColRelation": ret = tx.doUpdateAttrViewColRelation(op) + case "updateAttrViewColRollup": + ret = tx.doUpdateAttrViewColRollup(op) } if nil != ret { From 0ce8b58a79283706ec4fec74dfded99b64b13d03 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sun, 24 Dec 2023 22:27:38 +0800 Subject: [PATCH 3/3] :art: Add Rollup column to database table view https://github.com/siyuan-note/siyuan/issues/9958 --- kernel/av/av.go | 24 +++++++++++ kernel/model/attribute_view.go | 75 ++++++++++++++++++++++++++++------ kernel/treenode/node.go | 24 +++++++++++ 3 files changed, 110 insertions(+), 13 deletions(-) diff --git a/kernel/av/av.go b/kernel/av/av.go index 348366ce6..c2999ca16 100644 --- a/kernel/av/av.go +++ b/kernel/av/av.go @@ -49,6 +49,16 @@ type KeyValues struct { Values []*Value `json:"values,omitempty"` // 属性视图属性列值 } +func (kValues *KeyValues) GetValue(blockID string) (ret *Value) { + for _, v := range kValues.Values { + if v.BlockID == blockID { + ret = v + return + } + } + return +} + type KeyType string const ( @@ -306,6 +316,20 @@ func (av *AttributeView) GetCurrentView() (ret *View, err error) { return } +func (av *AttributeView) GetValue(keyID, blockID string) (ret *Value) { + for _, kv := range av.KeyValues { + if kv.Key.ID == keyID { + for _, v := range kv.Values { + if v.BlockID == blockID { + ret = v + return + } + } + } + } + return +} + func (av *AttributeView) GetKey(keyID string) (ret *Key, err error) { for _, kv := range av.KeyValues { if kv.Key.ID == keyID { diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 581da4d3d..542131929 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -180,23 +180,48 @@ func GetBlockAttributeViewKeys(blockID string) (ret []*BlockAttributeViewKeys) { } // 渲染自动生成的列值,比如模板列、关联列、汇总列、创建时间列和更新时间列 - // 先处理创建时间和更新时间 + // 先处理关联列、汇总列、创建时间列和更新时间列 for _, kv := range keyValues { switch kv.Key.Type { - case av.KeyTypeRelation: - relKey, _ := attrView.GetKey(kv.Values[0].KeyID) - if nil != relKey && nil != relKey.Relation { - destAv, _ := av.ParseAttributeView(relKey.Relation.AvID) - if nil != destAv { - blocks := map[string]string{} - for _, blockValue := range destAv.GetBlockKeyValues().Values { - blocks[blockValue.BlockID] = blockValue.Block.Content - } - for _, blockID := range kv.Values[0].Relation.BlockIDs { - kv.Values[0].Relation.Contents = append(kv.Values[0].Relation.Contents, blocks[blockID]) - } + case av.KeyTypeRollup: + if nil == kv.Key.Rollup { + break + } + + relKey, _ := attrView.GetKey(kv.Key.Rollup.RelationKeyID) + if nil == relKey { + break + } + + var blockIDs []string + relVal := attrView.GetValue(kv.Key.Rollup.RelationKeyID, kv.Values[0].BlockID) + if nil != relVal && nil != relVal.Relation { + blockIDs = relVal.Relation.BlockIDs + } + + destAv, _ := av.ParseAttributeView(relKey.Relation.AvID) + if nil != destAv { + for _, bID := range blockIDs { + kv.Values[0].Rollup.Contents = append(kv.Values[0].Rollup.Contents, destAv.GetValue(kv.Key.Rollup.KeyID, bID).String()) } } + case av.KeyTypeRelation: + if nil == kv.Key.Relation { + break + } + + destAv, _ := av.ParseAttributeView(kv.Key.Relation.AvID) + if nil == destAv { + break + } + + blocks := map[string]string{} + for _, blockValue := range destAv.GetBlockKeyValues().Values { + blocks[blockValue.BlockID] = blockValue.Block.Content + } + for _, bID := range kv.Values[0].Relation.BlockIDs { + kv.Values[0].Relation.Contents = append(kv.Values[0].Relation.Contents, blocks[bID]) + } case av.KeyTypeCreated: createdStr := blockID[:len("20060102150405")] created, parseErr := time.ParseInLocation("20060102150405", createdStr, time.Local) @@ -699,6 +724,30 @@ func renderAttributeViewTable(attrView *av.AttributeView, view *av.View) (ret *a } content := renderTemplateCol(ial, cell.Value.Template.Content, keyValues) cell.Value.Template.Content = content + case av.KeyTypeRollup: // 渲染汇总列 + rollupKey, _ := attrView.GetKey(cell.Value.KeyID) + if nil == rollupKey || nil == rollupKey.Rollup { + break + } + + relKey, _ := attrView.GetKey(rollupKey.Rollup.RelationKeyID) + if nil == relKey || nil == relKey.Relation { + break + } + + relVal := attrView.GetValue(relKey.ID, row.ID) + if nil == relVal || nil == relVal.Relation { + break + } + + destAv, _ := av.ParseAttributeView(relKey.Relation.AvID) + if nil == destAv { + break + } + + for _, blockID := range relVal.Relation.BlockIDs { + cell.Value.Rollup.Contents = append(cell.Value.Rollup.Contents, destAv.GetValue(rollupKey.Rollup.KeyID, blockID).String()) + } case av.KeyTypeRelation: // 渲染关联列 relKey, _ := attrView.GetKey(cell.Value.KeyID) if nil != relKey && nil != relKey.Relation { diff --git a/kernel/treenode/node.go b/kernel/treenode/node.go index 7e80aa0e2..a316b82b3 100644 --- a/kernel/treenode/node.go +++ b/kernel/treenode/node.go @@ -723,6 +723,30 @@ func renderAttributeViewTable(attrView *av.AttributeView, view *av.View) (ret *a } content := renderTemplateCol(ial, cell.Value.Template.Content, keyValues) cell.Value.Template.Content = content + case av.KeyTypeRollup: // 渲染汇总列 + rollupKey, _ := attrView.GetKey(cell.Value.KeyID) + if nil == rollupKey || nil == rollupKey.Rollup { + break + } + + relKey, _ := attrView.GetKey(rollupKey.Rollup.RelationKeyID) + if nil == relKey || nil == relKey.Relation { + break + } + + relVal := attrView.GetValue(relKey.ID, row.ID) + if nil == relVal || nil == relVal.Relation { + break + } + + destAv, _ := av.ParseAttributeView(relKey.Relation.AvID) + if nil == destAv { + break + } + + for _, blockID := range relVal.Relation.BlockIDs { + cell.Value.Rollup.Contents = append(cell.Value.Rollup.Contents, destAv.GetValue(rollupKey.Rollup.KeyID, blockID).String()) + } case av.KeyTypeRelation: // 渲染关联列 relKey, _ := attrView.GetKey(cell.Value.KeyID) if nil != relKey && nil != relKey.Relation {