mirror of
https://github.com/anyproto/anytype-heart.git
synced 2025-06-12 02:30:53 +09:00
GO-3273 Merge branch 'main' of github.com:anyproto/anytype-heart into go-3273-fix-history-protocol-and-implementation
This commit is contained in:
commit
02d9f662b5
16 changed files with 1650 additions and 653 deletions
|
@ -436,6 +436,9 @@ func validate(snapshot *pb.SnapshotWithType, info *useCaseInfo) (err error) {
|
|||
}
|
||||
|
||||
func insertAnalyticsData(s *pb.ChangeSnapshot, info *useCaseInfo) {
|
||||
if s == nil || s.Data == nil || len(s.Data.Blocks) == 0 {
|
||||
return
|
||||
}
|
||||
root := s.Data.Blocks[0]
|
||||
id := pbtypes.GetString(s.Data.Details, bundle.RelationKeyId.String())
|
||||
f := root.GetFields().GetFields()
|
||||
|
|
|
@ -101,7 +101,7 @@ func (s *Service) updateCollection(ctx session.Context, contextID string, modifi
|
|||
s.UpdateStoreSlice(template.CollectionStoreKey, lst)
|
||||
internalflag.Set{}.AddToState(s)
|
||||
return nil
|
||||
})
|
||||
}, smartblock.KeepInternalFlags)
|
||||
}
|
||||
|
||||
func (s *Service) collectionAddHookOnce(sb smartblock.SmartBlock) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/logging"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/internalflag"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
"github.com/anyproto/anytype-heart/util/slice"
|
||||
)
|
||||
|
@ -84,10 +85,15 @@ func (d *sdataview) SetSource(ctx session.Context, blockId string, source []stri
|
|||
return
|
||||
}
|
||||
|
||||
flags := internalflag.NewFromState(s)
|
||||
// set with source is no longer empty
|
||||
flags.Remove(model.InternalFlag_editorDeleteEmpty)
|
||||
flags.AddToState(s)
|
||||
|
||||
if len(source) == 0 {
|
||||
s.Unlink(blockId)
|
||||
s.SetLocalDetail(bundle.RelationKeySetOf.String(), pbtypes.StringList(source))
|
||||
return d.Apply(s, smartblock.NoRestrictions)
|
||||
return d.Apply(s, smartblock.NoRestrictions, smartblock.KeepInternalFlags)
|
||||
}
|
||||
|
||||
dvContent, err := BlockBySource(d.objectStore, source)
|
||||
|
@ -105,7 +111,7 @@ func (d *sdataview) SetSource(ctx session.Context, blockId string, source []stri
|
|||
}
|
||||
|
||||
s.SetLocalDetail(bundle.RelationKeySetOf.String(), pbtypes.StringList(source))
|
||||
return d.Apply(s, smartblock.NoRestrictions)
|
||||
return d.Apply(s, smartblock.NoRestrictions, smartblock.KeepInternalFlags)
|
||||
}
|
||||
|
||||
func (d *sdataview) AddRelations(ctx session.Context, blockId string, relationKeys []string, showEvent bool) error {
|
||||
|
|
|
@ -238,7 +238,7 @@ func (mw *Middleware) enrichWithDateSuggestion(ctx context.Context, records []da
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("make date record: %w", err)
|
||||
}
|
||||
f, _ := database.MakeFiltersAnd(req.Filters, store) //nolint:errcheck
|
||||
f, _ := database.MakeFilters(req.Filters, store) //nolint:errcheck
|
||||
if f.FilterObject(rec.Details) {
|
||||
return append([]database.Record{rec}, records...), nil
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@ import (
|
|||
mb2 "github.com/cheggaaa/mb/v3"
|
||||
"github.com/globalsign/mgo/bson"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"golang.org/x/exp/slices"
|
||||
"github.com/valyala/fastjson"
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
|
||||
|
@ -648,14 +648,11 @@ func (s *service) filtersFromSource(sources []string) (database.Filter, error) {
|
|||
}
|
||||
|
||||
if len(typeUniqueKeys) > 0 {
|
||||
nestedFiler, err := database.MakeFilter("",
|
||||
&model.BlockContentDataviewFilter{
|
||||
RelationKey: database.NestedRelationKey(bundle.RelationKeyType, bundle.RelationKeyUniqueKey),
|
||||
Condition: model.BlockContentDataviewFilter_In,
|
||||
Value: pbtypes.StringList(typeUniqueKeys),
|
||||
},
|
||||
s.objectStore,
|
||||
)
|
||||
nestedFiler, err := database.MakeFilter("", &model.BlockContentDataviewFilter{
|
||||
RelationKey: database.NestedRelationKey(bundle.RelationKeyType, bundle.RelationKeyUniqueKey),
|
||||
Condition: model.BlockContentDataviewFilter_In,
|
||||
Value: pbtypes.StringList(typeUniqueKeys),
|
||||
}, s.objectStore)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("make nested filter: %w", err)
|
||||
}
|
||||
|
|
|
@ -97,6 +97,209 @@ func TestService_Search(t *testing.T) {
|
|||
assert.NoError(t, fx.Unsubscribe("test"))
|
||||
assert.Len(t, fx.Service.(*service).cache.entries, 0)
|
||||
})
|
||||
t.Run("search with filters: one filter None", func(t *testing.T) {
|
||||
fx := newFixtureWithRealObjectStore(t)
|
||||
defer fx.a.Close(context.Background())
|
||||
defer fx.ctrl.Finish()
|
||||
source := "source"
|
||||
spaceID := "spaceId"
|
||||
relationKey := "key"
|
||||
option1 := "option1"
|
||||
option2 := "option2"
|
||||
|
||||
err := addTestObjects(t, source, relationKey, option1, option2, spaceID, fx)
|
||||
require.NoError(t, err)
|
||||
|
||||
resp, err := fx.Search(SubscribeRequest{
|
||||
Keys: []string{bundle.RelationKeyId.String()},
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: relationKey,
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String(option1),
|
||||
Format: model.RelationFormat_status,
|
||||
},
|
||||
},
|
||||
NoDepSubscription: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Len(t, resp.Records, 1)
|
||||
assert.Equal(t, "1", resp.Records[0].Fields[bundle.RelationKeyId.String()].GetStringValue())
|
||||
})
|
||||
t.Run("search with filters: linear structure with none filters", func(t *testing.T) {
|
||||
fx := newFixtureWithRealObjectStore(t)
|
||||
defer fx.a.Close(context.Background())
|
||||
defer fx.ctrl.Finish()
|
||||
source := "source"
|
||||
spaceID := "spaceId"
|
||||
relationKey := "key"
|
||||
option1 := "option1"
|
||||
option2 := "option2"
|
||||
|
||||
err := addTestObjects(t, source, relationKey, option1, option2, spaceID, fx)
|
||||
require.NoError(t, err)
|
||||
|
||||
resp, err := fx.Search(SubscribeRequest{
|
||||
Keys: []string{bundle.RelationKeyId.String()},
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: relationKey,
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String(option1),
|
||||
Format: model.RelationFormat_status,
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: relationKey,
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String(option2),
|
||||
Format: model.RelationFormat_status,
|
||||
},
|
||||
},
|
||||
NoDepSubscription: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, resp.Records, 0)
|
||||
})
|
||||
t.Run("search with filters: tree structure with And filter in root and None filters in NesterFilters", func(t *testing.T) {
|
||||
fx := newFixtureWithRealObjectStore(t)
|
||||
defer fx.a.Close(context.Background())
|
||||
defer fx.ctrl.Finish()
|
||||
source := "source"
|
||||
spaceID := "spaceId"
|
||||
relationKey := "key"
|
||||
option1 := "option1"
|
||||
option2 := "option2"
|
||||
|
||||
err := addTestObjects(t, source, relationKey, option1, option2, spaceID, fx)
|
||||
require.NoError(t, err)
|
||||
|
||||
resp, err := fx.Search(SubscribeRequest{
|
||||
Keys: []string{bundle.RelationKeyId.String()},
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_And,
|
||||
NestedFilters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: relationKey,
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String(option2),
|
||||
Format: model.RelationFormat_status,
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyName.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("Object 1"),
|
||||
Format: model.RelationFormat_shorttext,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
NoDepSubscription: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, resp.Records, 0)
|
||||
})
|
||||
t.Run("search with filters: tree structure with Or filter in root and None filters in NesterFilters", func(t *testing.T) {
|
||||
fx := newFixtureWithRealObjectStore(t)
|
||||
defer fx.a.Close(context.Background())
|
||||
defer fx.ctrl.Finish()
|
||||
source := "source"
|
||||
spaceID := "spaceId"
|
||||
relationKey := "key"
|
||||
option1 := "option1"
|
||||
option2 := "option2"
|
||||
|
||||
err := addTestObjects(t, source, relationKey, option1, option2, spaceID, fx)
|
||||
require.NoError(t, err)
|
||||
|
||||
resp, err := fx.Search(SubscribeRequest{
|
||||
Keys: []string{bundle.RelationKeyId.String()},
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_Or,
|
||||
NestedFilters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: relationKey,
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String(option2),
|
||||
Format: model.RelationFormat_status,
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyName.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("Object 1"),
|
||||
Format: model.RelationFormat_shorttext,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
NoDepSubscription: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, resp.Records, 2)
|
||||
assert.Equal(t, "1", resp.Records[0].Fields[bundle.RelationKeyId.String()].GetStringValue())
|
||||
assert.Equal(t, "2", resp.Records[1].Fields[bundle.RelationKeyId.String()].GetStringValue())
|
||||
})
|
||||
t.Run("search with filters: tree structure with And filter in root and combined filters as NestedFilter", func(t *testing.T) {
|
||||
fx := newFixtureWithRealObjectStore(t)
|
||||
defer fx.a.Close(context.Background())
|
||||
defer fx.ctrl.Finish()
|
||||
|
||||
spaceID := "spaceId"
|
||||
|
||||
option1 := "option1"
|
||||
option2 := "option2"
|
||||
option3 := "option3"
|
||||
|
||||
tag1 := "work"
|
||||
tag2 := "university"
|
||||
|
||||
addTestObjectsForNestedFilters(t, fx, spaceID, option1, option2, option3, tag1, tag2)
|
||||
|
||||
resp, err := fx.Search(SubscribeRequest{
|
||||
Keys: []string{bundle.RelationKeyId.String()},
|
||||
Filters: prepareNestedFiltersWithOperator(model.BlockContentDataviewFilter_And, option1, option2, tag1),
|
||||
NoDepSubscription: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, resp.Records, 1)
|
||||
assert.Equal(t, "1", resp.Records[0].Fields[bundle.RelationKeyId.String()].GetStringValue())
|
||||
})
|
||||
t.Run("search with filters: tree structure with Or filter in root and combined filters as NestedFilter", func(t *testing.T) {
|
||||
fx := newFixtureWithRealObjectStore(t)
|
||||
defer fx.a.Close(context.Background())
|
||||
defer fx.ctrl.Finish()
|
||||
|
||||
spaceID := "spaceId"
|
||||
|
||||
option1 := "option1"
|
||||
option2 := "option2"
|
||||
option3 := "option3"
|
||||
|
||||
tag1 := "work"
|
||||
tag2 := "university"
|
||||
|
||||
addTestObjectsForNestedFilters(t, fx, spaceID, option1, option2, option3, tag1, tag2)
|
||||
|
||||
resp, err := fx.Search(SubscribeRequest{
|
||||
Keys: []string{bundle.RelationKeyId.String()},
|
||||
Filters: prepareNestedFiltersWithOperator(model.BlockContentDataviewFilter_Or, option1, option2, tag1),
|
||||
NoDepSubscription: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, resp.Records, 3)
|
||||
assert.Equal(t, "1", resp.Records[0].Fields[bundle.RelationKeyId.String()].GetStringValue())
|
||||
assert.Equal(t, "2", resp.Records[1].Fields[bundle.RelationKeyId.String()].GetStringValue())
|
||||
assert.Equal(t, "3", resp.Records[2].Fields[bundle.RelationKeyId.String()].GetStringValue())
|
||||
})
|
||||
t.Run("cache ref counter", func(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
defer fx.a.Close(context.Background())
|
||||
|
@ -958,6 +1161,148 @@ func TestService_Search(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func addTestObjects(t *testing.T, source, relationKey, option1, option2, spaceID string, fx *fixtureRealStore) error {
|
||||
objectTypeKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeObjectType, source)
|
||||
assert.Nil(t, err)
|
||||
fx.store.AddObjects(t, []objectstore.TestObject{
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String("1"),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceID),
|
||||
domain.RelationKey(relationKey): pbtypes.String(option1),
|
||||
bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_basic)),
|
||||
bundle.RelationKeyName: pbtypes.String("Object 1"),
|
||||
bundle.RelationKeyType: pbtypes.String(objectTypeKey.Marshal()),
|
||||
},
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String("2"),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceID),
|
||||
domain.RelationKey(relationKey): pbtypes.String(option2),
|
||||
bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_basic)),
|
||||
bundle.RelationKeyName: pbtypes.String("Object 2"),
|
||||
bundle.RelationKeyType: pbtypes.String(objectTypeKey.Marshal()),
|
||||
},
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func addTestObjectsForNestedFilters(t *testing.T, fx *fixtureRealStore, spaceID, option1, option2, option3, tag1, tag2 string) {
|
||||
fx.store.AddObjects(t, []objectstore.TestObject{
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String("1"),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceID),
|
||||
bundle.RelationKeyStatus: pbtypes.String(option1),
|
||||
bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_basic)),
|
||||
bundle.RelationKeyName: pbtypes.String("Object 1"),
|
||||
bundle.RelationKeyType: pbtypes.String(bundle.TypeKeyPage.String()),
|
||||
bundle.RelationKeyTag: pbtypes.StringList([]string{tag1}),
|
||||
bundle.RelationKeyDueDate: pbtypes.Int64(1704070917),
|
||||
},
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String("2"),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceID),
|
||||
bundle.RelationKeyStatus: pbtypes.String(option3),
|
||||
bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_basic)),
|
||||
bundle.RelationKeyName: pbtypes.String("Object 2"),
|
||||
bundle.RelationKeyType: pbtypes.String(bundle.TypeKeyPage.String()),
|
||||
bundle.RelationKeyTag: pbtypes.StringList([]string{tag2}),
|
||||
bundle.RelationKeyDueDate: pbtypes.Int64(1709254917),
|
||||
},
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String("3"),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceID),
|
||||
bundle.RelationKeyStatus: pbtypes.String(option2),
|
||||
bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_basic)),
|
||||
bundle.RelationKeyName: pbtypes.String("Object 3"),
|
||||
bundle.RelationKeyType: pbtypes.String(bundle.TypeKeyPage.String()),
|
||||
bundle.RelationKeyTag: pbtypes.StringList([]string{tag1, tag2}),
|
||||
bundle.RelationKeyDueDate: pbtypes.Int64(1711933317),
|
||||
},
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String("4"),
|
||||
bundle.RelationKeySpaceId: pbtypes.String(spaceID),
|
||||
bundle.RelationKeyStatus: pbtypes.String(option1),
|
||||
bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_basic)),
|
||||
bundle.RelationKeyName: pbtypes.String("Object 4"),
|
||||
bundle.RelationKeyType: pbtypes.String(bundle.TypeKeyPage.String()),
|
||||
bundle.RelationKeyDueDate: pbtypes.Int64(1714525317),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func prepareNestedFiltersWithOperator(operator model.BlockContentDataviewFilterOperator, option1 string, option2 string, tag1 string) []*model.BlockContentDataviewFilter {
|
||||
return []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: operator,
|
||||
NestedFilters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_Or,
|
||||
NestedFilters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyName.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("Object 1"),
|
||||
Format: model.RelationFormat_shorttext,
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyName.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("Object 2"),
|
||||
Format: model.RelationFormat_shorttext,
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyName.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("Object 3"),
|
||||
Format: model.RelationFormat_shorttext,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_And,
|
||||
NestedFilters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyTag.String(),
|
||||
Condition: model.BlockContentDataviewFilter_In,
|
||||
Value: pbtypes.StringList([]string{tag1}),
|
||||
Format: model.RelationFormat_tag,
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_Or,
|
||||
NestedFilters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyStatus.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String(option1),
|
||||
Format: model.RelationFormat_shorttext,
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyName.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String(option2),
|
||||
Format: model.RelationFormat_shorttext,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyDueDate.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Less,
|
||||
Value: pbtypes.Int64(1709254917),
|
||||
Format: model.RelationFormat_shorttext,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func xTestNestedSubscription(t *testing.T) {
|
||||
t.Run("update nested object, so it's not satisfying filter anymore", func(t *testing.T) {
|
||||
fx := testCreateSubscriptionWithNestedFilter(t)
|
||||
|
|
|
@ -26340,6 +26340,7 @@ Bookmark is to keep a web-link and to preview a content.
|
|||
| quickOption | [Block.Content.Dataview.Filter.QuickOption](#anytype-model-Block-Content-Dataview-Filter-QuickOption) | | |
|
||||
| format | [RelationFormat](#anytype-model-RelationFormat) | | |
|
||||
| includeTime | [bool](#bool) | | |
|
||||
| nestedFilters | [Block.Content.Dataview.Filter](#anytype-model-Block-Content-Dataview-Filter) | repeated | |
|
||||
|
||||
|
||||
|
||||
|
@ -27816,8 +27817,9 @@ stored |
|
|||
|
||||
| Name | Number | Description |
|
||||
| ---- | ------ | ----------- |
|
||||
| And | 0 | |
|
||||
| No | 0 | |
|
||||
| Or | 1 | |
|
||||
| And | 2 | |
|
||||
|
||||
|
||||
|
||||
|
|
25
go.mod
25
go.mod
|
@ -57,7 +57,7 @@ require (
|
|||
github.com/joho/godotenv v1.5.1
|
||||
github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e
|
||||
github.com/kelseyhightower/envconfig v1.4.0
|
||||
github.com/klauspost/compress v1.17.8
|
||||
github.com/klauspost/compress v1.17.9
|
||||
github.com/libp2p/go-libp2p v0.35.1
|
||||
github.com/libp2p/zeroconf/v2 v2.2.0
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible
|
||||
|
@ -75,11 +75,11 @@ require (
|
|||
github.com/otiai10/copy v1.14.0
|
||||
github.com/otiai10/opengraph/v2 v2.1.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.19.1
|
||||
github.com/prometheus/client_golang v1.20.0
|
||||
github.com/pseudomuto/protoc-gen-doc v1.5.1
|
||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd
|
||||
github.com/samber/lo v1.46.0
|
||||
github.com/sasha-s/go-deadlock v0.3.1
|
||||
github.com/samber/lo v1.47.0
|
||||
github.com/sasha-s/go-deadlock v0.3.5
|
||||
github.com/shirou/gopsutil/v3 v3.24.4
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible
|
||||
|
@ -92,11 +92,11 @@ require (
|
|||
go.uber.org/multierr v1.11.0
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
|
||||
golang.org/x/image v0.18.0
|
||||
golang.org/x/image v0.19.0
|
||||
golang.org/x/mobile v0.0.0-20240520174638-fa72addaaa1b
|
||||
golang.org/x/net v0.27.0
|
||||
golang.org/x/oauth2 v0.21.0
|
||||
golang.org/x/text v0.16.0
|
||||
golang.org/x/oauth2 v0.22.0
|
||||
golang.org/x/text v0.17.0
|
||||
google.golang.org/grpc v1.65.0
|
||||
gopkg.in/Graylog2/go-gelf.v2 v2.0.0-20180125164251-1832d8546a9f
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
|
@ -216,16 +216,17 @@ require (
|
|||
github.com/multiformats/go-multicodec v0.9.0 // indirect
|
||||
github.com/multiformats/go-multistream v0.5.0 // indirect
|
||||
github.com/multiformats/go-varint v0.0.7 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/mwitkow/go-proto-validators v0.3.2 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.17.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
|
||||
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/polydawn/refmt v0.89.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.48.0 // indirect
|
||||
github.com/prometheus/procfs v0.12.0 // indirect
|
||||
github.com/prometheus/common v0.55.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/pseudomuto/protokit v0.2.1 // indirect
|
||||
github.com/quic-go/quic-go v0.44.0 // indirect
|
||||
github.com/rs/cors v1.7.0 // indirect
|
||||
|
@ -257,14 +258,14 @@ require (
|
|||
go.opentelemetry.io/otel/trace v1.14.0 // indirect
|
||||
golang.org/x/crypto v0.25.0 // indirect
|
||||
golang.org/x/mod v0.19.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.22.0 // indirect
|
||||
golang.org/x/term v0.22.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.23.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
lukechampine.com/blake3 v1.2.1 // indirect
|
||||
|
|
60
go.sum
60
go.sum
|
@ -83,8 +83,6 @@ github.com/andybalholm/cascadia v1.2.0/go.mod h1:YCyR8vOZT9aZ1CHEd8ap0gMVm2aFgxB
|
|||
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
|
||||
github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
|
||||
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
|
||||
github.com/anyproto/any-store v0.0.0-20240719163025-8a3657f8e01c h1:rRlF97BLA+4/jV82lMHEQGbNS4qgsed+HuoAJtYaLUM=
|
||||
github.com/anyproto/any-store v0.0.0-20240719163025-8a3657f8e01c/go.mod h1:JV7dJ8+xF1VaCQgFQsD8SZSNlxxTGFbDiF8llkB2ILc=
|
||||
github.com/anyproto/any-store v0.0.1 h1:RiZi3cHVSpIebcNeHYOUaDShH7E9Ahto33zdnqCaUHM=
|
||||
github.com/anyproto/any-store v0.0.1/go.mod h1:JV7dJ8+xF1VaCQgFQsD8SZSNlxxTGFbDiF8llkB2ILc=
|
||||
github.com/anyproto/any-sync v0.4.22 h1:f9iAbCv/clTzYtzOzkX1IOXahVM/Art1WkUtIgnwl8U=
|
||||
|
@ -758,8 +756,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
|
|||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
|
||||
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
|
@ -781,6 +779,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ=
|
||||
|
@ -1092,6 +1092,8 @@ github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS
|
|||
github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
||||
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
|
||||
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
|
@ -1156,8 +1158,8 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
|
|||
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
|
||||
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ=
|
||||
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
|
||||
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 h1:Dx7Ovyv/SFnMFw3fD4oEoeorXc6saIiQ23LrGLth0Gw=
|
||||
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
|
||||
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg=
|
||||
|
@ -1214,8 +1216,8 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf
|
|||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
|
||||
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
|
||||
github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI=
|
||||
github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
|
@ -1231,8 +1233,8 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
|
|||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
|
||||
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
|
||||
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
||||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
|
@ -1240,8 +1242,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
|
|||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
||||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/pseudomuto/protoc-gen-doc v1.5.1 h1:Ah259kcrio7Ix1Rhb6u8FCaOkzf9qRBqXnvAufg061w=
|
||||
github.com/pseudomuto/protoc-gen-doc v1.5.1/go.mod h1:XpMKYg6zkcpgfpCfQ8GcWBDRtRxOmMR5w7pz4Xo+dYM=
|
||||
|
@ -1270,11 +1272,11 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
|
|||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd h1:CmH9+J6ZSsIjUK3dcGsnCnO41eRBOnY12zwkn5qVwgc=
|
||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/samber/lo v1.46.0 h1:w8G+oaCPgz1PoCJztqymCFaKwXt+5cCXn51uPxExFfQ=
|
||||
github.com/samber/lo v1.46.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU=
|
||||
github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc=
|
||||
github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU=
|
||||
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0=
|
||||
github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM=
|
||||
github.com/sasha-s/go-deadlock v0.3.5 h1:tNCOEEDG6tBqrNDOX35j/7hL5FcFViG6awUGROb2NsU=
|
||||
github.com/sasha-s/go-deadlock v0.3.5/go.mod h1:bugP6EGbdGYObIlx7pUZtWqlvo8k9H6vCBBsiChJQ5U=
|
||||
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y=
|
||||
|
@ -1527,16 +1529,14 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
|
|||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
|
||||
golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
|
||||
golang.org/x/image v0.19.0 h1:D9FX4QWkLfkeqaC62SonffIIuYdOk/UE2XKUBgRIBIQ=
|
||||
golang.org/x/image v0.19.0/go.mod h1:y0zrRqlQRWQ5PXaYCOMLTW2fpsxZ8Qh9I/ohnInJEys=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
|
@ -1563,8 +1563,6 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
|
||||
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -1641,8 +1639,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
|
|||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
|
||||
golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
|
||||
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -1656,8 +1654,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -1773,8 +1771,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
|||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
@ -1843,8 +1841,6 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
|||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
|
||||
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
@ -1966,8 +1962,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
|
|||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
|
@ -35,13 +35,57 @@ type Query struct {
|
|||
}
|
||||
|
||||
func injectDefaultFilters(filters []*model.BlockContentDataviewFilter) []*model.BlockContentDataviewFilter {
|
||||
hasArchivedFilter, hasDeletedFilter, hasTypeFilter := hasDefaultFilters(filters)
|
||||
if len(filters) > 0 && len(filters[0].NestedFilters) > 0 {
|
||||
return addDefaultFiltersToNested(filters, hasArchivedFilter, hasDeletedFilter, hasTypeFilter)
|
||||
}
|
||||
return addDefaultFilters(filters, hasArchivedFilter, hasDeletedFilter, hasTypeFilter)
|
||||
}
|
||||
|
||||
func addDefaultFiltersToNested(filters []*model.BlockContentDataviewFilter, hasArchivedFilter, hasDeletedFilter, hasTypeFilter bool) []*model.BlockContentDataviewFilter {
|
||||
if filters[0].Operator == model.BlockContentDataviewFilter_And {
|
||||
filters[0].NestedFilters = addDefaultFilters(filters[0].NestedFilters, hasArchivedFilter, hasDeletedFilter, hasTypeFilter)
|
||||
}
|
||||
// build And filter based on original Or filter and default filters
|
||||
if filters[0].Operator != model.BlockContentDataviewFilter_And {
|
||||
filters = addDefaultFilters(filters, hasArchivedFilter, hasDeletedFilter, hasTypeFilter)
|
||||
return []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_And,
|
||||
NestedFilters: filters,
|
||||
},
|
||||
}
|
||||
}
|
||||
return filters
|
||||
}
|
||||
|
||||
func addDefaultFilters(filters []*model.BlockContentDataviewFilter, hasArchivedFilter, hasDeletedFilter, hasTypeFilter bool) []*model.BlockContentDataviewFilter {
|
||||
if !hasArchivedFilter {
|
||||
filters = append(filters, &model.BlockContentDataviewFilter{RelationKey: bundle.RelationKeyIsArchived.String(), Condition: model.BlockContentDataviewFilter_NotEqual, Value: pbtypes.Bool(true)})
|
||||
}
|
||||
if !hasDeletedFilter {
|
||||
filters = append(filters, &model.BlockContentDataviewFilter{RelationKey: bundle.RelationKeyIsDeleted.String(), Condition: model.BlockContentDataviewFilter_NotEqual, Value: pbtypes.Bool(true)})
|
||||
}
|
||||
if !hasTypeFilter {
|
||||
// temporarily exclude Space objects from search if we don't have explicit type filter
|
||||
filters = append(filters, &model.BlockContentDataviewFilter{RelationKey: bundle.RelationKeyType.String(), Condition: model.BlockContentDataviewFilter_NotIn, Value: pbtypes.Float64(float64(model.ObjectType_space))})
|
||||
}
|
||||
return filters
|
||||
}
|
||||
|
||||
func hasDefaultFilters(filters []*model.BlockContentDataviewFilter) (bool, bool, bool) {
|
||||
var (
|
||||
hasArchivedFilter bool
|
||||
hasDeletedFilter bool
|
||||
hasTypeFilter bool
|
||||
)
|
||||
|
||||
if len(filters) == 0 {
|
||||
return false, false, false
|
||||
}
|
||||
for _, filter := range filters {
|
||||
if len(filter.NestedFilters) > 0 {
|
||||
return hasDefaultFilters(filters[0].NestedFilters)
|
||||
}
|
||||
// include archived objects if we have explicit filter about it
|
||||
if filter.RelationKey == bundle.RelationKeyIsArchived.String() {
|
||||
hasArchivedFilter = true
|
||||
|
@ -55,18 +99,7 @@ func injectDefaultFilters(filters []*model.BlockContentDataviewFilter) []*model.
|
|||
hasDeletedFilter = true
|
||||
}
|
||||
}
|
||||
|
||||
if !hasArchivedFilter {
|
||||
filters = append(filters, &model.BlockContentDataviewFilter{RelationKey: bundle.RelationKeyIsArchived.String(), Condition: model.BlockContentDataviewFilter_NotEqual, Value: pbtypes.Bool(true)})
|
||||
}
|
||||
if !hasDeletedFilter {
|
||||
filters = append(filters, &model.BlockContentDataviewFilter{RelationKey: bundle.RelationKeyIsDeleted.String(), Condition: model.BlockContentDataviewFilter_NotEqual, Value: pbtypes.Bool(true)})
|
||||
}
|
||||
if !hasTypeFilter {
|
||||
// temporarily exclude Space objects from search if we don't have explicit type filter
|
||||
filters = append(filters, &model.BlockContentDataviewFilter{RelationKey: bundle.RelationKeyLayout.String(), Condition: model.BlockContentDataviewFilter_NotEqual, Value: pbtypes.Float64(float64(model.ObjectType_space))})
|
||||
}
|
||||
return filters
|
||||
return hasArchivedFilter, hasDeletedFilter, hasTypeFilter
|
||||
}
|
||||
|
||||
func injectDefaultOrder(qry Query, sorts []*model.BlockContentDataviewSort) []*model.BlockContentDataviewSort {
|
||||
|
@ -104,7 +137,7 @@ func NewFilters(qry Query, store ObjectStore, arena *fastjson.Arena) (filters *F
|
|||
objectStore: store,
|
||||
}
|
||||
|
||||
filterObj, err := MakeFiltersAnd(qry.Filters, store)
|
||||
filterObj, err := MakeFilters(qry.Filters, store)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
func TestDatabase(t *testing.T) {
|
||||
|
@ -136,3 +137,207 @@ func givenSingleIncludeTime() []*model.BlockContentDataviewSort {
|
|||
}
|
||||
return sorts
|
||||
}
|
||||
|
||||
func Test_NewFilters(t *testing.T) {
|
||||
t.Run("only default filters", func(t *testing.T) {
|
||||
// given
|
||||
mockStore := NewMockObjectStore(t)
|
||||
|
||||
// when
|
||||
filters, err := NewFilters(Query{}, mockStore, &fastjson.Arena{})
|
||||
|
||||
// then
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, filters.FilterObj, 3)
|
||||
})
|
||||
t.Run("and filter with 3 default", func(t *testing.T) {
|
||||
// given
|
||||
mockStore := NewMockObjectStore(t)
|
||||
filter := []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_And,
|
||||
NestedFilters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: "relationKey",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("option2"),
|
||||
Format: model.RelationFormat_status,
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyName.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("Object 1"),
|
||||
Format: model.RelationFormat_shorttext,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// when
|
||||
filters, err := NewFilters(Query{Filters: filter}, mockStore, &fastjson.Arena{})
|
||||
|
||||
// when
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, filters.FilterObj)
|
||||
assert.NotNil(t, filters.FilterObj.(FiltersAnd))
|
||||
assert.Len(t, filters.FilterObj.(FiltersAnd), 5)
|
||||
})
|
||||
t.Run("deleted filter", func(t *testing.T) {
|
||||
// given
|
||||
mockStore := NewMockObjectStore(t)
|
||||
filter := []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_And,
|
||||
NestedFilters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: "relationKey",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("option2"),
|
||||
Format: model.RelationFormat_status,
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyName.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("Object 1"),
|
||||
Format: model.RelationFormat_shorttext,
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyIsDeleted.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// then
|
||||
filters, err := NewFilters(Query{Filters: filter}, mockStore, &fastjson.Arena{})
|
||||
|
||||
// when
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, filters.FilterObj)
|
||||
assert.NotNil(t, filters.FilterObj.(FiltersAnd))
|
||||
assert.Len(t, filters.FilterObj.(FiltersAnd), 5)
|
||||
})
|
||||
t.Run("archived filter", func(t *testing.T) {
|
||||
// given
|
||||
mockStore := NewMockObjectStore(t)
|
||||
filter := []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_And,
|
||||
NestedFilters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: "relationKey",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("option2"),
|
||||
Format: model.RelationFormat_status,
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyName.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("Object 1"),
|
||||
Format: model.RelationFormat_shorttext,
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyIsArchived.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// then
|
||||
filters, err := NewFilters(Query{Filters: filter}, mockStore, &fastjson.Arena{})
|
||||
|
||||
// when
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, filters.FilterObj)
|
||||
assert.NotNil(t, filters.FilterObj.(FiltersAnd))
|
||||
assert.Len(t, filters.FilterObj.(FiltersAnd), 5)
|
||||
})
|
||||
t.Run("type filter", func(t *testing.T) {
|
||||
// given
|
||||
mockStore := NewMockObjectStore(t)
|
||||
filter := []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_And,
|
||||
NestedFilters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: "relationKey",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("option2"),
|
||||
Format: model.RelationFormat_status,
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyName.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("Object 1"),
|
||||
Format: model.RelationFormat_shorttext,
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyType.String(),
|
||||
Condition: model.BlockContentDataviewFilter_In,
|
||||
Value: pbtypes.Float64(float64(model.ObjectType_space)),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// then
|
||||
filters, err := NewFilters(Query{Filters: filter}, mockStore, &fastjson.Arena{})
|
||||
|
||||
// when
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, filters.FilterObj)
|
||||
assert.NotNil(t, filters.FilterObj.(FiltersAnd))
|
||||
assert.Len(t, filters.FilterObj.(FiltersAnd), 6)
|
||||
})
|
||||
t.Run("or filter with 3 default", func(t *testing.T) {
|
||||
// given
|
||||
mockStore := NewMockObjectStore(t)
|
||||
filter := []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_Or,
|
||||
NestedFilters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: "relationKey",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("option2"),
|
||||
Format: model.RelationFormat_status,
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyName.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("Object 1"),
|
||||
Format: model.RelationFormat_shorttext,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// then
|
||||
filters, err := NewFilters(Query{Filters: filter}, mockStore, &fastjson.Arena{})
|
||||
|
||||
// when
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, filters.FilterObj)
|
||||
assert.NotNil(t, filters.FilterObj.(FiltersAnd))
|
||||
assert.Len(t, filters.FilterObj.(FiltersAnd), 4)
|
||||
assert.NotNil(t, filters.FilterObj.(FiltersAnd)[0].(FiltersOr))
|
||||
assert.Len(t, filters.FilterObj.(FiltersAnd)[0].(FiltersOr), 2)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -23,34 +23,69 @@ var (
|
|||
ErrValueMustBeListSupporting = errors.New("value must be list supporting")
|
||||
)
|
||||
|
||||
func MakeFiltersAnd(protoFilters []*model.BlockContentDataviewFilter, store ObjectStore) (FiltersAnd, error) {
|
||||
if store == nil {
|
||||
return FiltersAnd{}, fmt.Errorf("objectStore dependency is nil")
|
||||
func MakeFilters(protoFilters []*model.BlockContentDataviewFilter, store ObjectStore) (Filter, error) {
|
||||
spaceId := getSpaceIDFromFilters(protoFilters)
|
||||
// to avoid unnecessary nested filter
|
||||
if len(protoFilters) == 1 && len(protoFilters[0].NestedFilters) > 0 && protoFilters[0].Operator != model.BlockContentDataviewFilter_No {
|
||||
return MakeFilter(spaceId, protoFilters[0], store)
|
||||
}
|
||||
spaceID := getSpaceIDFromFilters(protoFilters)
|
||||
protoFilters = TransformQuickOption(protoFilters, nil)
|
||||
return MakeFilter(spaceId, &model.BlockContentDataviewFilter{
|
||||
Operator: model.BlockContentDataviewFilter_And,
|
||||
NestedFilters: protoFilters,
|
||||
}, store)
|
||||
}
|
||||
|
||||
var and FiltersAnd
|
||||
for _, pf := range protoFilters {
|
||||
if pf.Condition != model.BlockContentDataviewFilter_None {
|
||||
f, err := MakeFilter(spaceID, pf, store)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
and = append(and, f)
|
||||
func MakeFilter(spaceId string, protoFilter *model.BlockContentDataviewFilter, store ObjectStore) (Filter, error) {
|
||||
if protoFilter.Operator == model.BlockContentDataviewFilter_No {
|
||||
return makeFilter(spaceId, protoFilter, store)
|
||||
}
|
||||
filters := make([]Filter, 0, len(protoFilter.NestedFilters))
|
||||
for _, nestedFilter := range protoFilter.NestedFilters {
|
||||
filter, err := MakeFilter(spaceId, nestedFilter, store)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if filter != nil {
|
||||
filters = append(filters, filter)
|
||||
}
|
||||
}
|
||||
return and, nil
|
||||
switch protoFilter.Operator {
|
||||
case model.BlockContentDataviewFilter_And, model.BlockContentDataviewFilter_No:
|
||||
return FiltersAnd(filters), nil
|
||||
case model.BlockContentDataviewFilter_Or:
|
||||
return FiltersOr(filters), nil
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported filter operator %v", protoFilter.Operator)
|
||||
}
|
||||
|
||||
func NestedRelationKey(baseRelationKey domain.RelationKey, nestedRelationKey domain.RelationKey) string {
|
||||
return fmt.Sprintf("%s.%s", baseRelationKey.String(), nestedRelationKey.String())
|
||||
}
|
||||
|
||||
func MakeFilter(spaceID string, rawFilter *model.BlockContentDataviewFilter, store ObjectStore) (Filter, error) {
|
||||
func makeFilter(spaceID string, rawFilter *model.BlockContentDataviewFilter, store ObjectStore) (Filter, error) {
|
||||
if store == nil {
|
||||
return nil, fmt.Errorf("objectStore dependency is nil")
|
||||
}
|
||||
if rawFilter.Condition == model.BlockContentDataviewFilter_None {
|
||||
return nil, nil
|
||||
}
|
||||
rawFilters := transformQuickOption(rawFilter, nil)
|
||||
|
||||
if len(rawFilters) == 1 {
|
||||
return makeFilterByCondition(spaceID, rawFilters[0], store)
|
||||
}
|
||||
resultFilters := FiltersAnd{}
|
||||
for _, filter := range rawFilters {
|
||||
filterByCondition, err := makeFilterByCondition(spaceID, filter, store)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resultFilters = append(resultFilters, filterByCondition)
|
||||
}
|
||||
return resultFilters, nil
|
||||
}
|
||||
|
||||
func makeFilterByCondition(spaceID string, rawFilter *model.BlockContentDataviewFilter, store ObjectStore) (Filter, error) {
|
||||
parts := strings.SplitN(rawFilter.RelationKey, ".", 2)
|
||||
if len(parts) == 2 {
|
||||
return makeFilterNestedIn(spaceID, rawFilter, store, parts[0], parts[1])
|
||||
|
|
|
@ -2,6 +2,7 @@ package database
|
|||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/anyproto/any-store/query"
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
@ -366,7 +367,7 @@ func TestMakeAndFilter(t *testing.T) {
|
|||
Value: pbtypes.StringList([]string{"14"}),
|
||||
},
|
||||
}
|
||||
andFilter, err := MakeFiltersAnd(filters, store)
|
||||
andFilter, err := MakeFilters(filters, store)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, andFilter, 14)
|
||||
})
|
||||
|
@ -377,7 +378,7 @@ func TestMakeAndFilter(t *testing.T) {
|
|||
model.BlockContentDataviewFilter_AllIn,
|
||||
model.BlockContentDataviewFilter_NotAllIn,
|
||||
} {
|
||||
_, err := MakeFiltersAnd([]*model.BlockContentDataviewFilter{
|
||||
_, err := MakeFilters([]*model.BlockContentDataviewFilter{
|
||||
{Condition: cond, Value: pbtypes.Null()},
|
||||
}, store)
|
||||
assert.Equal(t, ErrValueMustBeListSupporting, err)
|
||||
|
@ -385,13 +386,13 @@ func TestMakeAndFilter(t *testing.T) {
|
|||
|
||||
})
|
||||
t.Run("unexpected condition", func(t *testing.T) {
|
||||
_, err := MakeFiltersAnd([]*model.BlockContentDataviewFilter{
|
||||
_, err := MakeFilters([]*model.BlockContentDataviewFilter{
|
||||
{Condition: 10000},
|
||||
}, store)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
t.Run("replace 'value == false' to 'value != true'", func(t *testing.T) {
|
||||
f, err := MakeFiltersAnd([]*model.BlockContentDataviewFilter{
|
||||
f, err := MakeFilters([]*model.BlockContentDataviewFilter{
|
||||
{
|
||||
RelationKey: "b",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
|
@ -410,7 +411,7 @@ func TestMakeAndFilter(t *testing.T) {
|
|||
assertFilter(t, f, g, false)
|
||||
})
|
||||
t.Run("replace 'value != false' to 'value == true'", func(t *testing.T) {
|
||||
f, err := MakeFiltersAnd([]*model.BlockContentDataviewFilter{
|
||||
f, err := MakeFilters([]*model.BlockContentDataviewFilter{
|
||||
{
|
||||
RelationKey: "b",
|
||||
Condition: model.BlockContentDataviewFilter_NotEqual,
|
||||
|
@ -453,7 +454,7 @@ func TestNestedFilters(t *testing.T) {
|
|||
},
|
||||
}, nil)
|
||||
|
||||
f, err := MakeFilter("", &model.BlockContentDataviewFilter{
|
||||
f, err := MakeFilter("spaceId", &model.BlockContentDataviewFilter{
|
||||
RelationKey: "type.typeKey",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("note"),
|
||||
|
@ -542,3 +543,315 @@ func TestFilterOptionsEqual(t *testing.T) {
|
|||
assertFilter(t, eq, obj, false)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMakeFilters(t *testing.T) {
|
||||
t.Run("no filters", func(t *testing.T) {
|
||||
// given
|
||||
mockStore := NewMockObjectStore(t)
|
||||
|
||||
// when
|
||||
filters, err := MakeFilters(nil, mockStore)
|
||||
|
||||
// then
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, filters, 0)
|
||||
})
|
||||
t.Run("or filter", func(t *testing.T) {
|
||||
// given
|
||||
mockStore := NewMockObjectStore(t)
|
||||
filter := []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_Or,
|
||||
NestedFilters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: "relationKey",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("option2"),
|
||||
Format: model.RelationFormat_status,
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyName.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("Object 1"),
|
||||
Format: model.RelationFormat_shorttext,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// when
|
||||
filters, err := MakeFilters(filter, mockStore)
|
||||
|
||||
// then
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, filters, 2)
|
||||
assert.NotNil(t, filters.(FiltersOr))
|
||||
assert.NotNil(t, filters.(FiltersOr)[0].(FilterEq))
|
||||
assert.NotNil(t, filters.(FiltersOr)[1].(FilterEq))
|
||||
assert.Equal(t, "relationKey", filters.(FiltersOr)[0].(FilterEq).Key)
|
||||
assert.Equal(t, pbtypes.String("option2"), filters.(FiltersOr)[0].(FilterEq).Value)
|
||||
assert.Equal(t, "name", filters.(FiltersOr)[1].(FilterEq).Key)
|
||||
assert.Equal(t, pbtypes.String("Object 1"), filters.(FiltersOr)[1].(FilterEq).Value)
|
||||
})
|
||||
t.Run("and filter", func(t *testing.T) {
|
||||
// given
|
||||
mockStore := NewMockObjectStore(t)
|
||||
filter := []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_And,
|
||||
NestedFilters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: "relationKey",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("option2"),
|
||||
Format: model.RelationFormat_status,
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: bundle.RelationKeyName.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("Object 1"),
|
||||
Format: model.RelationFormat_shorttext,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// when
|
||||
filters, err := MakeFilters(filter, mockStore)
|
||||
|
||||
// then
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, filters, 2)
|
||||
assert.NotNil(t, filters.(FiltersAnd))
|
||||
assert.NotNil(t, filters.(FiltersAnd)[0].(FilterEq))
|
||||
assert.NotNil(t, filters.(FiltersAnd)[1].(FilterEq))
|
||||
assert.Equal(t, "relationKey", filters.(FiltersAnd)[0].(FilterEq).Key)
|
||||
assert.Equal(t, pbtypes.String("option2"), filters.(FiltersAnd)[0].(FilterEq).Value)
|
||||
assert.Equal(t, "name", filters.(FiltersAnd)[1].(FilterEq).Key)
|
||||
assert.Equal(t, pbtypes.String("Object 1"), filters.(FiltersAnd)[1].(FilterEq).Value)
|
||||
})
|
||||
t.Run("none filter", func(t *testing.T) {
|
||||
// given
|
||||
mockStore := NewMockObjectStore(t)
|
||||
filter := []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: "relationKey",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("option1"),
|
||||
Format: model.RelationFormat_status,
|
||||
},
|
||||
}
|
||||
|
||||
// when
|
||||
filters, err := MakeFilters(filter, mockStore)
|
||||
|
||||
// then
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, filters, 1)
|
||||
assert.NotNil(t, filters.(FiltersAnd))
|
||||
assert.NotNil(t, filters.(FiltersAnd)[0].(FilterEq))
|
||||
assert.Equal(t, "relationKey", filters.(FiltersAnd)[0].(FilterEq).Key)
|
||||
assert.Equal(t, pbtypes.String("option1"), filters.(FiltersAnd)[0].(FilterEq).Value)
|
||||
})
|
||||
t.Run("combined filter", func(t *testing.T) {
|
||||
// given
|
||||
mockStore := NewMockObjectStore(t)
|
||||
filter := []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_And,
|
||||
NestedFilters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_Or,
|
||||
NestedFilters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: "relationKey",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("option1"),
|
||||
Format: model.RelationFormat_status,
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: "relationKey1",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("option2"),
|
||||
Format: model.RelationFormat_status,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_No,
|
||||
RelationKey: "relationKey3",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.String("option3"),
|
||||
Format: model.RelationFormat_status,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// when
|
||||
filters, err := MakeFilters(filter, mockStore)
|
||||
|
||||
// then
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, filters, 2)
|
||||
assert.NotNil(t, filters.(FiltersAnd))
|
||||
assert.NotNil(t, filters.(FiltersAnd)[0].(FiltersOr))
|
||||
assert.NotNil(t, filters.(FiltersAnd)[1].(FilterEq))
|
||||
})
|
||||
t.Run("linear and nested filters", func(t *testing.T) {
|
||||
// given
|
||||
mockStore := NewMockObjectStore(t)
|
||||
filter := []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
RelationKey: "key1",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Bool(true),
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_Or,
|
||||
NestedFilters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
RelationKey: "key2",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// when
|
||||
filters, err := MakeFilters(filter, mockStore)
|
||||
|
||||
// then
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, filters, 2)
|
||||
assert.NotNil(t, filters.(FiltersAnd))
|
||||
assert.NotNil(t, filters.(FiltersAnd)[0].(FilterEq))
|
||||
assert.NotNil(t, filters.(FiltersAnd)[1].(FiltersOr))
|
||||
})
|
||||
t.Run("linear and nested filters", func(t *testing.T) {
|
||||
// given
|
||||
mockStore := NewMockObjectStore(t)
|
||||
filter := []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_And,
|
||||
RelationKey: "key1",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Bool(true),
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_And,
|
||||
RelationKey: "key1",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Bool(true),
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_And,
|
||||
RelationKey: "key1",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Bool(true),
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_And,
|
||||
RelationKey: "key1",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Bool(true),
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_And,
|
||||
RelationKey: "key1",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Bool(true),
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_And,
|
||||
RelationKey: "key1",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Bool(true),
|
||||
},
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_And,
|
||||
RelationKey: "key1",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Bool(true),
|
||||
},
|
||||
}
|
||||
|
||||
// when
|
||||
_, err := MakeFilters(filter, mockStore)
|
||||
|
||||
// then
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
t.Run("transform quick options", func(t *testing.T) {
|
||||
// given
|
||||
mockStore := NewMockObjectStore(t)
|
||||
filter := []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_Or,
|
||||
NestedFilters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
RelationKey: "key2",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Int64(time.Now().Unix()),
|
||||
QuickOption: model.BlockContentDataviewFilter_CurrentMonth,
|
||||
},
|
||||
{
|
||||
RelationKey: "key3",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// when
|
||||
filters, err := MakeFilters(filter, mockStore)
|
||||
|
||||
// then
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, filters, 2)
|
||||
assert.NotNil(t, filters.(FiltersOr))
|
||||
assert.NotNil(t, filters.(FiltersOr)[0].(FiltersAnd))
|
||||
assert.NotNil(t, filters.(FiltersOr)[1].(FilterEq))
|
||||
})
|
||||
t.Run("transform quick options", func(t *testing.T) {
|
||||
// given
|
||||
mockStore := NewMockObjectStore(t)
|
||||
filter := []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
Operator: model.BlockContentDataviewFilter_Or,
|
||||
NestedFilters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
RelationKey: "key2",
|
||||
Condition: model.BlockContentDataviewFilter_Less,
|
||||
Value: pbtypes.Int64(time.Now().Unix()),
|
||||
QuickOption: model.BlockContentDataviewFilter_CurrentMonth,
|
||||
},
|
||||
{
|
||||
RelationKey: "key3",
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// when
|
||||
filters, err := MakeFilters(filter, mockStore)
|
||||
|
||||
// then
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, filters, 2)
|
||||
assert.NotNil(t, filters.(FiltersOr))
|
||||
assert.NotNil(t, filters.(FiltersOr)[0].(FilterEq))
|
||||
assert.NotNil(t, filters.(FiltersOr)[1].(FilterEq))
|
||||
})
|
||||
}
|
||||
|
|
|
@ -8,50 +8,43 @@ import (
|
|||
timeutil "github.com/anyproto/anytype-heart/util/time"
|
||||
)
|
||||
|
||||
func TransformQuickOption(protoFilters []*model.BlockContentDataviewFilter, loc *time.Location) []*model.BlockContentDataviewFilter {
|
||||
if protoFilters == nil {
|
||||
func transformQuickOption(protoFilter *model.BlockContentDataviewFilter, loc *time.Location) []*model.BlockContentDataviewFilter {
|
||||
if protoFilter == nil {
|
||||
return nil
|
||||
}
|
||||
var filters []*model.BlockContentDataviewFilter
|
||||
filters = append(filters, protoFilter)
|
||||
if protoFilter.QuickOption > model.BlockContentDataviewFilter_ExactDate || protoFilter.Format == model.RelationFormat_date {
|
||||
d1, d2 := getRange(protoFilter, loc)
|
||||
switch protoFilter.Condition {
|
||||
case model.BlockContentDataviewFilter_Equal:
|
||||
protoFilter.Condition = model.BlockContentDataviewFilter_GreaterOrEqual
|
||||
protoFilter.Value = pbtypes.ToValue(d1)
|
||||
|
||||
filters := make([]*model.BlockContentDataviewFilter, len(protoFilters))
|
||||
for i, f := range protoFilters {
|
||||
filters[i] = pbtypes.CopyFilter(f)
|
||||
}
|
||||
filters = append(filters, &model.BlockContentDataviewFilter{
|
||||
RelationKey: protoFilter.RelationKey,
|
||||
Condition: model.BlockContentDataviewFilter_LessOrEqual,
|
||||
Value: pbtypes.ToValue(d2),
|
||||
})
|
||||
case model.BlockContentDataviewFilter_Less:
|
||||
protoFilter.Value = pbtypes.ToValue(d1)
|
||||
case model.BlockContentDataviewFilter_Greater:
|
||||
protoFilter.Value = pbtypes.ToValue(d2)
|
||||
case model.BlockContentDataviewFilter_LessOrEqual:
|
||||
protoFilter.Value = pbtypes.ToValue(d2)
|
||||
case model.BlockContentDataviewFilter_GreaterOrEqual:
|
||||
protoFilter.Value = pbtypes.ToValue(d1)
|
||||
case model.BlockContentDataviewFilter_In:
|
||||
protoFilter.Condition = model.BlockContentDataviewFilter_GreaterOrEqual
|
||||
protoFilter.Value = pbtypes.ToValue(d1)
|
||||
|
||||
for _, f := range filters {
|
||||
if f.QuickOption > model.BlockContentDataviewFilter_ExactDate || f.Format == model.RelationFormat_date {
|
||||
d1, d2 := getRange(f, loc)
|
||||
switch f.Condition {
|
||||
case model.BlockContentDataviewFilter_Equal:
|
||||
f.Condition = model.BlockContentDataviewFilter_GreaterOrEqual
|
||||
f.Value = pbtypes.ToValue(d1)
|
||||
|
||||
filters = append(filters, &model.BlockContentDataviewFilter{
|
||||
RelationKey: f.RelationKey,
|
||||
Condition: model.BlockContentDataviewFilter_LessOrEqual,
|
||||
Value: pbtypes.ToValue(d2),
|
||||
})
|
||||
case model.BlockContentDataviewFilter_Less:
|
||||
f.Value = pbtypes.ToValue(d1)
|
||||
case model.BlockContentDataviewFilter_Greater:
|
||||
f.Value = pbtypes.ToValue(d2)
|
||||
case model.BlockContentDataviewFilter_LessOrEqual:
|
||||
f.Value = pbtypes.ToValue(d2)
|
||||
case model.BlockContentDataviewFilter_GreaterOrEqual:
|
||||
f.Value = pbtypes.ToValue(d1)
|
||||
case model.BlockContentDataviewFilter_In:
|
||||
f.Condition = model.BlockContentDataviewFilter_GreaterOrEqual
|
||||
f.Value = pbtypes.ToValue(d1)
|
||||
|
||||
filters = append(filters, &model.BlockContentDataviewFilter{
|
||||
RelationKey: f.RelationKey,
|
||||
Condition: model.BlockContentDataviewFilter_LessOrEqual,
|
||||
Value: pbtypes.ToValue(d2),
|
||||
})
|
||||
}
|
||||
filters = append(filters, &model.BlockContentDataviewFilter{
|
||||
RelationKey: protoFilter.RelationKey,
|
||||
Condition: model.BlockContentDataviewFilter_LessOrEqual,
|
||||
Value: pbtypes.ToValue(d2),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return filters
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -432,10 +432,12 @@ message Block {
|
|||
QuickOption quickOption = 6;
|
||||
RelationFormat format = 7;
|
||||
bool includeTime = 8;
|
||||
repeated Filter nestedFilters = 10;
|
||||
|
||||
enum Operator {
|
||||
And = 0;
|
||||
No = 0;
|
||||
Or = 1;
|
||||
And = 2;
|
||||
}
|
||||
|
||||
enum Condition {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue