mirror of
https://github.com/MontFerret/ferret.git
synced 2024-12-16 11:37:36 +02:00
132 lines
3.0 KiB
Go
132 lines
3.0 KiB
Go
package clauses
|
|
|
|
import (
|
|
"context"
|
|
"github.com/MontFerret/ferret/pkg/runtime/collections"
|
|
"github.com/MontFerret/ferret/pkg/runtime/core"
|
|
)
|
|
|
|
type (
|
|
Collect struct {
|
|
group *CollectGroup
|
|
count *CollectCount
|
|
aggregate *CollectAggregate
|
|
}
|
|
|
|
CollectGroup struct {
|
|
selectors []*CollectSelector
|
|
projection *CollectProjection
|
|
count *CollectCount
|
|
aggregate *CollectAggregate
|
|
}
|
|
|
|
CollectCount struct {
|
|
variable string
|
|
}
|
|
|
|
CollectProjection struct {
|
|
selector *CollectSelector
|
|
}
|
|
|
|
CollectAggregate struct {
|
|
selectors []*CollectAggregateSelector
|
|
}
|
|
|
|
CollectClause struct {
|
|
src core.SourceMap
|
|
dataSource collections.Iterable
|
|
params *Collect
|
|
}
|
|
)
|
|
|
|
func NewCollect(
|
|
selectors []*CollectSelector,
|
|
projection *CollectProjection,
|
|
count *CollectCount,
|
|
aggregate *CollectAggregate,
|
|
) (*Collect, error) {
|
|
collect := new(Collect)
|
|
|
|
// grouping
|
|
if selectors != nil {
|
|
collect.group = new(CollectGroup)
|
|
collect.group.selectors = selectors
|
|
|
|
if projection == nil && count == nil && aggregate == nil {
|
|
return collect, nil
|
|
}
|
|
|
|
if projection != nil && count == nil && aggregate == nil {
|
|
collect.group.projection = projection
|
|
} else if projection == nil && count != nil && aggregate == nil {
|
|
collect.group.count = count
|
|
} else if projection == nil && count == nil && aggregate != nil {
|
|
collect.group.aggregate = aggregate
|
|
} else {
|
|
return nil, core.Error(core.ErrInvalidOperation, "projection, count and aggregate cannot be used together")
|
|
}
|
|
|
|
return collect, nil
|
|
}
|
|
|
|
if count == nil && aggregate != nil {
|
|
collect.aggregate = aggregate
|
|
} else if count != nil && aggregate == nil {
|
|
collect.count = count
|
|
} else {
|
|
return nil, core.Error(core.ErrInvalidOperation, "count and aggregate cannot be used together")
|
|
}
|
|
|
|
return collect, nil
|
|
}
|
|
|
|
func NewCollectCount(variable string) (*CollectCount, error) {
|
|
if variable == "" {
|
|
return nil, core.Error(core.ErrMissedArgument, "count variable")
|
|
}
|
|
|
|
return &CollectCount{variable}, nil
|
|
}
|
|
|
|
func NewCollectProjection(selector *CollectSelector) (*CollectProjection, error) {
|
|
if selector == nil {
|
|
return nil, core.Error(core.ErrMissedArgument, "projection selector")
|
|
}
|
|
|
|
return &CollectProjection{selector}, nil
|
|
}
|
|
|
|
func NewCollectAggregate(selectors []*CollectAggregateSelector) (*CollectAggregate, error) {
|
|
if selectors == nil {
|
|
return nil, core.Error(core.ErrMissedArgument, "aggregate selectors")
|
|
}
|
|
|
|
return &CollectAggregate{selectors}, nil
|
|
}
|
|
|
|
func NewCollectClause(
|
|
src core.SourceMap,
|
|
dataSource collections.Iterable,
|
|
params *Collect,
|
|
) (collections.Iterable, error) {
|
|
if dataSource == nil {
|
|
return nil, core.Error(core.ErrMissedArgument, "dataSource source")
|
|
}
|
|
|
|
return &CollectClause{src, dataSource, params}, nil
|
|
}
|
|
|
|
func (clause *CollectClause) Iterate(ctx context.Context, scope *core.Scope) (collections.Iterator, error) {
|
|
srcIterator, err := clause.dataSource.Iterate(ctx, scope)
|
|
|
|
if err != nil {
|
|
return nil, core.SourceError(clause.src, err)
|
|
}
|
|
|
|
return NewCollectIterator(
|
|
clause.src,
|
|
clause.params,
|
|
srcIterator,
|
|
)
|
|
}
|