1
0
Fork 0
mirror of https://github.com/anyproto/anytype-heart.git synced 2025-06-09 17:44:59 +09:00

database in/has filters: automatically wraps the non-list values

This commit is contained in:
Roman Khafizianov 2023-01-17 14:04:55 +01:00
parent 35bf9f57e7
commit dbaf3e2b3c
No known key found for this signature in database
GPG key ID: F07A7D55A2684852
3 changed files with 60 additions and 26 deletions

View file

@ -5,13 +5,14 @@ import (
"fmt"
"strings"
"github.com/gogo/protobuf/types"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
"github.com/anytypeio/go-anytype-middleware/util/pbtypes"
"github.com/gogo/protobuf/types"
)
var (
ErrValueMustBeList = errors.New("value must be list")
ErrValueMustBeListSupporting = errors.New("value must be list supporting")
)
func MakeAndFilter(protoFilters []*model.BlockContentDataviewFilter) (Filter, error) {
@ -78,18 +79,18 @@ func MakeFilter(proto *model.BlockContentDataviewFilter) (Filter, error) {
Value: proto.Value,
}}, nil
case model.BlockContentDataviewFilter_In:
list := proto.Value.GetListValue()
if list == nil {
return nil, ErrValueMustBeList
list, err := pbtypes.ValueListWrapper(proto.Value)
if err != nil {
return nil, ErrValueMustBeListSupporting
}
return In{
Key: proto.RelationKey,
Value: list,
}, nil
case model.BlockContentDataviewFilter_NotIn:
list := proto.Value.GetListValue()
if list == nil {
return nil, ErrValueMustBeList
list, err := pbtypes.ValueListWrapper(proto.Value)
if err != nil {
return nil, ErrValueMustBeListSupporting
}
return Not{In{
Key: proto.RelationKey,
@ -104,36 +105,36 @@ func MakeFilter(proto *model.BlockContentDataviewFilter) (Filter, error) {
Key: proto.RelationKey,
}}, nil
case model.BlockContentDataviewFilter_AllIn:
list := proto.Value.GetListValue()
if list == nil {
return nil, ErrValueMustBeList
list, err := pbtypes.ValueListWrapper(proto.Value)
if err != nil {
return nil, ErrValueMustBeListSupporting
}
return AllIn{
Key: proto.RelationKey,
Value: list,
}, nil
case model.BlockContentDataviewFilter_NotAllIn:
list := proto.Value.GetListValue()
if list == nil {
return nil, ErrValueMustBeList
list, err := pbtypes.ValueListWrapper(proto.Value)
if err != nil {
return nil, ErrValueMustBeListSupporting
}
return Not{AllIn{
Key: proto.RelationKey,
Value: list,
}}, nil
case model.BlockContentDataviewFilter_ExactIn:
list := proto.Value.GetListValue()
if list == nil {
return nil, ErrValueMustBeList
list, err := pbtypes.ValueListWrapper(proto.Value)
if err != nil {
return nil, ErrValueMustBeListSupporting
}
return ExactIn{
Key: proto.RelationKey,
Value: list,
}, nil
case model.BlockContentDataviewFilter_NotExactIn:
list := proto.Value.GetListValue()
if list == nil {
return nil, ErrValueMustBeList
list, err := pbtypes.ValueListWrapper(proto.Value)
if err != nil {
return nil, ErrValueMustBeListSupporting
}
return Not{ExactIn{
Key: proto.RelationKey,
@ -362,12 +363,16 @@ func (l AllIn) FilterObject(g Getter) bool {
if val == nil {
return false
}
list := val.GetListValue()
list, err := pbtypes.ValueListWrapper(val)
if err != nil {
return false
}
if list == nil {
return false
}
exist := func(v *types.Value) bool {
for _, lv := range list.Values {
for _, lv := range list.GetValues() {
if v.Equal(lv) {
return true
}

View file

@ -3,11 +3,12 @@ package filter
import (
"testing"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
"github.com/anytypeio/go-anytype-middleware/util/pbtypes"
"github.com/gogo/protobuf/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
"github.com/anytypeio/go-anytype-middleware/util/pbtypes"
)
type testGetter map[string]*types.Value
@ -227,6 +228,22 @@ func TestAllIn_FilterObject(t *testing.T) {
g := testGetter{"k": pbtypes.StringList([]string{"2", "3", "4"})}
assert.False(t, allIn.FilterObject(g))
})
t.Run("ok string in Object", func(t *testing.T) {
allIn := AllIn{Key: "k", Value: pbtypes.StringList([]string{"1"}).GetListValue()}
g := testGetter{"k": pbtypes.String("1")}
assert.True(t, allIn.FilterObject(g))
})
t.Run("ok string in Filter", func(t *testing.T) {
v, err := pbtypes.ValueListWrapper(pbtypes.String("1"))
assert.NoError(t, err)
allIn := AllIn{Key: "k", Value: v}
g := testGetter{"k": pbtypes.StringList([]string{"1", "2", "3"})}
assert.True(t, allIn.FilterObject(g))
})
}
func TestMakeAndFilter(t *testing.T) {
@ -313,9 +330,9 @@ func TestMakeAndFilter(t *testing.T) {
model.BlockContentDataviewFilter_NotAllIn,
} {
_, err := MakeAndFilter([]*model.BlockContentDataviewFilter{
{Condition: cond, Value: pbtypes.String("not list")},
{Condition: cond, Value: pbtypes.Null()},
})
assert.Equal(t, ErrValueMustBeList, err)
assert.Equal(t, ErrValueMustBeListSupporting, err)
}
})

View file

@ -428,3 +428,15 @@ func StructCompareIgnoreKeys(st1 *types.Struct, st2 *types.Struct, ignoreKeys []
}
return true
}
// ValueListWrapper wraps single value into the list. If value is already a list, it is returned as is.
// Null and struct values are not supported
func ValueListWrapper(value *types.Value) (*types.ListValue, error) {
switch v := value.Kind.(type) {
case *types.Value_ListValue:
return v.ListValue, nil
case *types.Value_StringValue, *types.Value_NumberValue, *types.Value_BoolValue:
return &types.ListValue{Values: []*types.Value{value}}, nil
}
return nil, fmt.Errorf("not supported type")
}