github.com/MontFerret/ferret@v0.18.0/pkg/runtime/expressions/clauses/limit.go (about) 1 package clauses 2 3 import ( 4 "context" 5 6 "github.com/MontFerret/ferret/pkg/runtime/collections" 7 "github.com/MontFerret/ferret/pkg/runtime/core" 8 "github.com/MontFerret/ferret/pkg/runtime/values/types" 9 ) 10 11 type LimitClause struct { 12 src core.SourceMap 13 dataSource collections.Iterable 14 count core.Expression 15 offset core.Expression 16 } 17 18 func NewLimitClause( 19 src core.SourceMap, 20 dataSource collections.Iterable, 21 count core.Expression, 22 offset core.Expression, 23 ) (collections.Iterable, error) { 24 if dataSource == nil { 25 return nil, core.Error(core.ErrMissedArgument, "dataSource source") 26 } 27 28 return &LimitClause{src, dataSource, count, offset}, nil 29 } 30 31 func (clause *LimitClause) Iterate(ctx context.Context, scope *core.Scope) (collections.Iterator, error) { 32 src, err := clause.dataSource.Iterate(ctx, scope) 33 34 if err != nil { 35 return nil, core.SourceError(clause.src, err) 36 } 37 38 count, err := clause.count.Exec(ctx, scope) 39 40 if err != nil { 41 return nil, core.SourceError(clause.src, err) 42 } 43 44 offset, err := clause.offset.Exec(ctx, scope) 45 46 if err != nil { 47 return nil, core.SourceError(clause.src, err) 48 } 49 50 countInt, err := clause.parseValue(count) 51 52 if err != nil { 53 return nil, err 54 } 55 56 offsetInt, err := clause.parseValue(offset) 57 58 if err != nil { 59 return nil, err 60 } 61 62 iterator, err := collections.NewLimitIterator(src, countInt, offsetInt) 63 64 if err != nil { 65 return nil, core.SourceError(clause.src, err) 66 } 67 68 return iterator, nil 69 } 70 71 func (clause *LimitClause) parseValue(val core.Value) (int, error) { 72 if val.Type() == types.Int { 73 return val.Unwrap().(int), nil 74 } 75 76 if val.Type() == types.Float { 77 return int(val.Unwrap().(float64)), nil 78 } 79 80 return -1, core.TypeError(val.Type(), types.Int, types.Float) 81 }