1
0
Fork 0
mirror of https://github.com/anyproto/anytype-heart.git synced 2025-06-08 05:47:07 +09:00

GO-4144 Merge branch 'main' of github.com:anyproto/anytype-heart into go-4144-refactor-internal-details-structure

# Conflicts:
#	core/block/backlinks/watcher.go
#	core/block/bookmark/bookmarkimporter/bookmark_importer_decorator.go
#	core/block/detailservice/mock_detailservice/mock_Service.go
#	core/block/detailservice/relations.go
#	core/block/detailservice/relations_test.go
#	core/block/detailservice/service.go
#	core/block/detailservice/set_details.go
#	core/block/editor/collection/collection.go
#	core/block/editor/dashboard.go
#	core/block/import/importer.go
#	core/block/import/importer_test.go
#	core/block/import/types.go
#	core/block/object/objectcreator/creator_test.go
#	core/block/object/objectlink/dependent_objects.go
#	core/block/source/date.go
#	core/object.go
#	core/relations.go
#	pkg/lib/database/database.go
#	pkg/lib/database/filter.go
#	pkg/lib/database/filter_test.go
#	pkg/lib/localstore/objectstore/spaceindex/queries.go
#	pkg/lib/localstore/objectstore/spaceindex/queries_test.go
This commit is contained in:
Sergey 2024-11-20 18:10:31 +01:00
commit e34cef28ca
No known key found for this signature in database
GPG key ID: 3B6BEF79160221C6
121 changed files with 7814 additions and 5186 deletions

View file

@ -6,7 +6,6 @@ import (
"github.com/anyproto/anytype-heart/core/domain"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
"github.com/anyproto/anytype-heart/pkg/lib/localstore/ftsearch"
"github.com/anyproto/anytype-heart/pkg/lib/logging"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
)
@ -66,10 +65,9 @@ type SortRequest struct {
}
type Query struct {
FullText string
SpaceId string
Highlighter ftsearch.HighlightFormatter // default is json
Filters []FilterRequest // filters results. apply sequentially
TextQuery string
SpaceId string
Filters []FilterRequest // filters results. apply sequentially
Sorts []SortRequest // order results. apply hierarchically
Limit int // maximum number of results
Offset int // skip given number of results
@ -159,7 +157,7 @@ func injectDefaultOrder(qry Query, sorts []SortRequest) []SortRequest {
var (
hasScoreSort bool
)
if qry.FullText == "" {
if qry.TextQuery == "" {
return sorts
}

View file

@ -15,6 +15,9 @@ 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/dateutil"
"github.com/anyproto/anytype-heart/util/pbtypes"
"github.com/anyproto/anytype-heart/util/slice"
)
var (
@ -153,6 +156,14 @@ func makeFilterByCondition(spaceID string, rawFilter FilterRequest, store Object
Value: rawFilter.Value.String(),
}}, nil
case model.BlockContentDataviewFilter_In:
// hack for queries for relations containing date objects ids with format _date_YYYY-MM-DD-hh-mm-ss
// to find all date object ids of the same day we search by prefix _date_YYYY-MM-DD
if ts, err := dateutil.ParseDateId(rawFilter.Value.GetStringValue()); err == nil {
return FilterHasPrefix{
Key: rawFilter.RelationKey,
Prefix: dateutil.TimeToDateId(ts),
}, nil
}
list, err := rawFilter.Value.TryWrapToList()
if err != nil {
return nil, errors.Join(ErrValueMustBeListSupporting, err)
@ -456,6 +467,40 @@ func (e FilterEq) filterObject(v domain.Value) bool {
return false
}
type FilterHasPrefix struct {
Key, Prefix string
}
func (p FilterHasPrefix) FilterObject(s *types.Struct) bool {
val := pbtypes.Get(s, p.Key)
if strings.HasPrefix(val.GetStringValue(), p.Prefix) {
return true
}
list := val.GetListValue()
if list == nil {
return false
}
for _, v := range list.Values {
if strings.HasPrefix(v.GetStringValue(), p.Prefix) {
return true
}
}
return false
}
func (p FilterHasPrefix) AnystoreFilter() query.Filter {
re, err := regexp.Compile("^" + regexp.QuoteMeta(p.Prefix))
if err != nil {
log.Errorf("failed to build anystore HAS PREFIX filter: %v", err)
}
return query.Key{
Path: []string{p.Key},
Filter: query.Regexp{Regexp: re},
}
}
// any
type FilterIn struct {
Key domain.RelationKey
@ -536,14 +581,7 @@ func (e FilterEmpty) FilterObject(g *domain.Details) bool {
}
var (
filterEqNil = query.NewComp(query.CompOpEq, nil)
filterEqEmptyString = query.NewComp(query.CompOpEq, "")
filterEq0 = query.NewComp(query.CompOpEq, 0)
filterEqFalse = query.NewComp(query.CompOpEq, false)
filterEqEmptyArray = &query.Comp{
CompOp: query.CompOpEq,
EqValue: anyenc.MustParseJson(`[]`).MarshalTo(nil),
}
emptyArrayValue = anyenc.MustParseJson(`[]`).MarshalTo(nil)
)
func (e FilterEmpty) AnystoreFilter() query.Filter {
@ -555,23 +593,26 @@ func (e FilterEmpty) AnystoreFilter() query.Filter {
},
query.Key{
Path: path,
Filter: filterEqNil,
Filter: query.NewComp(query.CompOpEq, nil),
},
query.Key{
Path: path,
Filter: filterEqEmptyString,
Filter: query.NewComp(query.CompOpEq, ""),
},
query.Key{
Path: path,
Filter: filterEq0,
Filter: query.NewComp(query.CompOpEq, 0),
},
query.Key{
Path: path,
Filter: filterEqFalse,
Filter: query.NewComp(query.CompOpEq, false),
},
query.Key{
Path: path,
Filter: filterEqEmptyArray,
Path: path,
Filter: &query.Comp{
CompOp: query.CompOpEq,
EqValue: emptyArrayValue,
},
},
}
}

View file

@ -11,6 +11,8 @@ 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/dateutil"
"github.com/anyproto/anytype-heart/util/pbtypes"
)
func assertFilter(t *testing.T, f Filter, obj *domain.Details, expected bool) {
@ -919,3 +921,66 @@ func TestFilter2ValuesComp_FilterObject(t *testing.T) {
assertFilter(t, eq, obj3, true)
})
}
func TestFilterHasPrefix_FilterObject(t *testing.T) {
t.Run("date object id", func(t *testing.T) {
key := bundle.RelationKeyMentions.String()
now := time.Now()
f := FilterHasPrefix{
Key: key,
Prefix: dateutil.TimeToDateId(now), // _date_YYYY-MM-DD
}
obj1 := &types.Struct{Fields: map[string]*types.Value{
key: pbtypes.StringList([]string{"obj2", dateutil.TimeToDateId(now.Add(30 * time.Minute)), "obj3"}), // _date_YYYY-MM-DD-hh-mm-ss
}}
obj2 := &types.Struct{Fields: map[string]*types.Value{
key: pbtypes.StringList([]string{dateutil.TimeToDateId(now.Add(24 * time.Hour)), "obj1", "obj3"}), // same format, but next day
}}
obj3 := &types.Struct{Fields: map[string]*types.Value{
key: pbtypes.StringList([]string{"obj2", "obj3", dateutil.TimeToDateId(now.Add(30 * time.Minute))}), // _date_YYYY-MM-DD
}}
assertFilter(t, f, obj1, true)
assertFilter(t, f, obj2, false)
assertFilter(t, f, obj3, true)
})
t.Run("string", func(t *testing.T) {
key := bundle.RelationKeyName.String()
f := FilterHasPrefix{
Key: key,
Prefix: "Let's",
}
obj1 := &types.Struct{Fields: map[string]*types.Value{
key: pbtypes.String("Let's do it"),
}}
obj2 := &types.Struct{Fields: map[string]*types.Value{
key: pbtypes.String("Lets do it"),
}}
obj3 := &types.Struct{Fields: map[string]*types.Value{
key: pbtypes.String("Let's fix it :("),
}}
assertFilter(t, f, obj1, true)
assertFilter(t, f, obj2, false)
assertFilter(t, f, obj3, true)
})
t.Run("string list", func(t *testing.T) {
toys := "my favorite toys"
f := FilterHasPrefix{
Key: toys,
Prefix: "Fluffy",
}
obj1 := &types.Struct{Fields: map[string]*types.Value{
toys: pbtypes.StringList([]string{"Teddy bear", "Fluffy giraffe"}),
}}
obj2 := &types.Struct{Fields: map[string]*types.Value{
toys: pbtypes.StringList([]string{"Barbie doll", "Peppa Pig"}),
}}
obj3 := &types.Struct{Fields: map[string]*types.Value{
toys: pbtypes.StringList([]string{"T Rex", "Fluffy Rabbit the Murderer"}),
}}
assertFilter(t, f, obj1, true)
assertFilter(t, f, obj2, false)
assertFilter(t, f, obj3, true)
})
}