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:
parent
35bf9f57e7
commit
dbaf3e2b3c
3 changed files with 60 additions and 26 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
})
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue