1
0
mirror of https://github.com/MontFerret/ferret.git synced 2025-08-15 20:02:56 +02:00

Changed logic of iterator termination (#330)

This commit is contained in:
Tim Voronov
2019-07-13 13:39:01 -04:00
committed by GitHub
parent b1e9505dd1
commit 9756f0dc5a
21 changed files with 87 additions and 86 deletions

View File

@@ -23,7 +23,7 @@ compile:
./main.go
test:
go test -race -v ${DIR_PKG}/...
go test -race ${DIR_PKG}/...
cover:
go test -race -coverprofile=coverage.txt -covermode=atomic ${DIR_PKG}/... && \

View File

@@ -46,11 +46,6 @@ func (iterator *coreIterator) Next(ctx context.Context, scope *core.Scope) (*cor
return nil, err
}
// end of iteration
if val == values.None {
return nil, nil
}
nextScope := scope.Fork()
if err := nextScope.SetVariable(iterator.valVar, val); err != nil {

View File

@@ -35,11 +35,6 @@ func (iterator *FilterIterator) Next(ctx context.Context, scope *core.Scope) (*c
return nil, err
}
if nextScope == nil {
return nil, nil
}
// TODO: test case when predicate return not nil
take, err := iterator.predicate(ctx, nextScope)
if err != nil {

View File

@@ -161,7 +161,7 @@ func TestFilter(t *testing.T) {
item, err := iter.Next(context.Background(), scope)
So(item, ShouldBeNil)
So(err, ShouldBeNil)
So(err, ShouldEqual, core.ErrNoMoreData)
})
Convey("Should iterate over nested filter", t, func() {

View File

@@ -62,5 +62,5 @@ func (iterator *IndexedIterator) Next(_ context.Context, scope *core.Scope) (*co
return nextScope, nil
}
return nil, nil
return nil, core.ErrNoMoreData
}

View File

@@ -37,10 +37,12 @@ func TestArrayIterator(t *testing.T) {
for {
nextScope, err := iter.Next(ctx, scope.Fork())
So(err, ShouldBeNil)
if err != nil {
if core.IsNoMoreData(err) {
break
}
if nextScope == nil {
break
So(err, ShouldBeNil)
}
res = append(res, nextScope.MustGetVariable(collections.DefaultValueVar))
@@ -70,10 +72,12 @@ func TestArrayIterator(t *testing.T) {
for {
nextScope, err := iter.Next(ctx, scope.Fork())
So(err, ShouldBeNil)
if err != nil {
if core.IsNoMoreData(err) {
break
}
if nextScope == nil {
break
So(err, ShouldBeNil)
}
res = append(res, nextScope.MustGetVariable(collections.DefaultValueVar))
@@ -107,10 +111,12 @@ func TestArrayIterator(t *testing.T) {
for {
nextScope, err := iter.Next(ctx, scope.Fork())
So(err, ShouldBeNil)
if err != nil {
if core.IsNoMoreData(err) {
break
}
if nextScope == nil {
break
So(err, ShouldBeNil)
}
res = append(res, nextScope.MustGetVariable(collections.DefaultValueVar))
@@ -119,7 +125,7 @@ func TestArrayIterator(t *testing.T) {
item, err := iter.Next(ctx, scope)
So(item, ShouldBeNil)
So(err, ShouldBeNil)
So(err, ShouldEqual, core.ErrNoMoreData)
So(res, ShouldHaveLength, int(arr.Length()))
})
@@ -133,7 +139,7 @@ func TestArrayIterator(t *testing.T) {
nextScope, err := iter.Next(ctx, scope)
So(err, ShouldBeNil)
So(err, ShouldEqual, core.ErrNoMoreData)
So(nextScope, ShouldBeNil)
})
}

View File

@@ -22,11 +22,11 @@ func ToSlice(ctx context.Context, scope *core.Scope, iterator Iterator) ([]*core
nextScope, err := iterator.Next(ctx, scope.Fork())
if err != nil {
return nil, err
}
if core.IsNoMoreData(err) {
return res, nil
}
if nextScope == nil {
return res, nil
return nil, err
}
res = append(res, nextScope)

View File

@@ -60,5 +60,5 @@ func (iterator *KeyedIterator) Next(_ context.Context, scope *core.Scope) (*core
return nextScope, nil
}
return nil, nil
return nil, core.ErrNoMoreData
}

View File

@@ -35,10 +35,12 @@ func TestObjectIterator(t *testing.T) {
for {
nextScope, err := iter.Next(ctx, scope)
So(err, ShouldBeNil)
if err != nil {
if core.IsNoMoreData(err) {
break
}
if nextScope == nil {
break
So(err, ShouldBeNil)
}
key := nextScope.MustGetVariable(collections.DefaultKeyVar)
@@ -77,7 +79,7 @@ func TestObjectIterator(t *testing.T) {
nextScope, err := iter.Next(ctx, scope)
So(nextScope, ShouldBeNil)
So(err, ShouldBeNil)
So(err, ShouldEqual, core.ErrNoMoreData)
})
Convey("Should NOT iterate over a empty map", t, func() {
@@ -91,6 +93,6 @@ func TestObjectIterator(t *testing.T) {
nextScope, err := iter.Next(ctx, scope)
So(nextScope, ShouldBeNil)
So(err, ShouldBeNil)
So(err, ShouldEqual, core.ErrNoMoreData)
})
}

View File

@@ -31,7 +31,7 @@ func (iterator *LimitIterator) Next(ctx context.Context, scope *core.Scope) (*co
return iterator.values.Next(ctx, scope)
}
return nil, nil
return nil, core.ErrNoMoreData
}
func (iterator *LimitIterator) counter() int {
@@ -44,15 +44,14 @@ func (iterator *LimitIterator) verifyOffset(ctx context.Context, scope *core.Sco
}
for iterator.offset > iterator.currCount {
nextScope, err := iterator.values.Next(ctx, scope.Fork())
_, err := iterator.values.Next(ctx, scope.Fork())
if err != nil {
return err
}
if core.IsNoMoreData(err) {
iterator.currCount = iterator.offset
}
if nextScope == nil {
iterator.currCount = iterator.offset
return nil
return err
}
iterator.currCount++

View File

@@ -69,5 +69,5 @@ func (iterator *MapIterator) Next(_ context.Context, scope *core.Scope) (*core.S
return nextScope, nil
}
return nil, nil
return nil, core.ErrNoMoreData
}

View File

@@ -34,10 +34,12 @@ func TestMapIterator(t *testing.T) {
for {
nextScope, err := iter.Next(ctx, scope)
So(err, ShouldBeNil)
if err != nil {
if core.IsNoMoreData(err) {
break
}
if nextScope == nil {
break
So(err, ShouldBeNil)
}
key := nextScope.MustGetVariable(collections.DefaultKeyVar)
@@ -73,7 +75,7 @@ func TestMapIterator(t *testing.T) {
item, err := iter.Next(ctx, scope)
So(item, ShouldBeNil)
So(err, ShouldBeNil)
So(err, ShouldEqual, core.ErrNoMoreData)
})
Convey("Should NOT iterate over a empty map", t, func() {
@@ -87,6 +89,6 @@ func TestMapIterator(t *testing.T) {
item, err := iter.Next(ctx, scope)
So(item, ShouldBeNil)
So(err, ShouldBeNil)
So(err, ShouldEqual, core.ErrNoMoreData)
})
}

View File

@@ -51,5 +51,5 @@ func (iterator *SliceIterator) Next(_ context.Context, scope *core.Scope) (*core
return nextScope, nil
}
return nil, nil
return nil, core.ErrNoMoreData
}

View File

@@ -36,10 +36,12 @@ func TestSliceIterator(t *testing.T) {
for {
nextScope, err := iter.Next(ctx, scope)
So(err, ShouldBeNil)
if err != nil {
if core.IsNoMoreData(err) {
break
}
if nextScope == nil {
break
So(err, ShouldBeNil)
}
key := nextScope.MustGetVariable(collections.DefaultKeyVar)
@@ -101,7 +103,7 @@ func TestSliceIterator(t *testing.T) {
item, err := iter.Next(ctx, scope)
So(item, ShouldBeNil)
So(err, ShouldBeNil)
So(err, ShouldEqual, core.ErrNoMoreData)
})
Convey("Should NOT iterate over an empty slice", t, func() {
@@ -114,6 +116,6 @@ func TestSliceIterator(t *testing.T) {
item, err := iter.Next(ctx, scope)
So(item, ShouldBeNil)
So(err, ShouldBeNil)
So(err, ShouldEqual, core.ErrNoMoreData)
})
}

View File

@@ -104,7 +104,7 @@ func (iterator *SortIterator) Next(ctx context.Context, scope *core.Scope) (*cor
return val, nil
}
return nil, nil
return nil, core.ErrNoMoreData
}
func (iterator *SortIterator) sort(ctx context.Context, scope *core.Scope) ([]*core.Scope, error) {

View File

@@ -29,10 +29,6 @@ func (iterator *TapIterator) Next(ctx context.Context, scope *core.Scope) (*core
return nil, err
}
if nextScope == nil {
return nil, nil
}
_, err = iterator.predicate.Exec(ctx, nextScope)
if err != nil {

View File

@@ -33,10 +33,6 @@ func (iterator *UniqueIterator) Next(ctx context.Context, scope *core.Scope) (*c
return nil, err
}
if nextScope == nil {
return nil, nil
}
v, err := nextScope.GetVariable(iterator.hashKey)
if err != nil {

View File

@@ -20,6 +20,7 @@ var (
ErrTimeout = errors.New("operation timed out")
ErrNotImplemented = errors.New("not implemented")
ErrNotSupported = errors.New("not supported")
ErrNoMoreData = errors.New("no more data")
)
const typeErrorTemplate = "expected %s, but got %s"
@@ -65,3 +66,7 @@ func Errors(err ...error) error {
return errors.New(message)
}
func IsNoMoreData(err error) bool {
return err == ErrNoMoreData
}

View File

@@ -97,7 +97,7 @@ func (iterator *CollectIterator) Next(ctx context.Context, scope *core.Scope) (*
return val, nil
}
return nil, nil
return nil, core.ErrNoMoreData
}
func (iterator *CollectIterator) init(ctx context.Context, scope *core.Scope) ([]*core.Scope, error) {
@@ -137,11 +137,11 @@ func (iterator *CollectIterator) group(ctx context.Context, scope *core.Scope) (
dataSourceScope, err := iterator.dataSource.Next(ctx, scope.Fork())
if err != nil {
return nil, err
}
if core.IsNoMoreData(err) {
break
}
if dataSourceScope == nil {
break
return nil, err
}
// this data dataSourceScope represents a data of a given iteration with values retrieved by selectors
@@ -328,14 +328,14 @@ func (iterator *CollectIterator) count(ctx context.Context, scope *core.Scope) (
for {
// keep all defined variables in forked scopes
// all those variables should not be available for further executions
os, err := iterator.dataSource.Next(ctx, scope.Fork())
_, err := iterator.dataSource.Next(ctx, scope.Fork())
if err != nil {
return nil, err
}
if core.IsNoMoreData(err) {
break
}
if os == nil {
break
return nil, err
}
counter++
@@ -368,11 +368,11 @@ func (iterator *CollectIterator) aggregate(ctx context.Context, scope *core.Scop
os, err := iterator.dataSource.Next(ctx, scope.Fork())
if err != nil {
return nil, err
}
if core.IsNoMoreData(err) {
break
}
if os == nil {
break
return nil, err
}
// iterate over each selector for a current data set

View File

@@ -59,7 +59,7 @@ func (i *testCollectionIterator) Next(ctx context.Context) (core.Value, core.Val
i.position++
if i.position > i.values.Length() {
return values.None, values.None, nil
return values.None, values.None, core.ErrNoMoreData
}
return i.values.Get(i.position), i.position, nil
@@ -104,15 +104,18 @@ func TestDataSource(t *testing.T) {
nextScope := scope
for {
pos++
nextScope, err = out.Next(ctx, nextScope.Fork())
So(err, ShouldBeNil)
if err != nil {
if core.IsNoMoreData(err) {
break
}
if nextScope == nil {
break
So(err, ShouldBeNil)
}
pos++
actualV, _ := nextScope.GetVariable(collections.DefaultValueVar)
actualK, _ := nextScope.GetVariable(collections.DefaultKeyVar)

View File

@@ -126,16 +126,16 @@ func (e *ForExpression) Exec(ctx context.Context, scope *core.Scope) (core.Value
}
res := values.NewArray(10)
for {
nextScope, err := iterator.Next(ctx, scope)
if err != nil {
return values.None, core.SourceError(e.src, err)
}
if core.IsNoMoreData(err) {
break
}
// no data anymore
if nextScope == nil {
break
return values.None, core.SourceError(e.src, err)
}
out, err := e.predicate.Exec(ctx, nextScope)