From b3325742171e0002f7180faf38a77ca9a42c4cb5 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Tue, 26 Aug 2025 10:38:26 +0800 Subject: [PATCH 1/2] :art: Improve av --- kernel/av/filter.go | 62 ++++++++++----------------------------------- kernel/av/value.go | 2 +- 2 files changed, 15 insertions(+), 49 deletions(-) diff --git a/kernel/av/filter.go b/kernel/av/filter.go index ab356297d..608139735 100644 --- a/kernel/av/filter.go +++ b/kernel/av/filter.go @@ -138,18 +138,17 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st return true } + switch filter.Operator { + case FilterOperatorIsEmpty: + return value.IsEmpty() + case FilterOperatorIsNotEmpty: + return !value.IsEmpty() + } + if nil != value.Rollup && KeyTypeRollup == value.Type && nil != filter.Value && KeyTypeRollup == filter.Value.Type && nil != filter.Value.Rollup && 0 < len(filter.Value.Rollup.Contents) { // 单独处理汇总类型的比较 - // 处理为空和不为空 - switch filter.Operator { - case FilterOperatorIsEmpty: - return 0 == len(value.Rollup.Contents) - case FilterOperatorIsNotEmpty: - return 0 != len(value.Rollup.Contents) - } - // 处理值比较 key, _ := attrView.GetKey(value.KeyID) if nil == key { @@ -215,14 +214,6 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st nil != filter.Value.Relation && 0 < len(filter.Value.Relation.BlockIDs) { // 单独处理关联类型的比较 - // 处理为空和不为空 - switch filter.Operator { - case FilterOperatorIsEmpty: - return 0 == len(value.Relation.Contents) - case FilterOperatorIsNotEmpty: - return 0 != len(value.Relation.Contents) - } - for _, relationValue := range value.Relation.Contents { filterValue := &Value{Type: KeyTypeBlock, Block: &ValueBlock{Content: filter.Value.Relation.BlockIDs[0]}} @@ -256,6 +247,13 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st } func (value *Value) filter(other *Value, relativeDate, relativeDate2 *RelativeDate, operator FilterOperator) bool { + switch operator { + case FilterOperatorIsEmpty: + return value.IsEmpty() + case FilterOperatorIsNotEmpty: + return !value.IsEmpty() + } + switch value.Type { case KeyTypeBlock: if nil != value.Block && nil != other && nil != other.Block { @@ -284,10 +282,6 @@ func (value *Value) filter(other *Value, relativeDate, relativeDate2 *RelativeDa return value.Number.Content < other.Number.Content case FilterOperatorIsLessOrEqual: return value.Number.Content <= other.Number.Content - case FilterOperatorIsEmpty: - return !value.Number.IsNotEmpty - case FilterOperatorIsNotEmpty: - return value.Number.IsNotEmpty } } case KeyTypeDate: @@ -298,13 +292,6 @@ func (value *Value) filter(other *Value, relativeDate, relativeDate2 *RelativeDa } if nil != value.Date { - switch operator { - case FilterOperatorIsEmpty: - return !value.Date.IsNotEmpty - case FilterOperatorIsNotEmpty: - return value.Date.IsNotEmpty - } - if !value.Date.IsNotEmpty { // 空值不进行比较,直接排除 // Database date filter excludes empty values https://github.com/siyuan-note/siyuan/issues/11061 @@ -352,12 +339,6 @@ func (value *Value) filter(other *Value, relativeDate, relativeDate2 *RelativeDa case KeyTypeSelect, KeyTypeMSelect: if nil != value.MSelect { if 1 > len(other.MSelect) { - switch operator { - case FilterOperatorIsEmpty: - return value.IsEmpty() - case FilterOperatorIsNotEmpty: - return !value.IsEmpty() - } return true } @@ -423,10 +404,6 @@ func (value *Value) filter(other *Value, relativeDate, relativeDate2 *RelativeDa } } return !contains - case FilterOperatorIsEmpty: - return 0 == len(value.MAsset) || 1 == len(value.MAsset) && "" == value.MAsset[0].Content - case FilterOperatorIsNotEmpty: - return 0 != len(value.MAsset) && !(1 == len(value.MAsset) && "" == value.MAsset[0].Content) } } case KeyTypeTemplate: @@ -482,10 +459,6 @@ func (value *Value) filter(other *Value, relativeDate, relativeDate2 *RelativeDa return true } return strings.HasSuffix(value.Template.Content, other.Template.Content) - case FilterOperatorIsEmpty: - return "" == strings.TrimSpace(value.Template.Content) - case FilterOperatorIsNotEmpty: - return "" != strings.TrimSpace(value.Template.Content) } } case KeyTypeCheckbox: @@ -498,13 +471,6 @@ func (value *Value) filter(other *Value, relativeDate, relativeDate2 *RelativeDa } } } - - switch operator { - case FilterOperatorIsEmpty: - return value.IsEmpty() - case FilterOperatorIsNotEmpty: - return !value.IsEmpty() - } return false } diff --git a/kernel/av/value.go b/kernel/av/value.go index 2be6b01f1..fe3aaed85 100644 --- a/kernel/av/value.go +++ b/kernel/av/value.go @@ -355,7 +355,7 @@ func (value *Value) IsEmpty() bool { if nil == value.Template { return true } - return "" == value.Template.Content + return "" == strings.TrimSpace(value.Template.Content) case KeyTypeCreated: if nil == value.Created { return true From 7b995fd16c67d8c3c3f61c4c948b5392e16d9a67 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Tue, 26 Aug 2025 10:46:41 +0800 Subject: [PATCH 2/2] :art: Improve `Add to Database` https://github.com/siyuan-note/siyuan/issues/10659 --- kernel/api/av.go | 6 +++++- kernel/model/attribute_view.go | 16 ++++++++++++---- kernel/model/file.go | 2 +- kernel/model/transaction.go | 5 +++-- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/kernel/api/av.go b/kernel/api/av.go index 63050ecf3..356aa98e0 100644 --- a/kernel/api/av.go +++ b/kernel/api/av.go @@ -331,6 +331,10 @@ func addAttributeViewBlocks(c *gin.Context) { if blockIDArg := arg["blockID"]; nil != blockIDArg { blockID = blockIDArg.(string) } + var viewID string + if viewIDArg := arg["viewID"]; nil != viewIDArg { + viewID = viewIDArg.(string) + } var groupID string if groupIDArg := arg["groupID"]; nil != groupIDArg { groupID = groupIDArg.(string) @@ -351,7 +355,7 @@ func addAttributeViewBlocks(c *gin.Context) { ignoreDefaultFill = arg["ignoreDefaultFill"].(bool) } - err := model.AddAttributeViewBlock(nil, srcs, avID, blockID, groupID, previousID, ignoreDefaultFill, map[string]interface{}{}) + err := model.AddAttributeViewBlock(nil, srcs, avID, blockID, viewID, groupID, previousID, ignoreDefaultFill, map[string]interface{}{}) if err != nil { ret.Code = -1 ret.Msg = err.Error() diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 4c9ed6132..c1c5c7e61 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -2964,14 +2964,14 @@ func (tx *Transaction) doInsertAttrViewBlock(operation *Operation) (ret *TxErr) operation.Context = map[string]interface{}{} } - err := AddAttributeViewBlock(tx, operation.Srcs, operation.AvID, operation.BlockID, operation.GroupID, operation.PreviousID, operation.IgnoreDefaultFill, operation.Context) + err := AddAttributeViewBlock(tx, operation.Srcs, operation.AvID, operation.BlockID, operation.ViewID, operation.GroupID, operation.PreviousID, operation.IgnoreDefaultFill, operation.Context) if err != nil { return &TxErr{code: TxErrHandleAttributeView, id: operation.AvID, msg: err.Error()} } return } -func AddAttributeViewBlock(tx *Transaction, srcs []map[string]interface{}, avID, dbBlockID, groupID, previousItemID string, ignoreDefaultFill bool, context map[string]interface{}) (err error) { +func AddAttributeViewBlock(tx *Transaction, srcs []map[string]interface{}, avID, dbBlockID, viewID, groupID, previousItemID string, ignoreDefaultFill bool, context map[string]interface{}) (err error) { slices.Reverse(srcs) // https://github.com/siyuan-note/siyuan/issues/11286 now := time.Now().UnixMilli() @@ -3006,14 +3006,14 @@ func AddAttributeViewBlock(tx *Transaction, srcs []map[string]interface{}, avID, if nil != src["content"] { srcContent = src["content"].(string) } - if avErr := addAttributeViewBlock(now, avID, dbBlockID, groupID, previousItemID, srcItemID, boundBlockID, srcContent, isDetached, ignoreDefaultFill, tree, tx, context); nil != avErr { + if avErr := addAttributeViewBlock(now, avID, dbBlockID, viewID, groupID, previousItemID, srcItemID, boundBlockID, srcContent, isDetached, ignoreDefaultFill, tree, tx, context); nil != avErr { return avErr } } return } -func addAttributeViewBlock(now int64, avID, dbBlockID, groupID, previousItemID, addingItemID, addingBoundBlockID, addingBlockContent string, isDetached, ignoreDefaultFill bool, tree *parse.Tree, tx *Transaction, context map[string]interface{}) (err error) { +func addAttributeViewBlock(now int64, avID, dbBlockID, viewID, groupID, previousItemID, addingItemID, addingBoundBlockID, addingBlockContent string, isDetached, ignoreDefaultFill bool, tree *parse.Tree, tx *Transaction, context map[string]interface{}) (err error) { var node *ast.Node if !isDetached { node = treenode.GetNodeInTree(tree, addingBoundBlockID) @@ -3085,6 +3085,14 @@ func addAttributeViewBlock(now int64, avID, dbBlockID, groupID, previousItemID, return } + if "" != viewID { + view = attrView.GetView(viewID) + if nil == view { + logging.LogErrorf("get view by view ID [%s] failed", viewID) + return av.ErrViewNotFound + } + } + groupView := view if "" != groupID { groupView = view.GetGroupByID(groupID) diff --git a/kernel/model/file.go b/kernel/model/file.go index cf429baf8..51dbaf4e3 100644 --- a/kernel/model/file.go +++ b/kernel/model/file.go @@ -991,7 +991,7 @@ func DuplicateDoc(tree *parse.Tree) { AddAttributeViewBlock(nil, []map[string]interface{}{{ "id": n.ID, "isDetached": false, - }}, avID, "", "", "", false, map[string]interface{}{}) + }}, avID, "", "", "", "", false, map[string]interface{}{}) ReloadAttrView(avID) } return ast.WalkContinue diff --git a/kernel/model/transaction.go b/kernel/model/transaction.go index 04bcf13ef..18ab0d7da 100644 --- a/kernel/model/transaction.go +++ b/kernel/model/transaction.go @@ -1099,7 +1099,7 @@ func (tx *Transaction) doLargeInsert(previousID string) (ret *TxErr) { AddAttributeViewBlock(tx, []map[string]interface{}{{ "id": insertedNode.ID, "isDetached": false, - }}, avID, "", "", previousID, false, map[string]interface{}{}) + }}, avID, "", "", "", previousID, false, map[string]interface{}{}) ReloadAttrView(avID) } @@ -1284,7 +1284,7 @@ func (tx *Transaction) doInsert(operation *Operation) (ret *TxErr) { AddAttributeViewBlock(tx, []map[string]interface{}{{ "id": insertedNode.ID, "isDetached": false, - }}, avID, "", "", previousID, false, map[string]interface{}{}) + }}, avID, "", "", "", previousID, false, map[string]interface{}{}) ReloadAttrView(avID) } @@ -1727,6 +1727,7 @@ type Operation struct { Layout av.LayoutType `json:"layout"` // 属性视图布局类型 GroupID string `json:"groupID"` // 属性视图分组视图 ID TargetGroupID string `json:"targetGroupID"` // 属性视图目标分组视图 ID + ViewID string `json:"viewID"` // 属性视图视图 ID IgnoreDefaultFill bool `json:"ignoreDefaultFill"` // 是否忽略默认填充 Context map[string]interface{} `json:"context"` // 上下文信息