github.com/MontFerret/ferret@v0.18.0/pkg/runtime/expressions/for.go (about) 1 package expressions 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/expressions/clauses" 9 "github.com/MontFerret/ferret/pkg/runtime/values" 10 ) 11 12 type ForExpression struct { 13 src core.SourceMap 14 dataSource collections.Iterable 15 predicate core.Expression 16 distinct bool 17 spread bool 18 passThrough bool 19 } 20 21 func NewForExpression( 22 src core.SourceMap, 23 dataSource collections.Iterable, 24 predicate core.Expression, 25 distinct, 26 spread, 27 passThrough bool, 28 ) (*ForExpression, error) { 29 if dataSource == nil { 30 return nil, core.Error(core.ErrMissedArgument, "missed source expression") 31 } 32 33 if predicate == nil { 34 return nil, core.Error(core.ErrMissedArgument, "missed return expression") 35 } 36 37 exp := new(ForExpression) 38 exp.src = src 39 exp.dataSource = dataSource 40 exp.predicate = predicate 41 exp.distinct = distinct 42 exp.spread = spread 43 exp.passThrough = passThrough 44 45 return exp, nil 46 } 47 48 func (e *ForExpression) AddLimit(src core.SourceMap, size, count core.Expression) error { 49 limit, err := clauses.NewLimitClause(src, e.dataSource, size, count) 50 51 if err != nil { 52 return err 53 } 54 55 e.dataSource = limit 56 57 return nil 58 } 59 60 func (e *ForExpression) AddFilter(src core.SourceMap, exp core.Expression) error { 61 filter, err := clauses.NewFilterClause(src, e.dataSource, exp) 62 63 if err != nil { 64 return err 65 } 66 67 e.dataSource = filter 68 69 return nil 70 } 71 72 func (e *ForExpression) AddSort(src core.SourceMap, sorters ...*clauses.SorterExpression) error { 73 sort, err := clauses.NewSortClause(src, e.dataSource, sorters...) 74 75 if err != nil { 76 return err 77 } 78 79 e.dataSource = sort 80 81 return nil 82 } 83 84 func (e *ForExpression) AddCollect(src core.SourceMap, params *clauses.Collect) error { 85 collect, err := clauses.NewCollectClause(src, e.dataSource, params) 86 87 if err != nil { 88 return err 89 } 90 91 e.dataSource = collect 92 93 return nil 94 } 95 96 func (e *ForExpression) AddStatement(stmt core.Expression) error { 97 tap, ok := e.dataSource.(*BlockExpression) 98 99 if !ok { 100 t, err := NewBlockExpression(e.dataSource) 101 102 if err != nil { 103 return err 104 } 105 106 tap = t 107 e.dataSource = tap 108 } 109 110 tap.Add(stmt) 111 112 return nil 113 } 114 115 func (e *ForExpression) Exec(ctx context.Context, scope *core.Scope) (core.Value, error) { 116 select { 117 case <-ctx.Done(): 118 return values.None, core.ErrTerminated 119 default: 120 iterator, err := e.dataSource.Iterate(ctx, scope) 121 122 if err != nil { 123 return values.None, err 124 } 125 126 res := NewForResult(10). 127 Distinct(e.distinct). 128 Spread(e.spread). 129 PassThrough(e.passThrough) 130 131 for { 132 nextScope, err := iterator.Next(ctx, scope) 133 134 if err != nil { 135 if core.IsNoMoreData(err) { 136 break 137 } 138 139 return values.None, core.SourceError(e.src, err) 140 } 141 142 out, err := e.predicate.Exec(ctx, nextScope) 143 144 if err != nil { 145 return values.None, err 146 } 147 148 res.Push(out) 149 } 150 151 return res.ToArray(), nil 152 } 153 }