Skip to content
Snippets Groups Projects
Commit feb7bffc authored by Pavel Antonov's avatar Pavel Antonov :asterisk:
Browse files

Merge branch 'feature/PRXS-951-1984-FindOptions' into 'feature/PRXS-951-Log'

Реализация параметров offset и limit для опций поиска FindOptions сервисов Items, Delivery, Users, Organizations

See merge request perxis/perxis-go!169
parents f2545131 74e6436c
No related branches found
No related tags found
No related merge requests found
......@@ -302,39 +302,11 @@ func ProtoToPtrItemsFilter(protoFilter *itemspb.Filter) (*items.Filter, error) {
}
func PtrServicesFindOptionsToProto(options *services.FindOptions) (*common.FindOptions, error) {
if options == nil {
return nil, nil
}
return &common.FindOptions{
Sort: options.Sort,
PageNum: int32(options.PageNum),
PageSize: int32(options.PageSize),
Offset: int32(options.Offset),
Limit: int32(options.Limit),
Fields: options.Fields,
ExcludeFields: options.ExcludeFields,
}, nil
return services.FindOptionsToPB(options), nil
}
func ProtoToPtrServicesFindOptions(protoOptions *common.FindOptions) (*services.FindOptions, error) {
if protoOptions == nil {
return nil, nil
}
return &services.FindOptions{
SortOptions: services.SortOptions{
Sort: protoOptions.Sort,
},
PaginationOptions: services.PaginationOptions{
PageNum: int(protoOptions.PageNum),
PageSize: int(protoOptions.PageSize),
Offset: int(protoOptions.Offset),
Limit: int(protoOptions.Limit),
},
FieldOptions: services.FieldOptions{
Fields: protoOptions.Fields,
ExcludeFields: protoOptions.ExcludeFields,
},
}, nil
return services.FindOptionsFromPB(protoOptions), nil
}
func ListPtrItemsItemToProto(itms []*items.Item) ([]*itemspb.Item, error) {
......
......@@ -104,11 +104,18 @@ func PtrServicesFindOptionsToProto(opts *options.FindOptions) (*pb.FindOptions,
if opts == nil {
return nil, nil
}
return &pb.FindOptions{
fo := &pb.FindOptions{
Sort: opts.Sort,
PageNum: int32(opts.PageNum),
PageSize: int32(opts.PageSize),
}, nil
PageSize: int32(opts.Limit),
}
if opts.Limit != 0 {
// Потенциальная ошибка если offset не кратен limit
fo.PageNum = int32(opts.Offset / opts.Limit)
}
return fo, nil
}
func ProtoToPtrServicesFindOptions(protoOpts *pb.FindOptions) (*options.FindOptions, error) {
......@@ -120,8 +127,8 @@ func ProtoToPtrServicesFindOptions(protoOpts *pb.FindOptions) (*options.FindOpti
Sort: protoOpts.Sort,
},
PaginationOptions: options.PaginationOptions{
PageNum: int(protoOpts.PageNum),
PageSize: int(protoOpts.PageSize),
Limit: int(protoOpts.PageSize),
Offset: int(protoOpts.PageNum * protoOpts.PageSize),
},
}, nil
}
......
package items
import "context"
type FindResultDummy struct {
Items []*Item
Total int
Error error
}
type Dummy struct {
Items
FindResult *FindResultDummy
}
func (d *Dummy) Find(_ context.Context, _, _, _ string, _ *Filter, _ ...*FindOptions) ([]*Item, int, error) {
return d.FindResult.Items, d.FindResult.Total, d.FindResult.Error
}
......@@ -16,9 +16,7 @@ type BatchProcessor struct {
FindPublishedOptions *FindPublishedOptions
Filter *Filter
// Deprecated использовать offset, limit
pageSize, pageNum int
limit int
sort []string
processed int
}
......@@ -39,7 +37,7 @@ func (b *BatchProcessor) getBatch(ctx context.Context) ([]*Item, bool, error) {
Regular: b.FindPublishedOptions.Regular,
Hidden: b.FindPublishedOptions.Hidden,
Templates: b.FindPublishedOptions.Templates,
FindOptions: *options.NewFindOptions(b.pageNum, b.pageSize, b.sort...),
FindOptions: *options.New(b.processed, b.limit, b.sort...),
},
)
} else {
......@@ -54,14 +52,13 @@ func (b *BatchProcessor) getBatch(ctx context.Context) ([]*Item, bool, error) {
Regular: b.FindOptions.Regular,
Hidden: b.FindOptions.Hidden,
Templates: b.FindOptions.Templates,
FindOptions: *options.NewFindOptions(b.pageNum, b.pageSize, b.sort...),
FindOptions: *options.New(b.processed, b.limit, b.sort...),
},
)
}
if err == nil {
b.processed += len(res)
b.pageNum++
}
return res, b.processed != total, err
......@@ -86,32 +83,29 @@ func (b *BatchProcessor) next(ctx context.Context) (res []*Item, next bool, err
}
func (b *BatchProcessor) reducePageSize() bool {
if b.pageSize == 1 {
if b.limit == 1 {
return false
}
b.pageNum = 2 * b.pageNum
b.pageSize = b.pageSize / 2
b.limit /= 2
return true
}
func (b *BatchProcessor) Do(ctx context.Context, f func(batch []*Item) error) (int, error) {
if b.FindOptions == nil && b.FindPublishedOptions == nil {
b.FindOptions = new(FindOptions)
}
if b.FindOptions != nil {
b.pageSize = b.FindOptions.PageSize
b.limit = b.FindOptions.Limit
b.sort = b.FindOptions.Sort
}
if b.FindPublishedOptions != nil {
b.pageSize = b.FindPublishedOptions.PageSize
b.limit = b.FindPublishedOptions.Limit
b.sort = b.FindPublishedOptions.Sort
}
if b.pageSize == 0 {
b.pageSize = 128
if b.limit == 0 {
b.limit = 128
}
if b.Filter != nil && (len(b.Filter.ID) > 0 || len(b.Filter.Q) > 0) && !data.Contains("_id", b.sort) {
......
......@@ -11,8 +11,12 @@ import (
)
func TestBatchProcessor(t *testing.T) {
itemssvc := &Dummy{FindResult: &FindResultDummy{Items: nil, Total: 0, Error: nil}}
t.Run("EmptyResults", func(t *testing.T) {
itemssvc := &Stub{
FindResult: func(req StubFindRequest) StubFindResult {
return StubFindResult{Items: nil, Total: 0, Error: nil}
},
}
b := &BatchProcessor{
Items: itemssvc,
......@@ -32,4 +36,26 @@ func TestBatchProcessor(t *testing.T) {
_, err := b.Do(context.Background(), func(batch []*Item) error { counter++; return nil })
require.NoError(t, err)
assert.Equal(t, 0, counter)
})
t.Run("With FindOptions", func(t *testing.T) {
itemssvc := &Stub{
FindResult: func(req StubFindRequest) StubFindResult {
fo := MergeFindOptions(req.Options...)
return StubFindResult{Items: make([]*Item, fo.Limit), Total: 1000, Error: nil}
},
}
b := &BatchProcessor{
Items: itemssvc,
SpaceID: "sp",
EnvID: environments.DefaultEnvironment,
CollectionID: "col",
FindOptions: &FindOptions{FindOptions: *options.New(0, 25)},
}
var counter int
_, err := b.Do(context.Background(), func(batch []*Item) error { counter++; return nil })
require.NoError(t, err)
assert.Equal(t, 1000/25, counter)
})
}
package items
import (
"context"
)
type StubFindRequest struct {
Context context.Context
SpaceID, EnvID, CollID string
Filter *Filter
Options []*FindOptions
}
type StubFindResult struct {
Items []*Item
Total int
Error error
}
type Stub struct {
Items
FindResult func(req StubFindRequest) StubFindResult
}
func (d *Stub) Find(ctx context.Context, spaceID, envID, collID string, filter *Filter, opts ...*FindOptions) ([]*Item, int, error) {
res := d.FindResult(StubFindRequest{
Context: ctx,
SpaceID: spaceID,
EnvID: envID,
CollID: collID,
Filter: filter,
Options: opts,
})
return res.Items, res.Total, res.Error
}
......@@ -144,39 +144,11 @@ func ProtoToPtrFilter(protoFilter *pb.Filter) (*service.Filter, error) {
}
func PtrServicesFindOptionsToProto(opts *options.FindOptions) (*pbcommon.FindOptions, error) {
if opts == nil {
return nil, nil
}
return &pbcommon.FindOptions{
Sort: opts.Sort,
PageNum: int32(opts.PageNum),
PageSize: int32(opts.PageSize),
Offset: int32(opts.Offset),
Limit: int32(opts.Limit),
Fields: opts.Fields,
ExcludeFields: opts.ExcludeFields,
}, nil
return options.FindOptionsToPB(opts), nil
}
func ProtoToPtrServicesFindOptions(protoOpts *pbcommon.FindOptions) (*options.FindOptions, error) {
if protoOpts == nil {
return nil, nil
}
return &options.FindOptions{
SortOptions: options.SortOptions{
Sort: protoOpts.Sort,
},
PaginationOptions: options.PaginationOptions{
PageNum: int(protoOpts.PageNum),
PageSize: int(protoOpts.PageSize),
Offset: int(protoOpts.Offset),
Limit: int(protoOpts.Limit),
},
FieldOptions: options.FieldOptions{
Fields: protoOpts.Fields,
ExcludeFields: protoOpts.ExcludeFields,
},
}, nil
return options.FindOptionsFromPB(protoOpts), nil
}
func ListPtrItemToProto(items []*service.Item) ([]*pb.Item, error) {
......
......@@ -13,10 +13,6 @@ type SortOptions struct {
// PaginationOptions настройки возвращаемых страниц результатов
type PaginationOptions struct {
//Deprecated
PageNum int
PageSize int
Limit int
Offset int
}
......@@ -39,12 +35,18 @@ type FindOptions struct {
FieldOptions
}
// Deprecated использовать New
// NewFindOptions создает новые результаты поиска
func NewFindOptions(pageNum, pageSize int, sort ...string) *FindOptions {
return New(pageNum*pageSize, pageSize, sort...)
}
// New создает новые параметры поиска
func New(offset, limit int, sort ...string) *FindOptions {
return &FindOptions{
PaginationOptions: PaginationOptions{
PageNum: pageNum,
PageSize: pageSize,
Offset: offset,
Limit: limit,
},
SortOptions: SortOptions{
Sort: sort,
......@@ -95,8 +97,8 @@ func FindOptionsFromPB(protoOpts *commonpb.FindOptions) *FindOptions {
Sort: protoOpts.Sort,
},
PaginationOptions: PaginationOptions{
Offset: int(protoOpts.Offset),
Limit: int(protoOpts.Limit),
Offset: int(protoOpts.Offset),
},
FieldOptions: FieldOptions{
Fields: protoOpts.Fields,
......@@ -104,9 +106,9 @@ func FindOptionsFromPB(protoOpts *commonpb.FindOptions) *FindOptions {
},
}
if fo.Offset == 0 && fo.Limit == 0 && fo.PageSize != 0 {
fo.Offset = fo.PageSize * (fo.PageNum - 1)
fo.Limit = fo.PageSize
if fo.Offset == 0 && fo.Limit == 0 {
fo.Offset = int(protoOpts.PageSize * protoOpts.PageNum)
fo.Limit = int(protoOpts.PageSize)
}
return fo
......@@ -118,21 +120,11 @@ func FindOptionsToPB(opts *FindOptions) *commonpb.FindOptions {
}
fo := &commonpb.FindOptions{
Sort: opts.Sort,
PageNum: int32(opts.PageNum),
PageSize: int32(opts.PageSize),
Offset: int32(opts.Offset),
Limit: int32(opts.Limit),
Fields: opts.Fields,
ExcludeFields: opts.ExcludeFields,
}
if fo.PageSize != 0 && fo.Limit == 0 {
fo.Limit = fo.PageSize
fo.Offset = fo.PageSize * (fo.PageNum - 1)
}
if fo.Limit != 0 && fo.PageSize == 0 {
fo.PageSize = fo.Limit
fo.PageNum = fo.Offset / fo.Limit
}
return fo
}
......@@ -156,11 +148,9 @@ func MergeSortOptions(options ...SortOptions) SortOptions {
func MergePaginationOptions(options ...PaginationOptions) PaginationOptions {
fo := PaginationOptions{}
for _, opt := range options {
if opt.PageSize == 0 && opt.PageNum == 0 && opt.Offset == 0 && opt.Limit == 0 {
if opt.Offset == 0 && opt.Limit == 0 {
continue
}
fo.PageNum = opt.PageNum
fo.PageSize = opt.PageSize
fo.Offset = opt.Offset
fo.Limit = opt.Limit
}
......
......@@ -7,7 +7,6 @@ import (
)
func TestOptions_MergePaginationOptions(t *testing.T) {
var tt = []struct {
name string
options []PaginationOptions
......@@ -24,29 +23,29 @@ func TestOptions_MergePaginationOptions(t *testing.T) {
expected: PaginationOptions{},
},
{
name: "One option",
options: []PaginationOptions{{PageNum: 10, PageSize: 100}},
expected: PaginationOptions{PageNum: 10, PageSize: 100},
name: "One limit/offset option",
options: []PaginationOptions{{Limit: 10, Offset: 100}},
expected: PaginationOptions{Limit: 10, Offset: 100},
},
{
name: "Merge #1",
options: []PaginationOptions{{PageNum: 0, PageSize: 0}, {PageNum: 10, PageSize: 100}},
expected: PaginationOptions{PageNum: 10, PageSize: 100},
name: "Merge limit/offset #1",
options: []PaginationOptions{{Limit: 0, Offset: 0}, {Limit: 10, Offset: 100}},
expected: PaginationOptions{Limit: 10, Offset: 100},
},
{
name: "Merge #2",
options: []PaginationOptions{{PageNum: 10, PageSize: 100}, {PageNum: 0, PageSize: 0}},
expected: PaginationOptions{PageNum: 10, PageSize: 100},
name: "Merge limit/offset #2",
options: []PaginationOptions{{Limit: 10, Offset: 100}, {Limit: 0, Offset: 0}},
expected: PaginationOptions{Limit: 10, Offset: 100},
},
{
name: "Merge #3",
options: []PaginationOptions{{PageNum: 0, PageSize: 0}, {PageNum: 10, PageSize: 100}, {PageNum: 0, PageSize: 0}},
expected: PaginationOptions{PageNum: 10, PageSize: 100},
name: "Merge limit/offset #3",
options: []PaginationOptions{{Limit: 0, Offset: 0}, {Limit: 10, Offset: 100}, {Limit: 0, Offset: 0}},
expected: PaginationOptions{Limit: 10, Offset: 100},
},
{
name: "Merge #4",
options: []PaginationOptions{{PageNum: 10, PageSize: 100}, {}},
expected: PaginationOptions{PageNum: 10, PageSize: 100},
name: "Merge limit/offset #4",
options: []PaginationOptions{{Limit: 10, Offset: 100}, {}},
expected: PaginationOptions{Limit: 10, Offset: 100},
},
}
......
......@@ -61,33 +61,11 @@ func ProtoToPtrFilter(protoFilter *pb.Filter) (*organizations.Filter, error) {
}
func PtrServicesFindOptionsToProto(opts *options.FindOptions) (*common.FindOptions, error) {
if opts == nil {
return nil, nil
}
return &common.FindOptions{
Sort: opts.Sort,
PageNum: int32(opts.PageNum),
PageSize: int32(opts.PageSize),
Offset: int32(opts.Offset),
Limit: int32(opts.Limit),
}, nil
return options.FindOptionsToPB(opts), nil
}
func ProtoToPtrServicesFindOptions(protoOpts *common.FindOptions) (*options.FindOptions, error) {
if protoOpts == nil {
return nil, nil
}
return &options.FindOptions{
SortOptions: options.SortOptions{
Sort: protoOpts.Sort,
},
PaginationOptions: options.PaginationOptions{
PageNum: int(protoOpts.PageNum),
PageSize: int(protoOpts.PageSize),
Offset: int(protoOpts.Offset),
Limit: int(protoOpts.Limit),
},
}, nil
return options.FindOptionsFromPB(protoOpts), nil
}
func ListPtrOrganizationToProto(orgs []*organizations.Organization) ([]*pb.Organization, error) {
......
......@@ -127,27 +127,9 @@ func ProtoToListPtrUser(protoCreates []*pb.User) ([]*service.User, error) {
}
func PtrServicesFindOptionsToProto(opts *options.FindOptions) (*common.FindOptions, error) {
if opts == nil {
return nil, nil
}
return &common.FindOptions{
Sort: opts.Sort,
PageNum: int32(opts.PageNum),
PageSize: int32(opts.PageSize),
}, nil
return options.FindOptionsToPB(opts), nil
}
func ProtoToPtrServicesFindOptions(protoOpts *common.FindOptions) (*options.FindOptions, error) {
if protoOpts == nil {
return nil, nil
}
return &options.FindOptions{
SortOptions: options.SortOptions{
Sort: protoOpts.Sort,
},
PaginationOptions: options.PaginationOptions{
PageNum: int(protoOpts.PageNum),
PageSize: int(protoOpts.PageSize),
},
}, nil
return options.FindOptionsFromPB(protoOpts), nil
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment