Skip to content
This repository has been archived by the owner on Sep 28, 2022. It is now read-only.

Commit

Permalink
Add GroupByBase method which takes function options
Browse files Browse the repository at this point in the history
  • Loading branch information
travisturner committed Nov 21, 2019
1 parent 39c2f0e commit 64c8d57
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 0 deletions.
87 changes: 87 additions & 0 deletions orm.go
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,93 @@ func (idx *Index) Options(row *PQLRowQuery, opts ...OptionsOption) *PQLBaseQuery
return NewPQLBaseQuery(text, idx, nil)
}

type groupByBuilder struct {
rows []*PQLRowsQuery
limit int64
filter *PQLRowQuery
aggregate *PQLBaseQuery
}

// groupByBuilderOption is a functional option type for index.GroupBy
type groupByBuilderOption func(g *groupByBuilder) error

// OptGroupByBuilderRows is a functional option on groupByBuilder
// used to set the rows.
func OptGroupByBuilderRows(rows ...*PQLRowsQuery) groupByBuilderOption {
return func(g *groupByBuilder) error {
g.rows = rows
return nil
}
}

// OptGroupByBuilderLimit is a functional option on groupByBuilder
// used to set the limit.
func OptGroupByBuilderLimit(l int64) groupByBuilderOption {
return func(g *groupByBuilder) error {
g.limit = l
return nil
}
}

// OptGroupByBuilderFilter is a functional option on groupByBuilder
// used to set the filter.
func OptGroupByBuilderFilter(q *PQLRowQuery) groupByBuilderOption {
return func(g *groupByBuilder) error {
g.filter = q
return nil
}
}

// OptGroupByBuilderAggregate is a functional option on groupByBuilder
// used to set the aggregate.
func OptGroupByBuilderAggregate(agg *PQLBaseQuery) groupByBuilderOption {
return func(g *groupByBuilder) error {
g.aggregate = agg
return nil
}
}

// GroupByBase creates a GroupBy query with the given functional options.
func (idx *Index) GroupByBase(opts ...groupByBuilderOption) *PQLBaseQuery {
bldr := &groupByBuilder{}
for _, opt := range opts {
err := opt(bldr)
if err != nil {
return NewPQLBaseQuery("", idx, errors.Wrap(err, "applying option"))
}
}

if len(bldr.rows) < 1 {
return NewPQLBaseQuery("", idx, errors.New("there should be at least one rows query"))
}
if bldr.limit < 0 {
return NewPQLBaseQuery("", idx, errors.New("limit must be non-negative"))
}

// rows
text := fmt.Sprintf("GroupBy(%s", strings.Join(serializeGroupBy(bldr.rows...), ","))

// limit
if bldr.limit > 0 {
text += fmt.Sprintf(",limit=%d", bldr.limit)
}

// filter
if bldr.filter != nil {
filterText := bldr.filter.serialize().String()
text += fmt.Sprintf(",filter=%s", filterText)
}

// aggregate
if bldr.aggregate != nil {
aggregateText := bldr.aggregate.Serialize().String()
text += fmt.Sprintf(",aggregate=%s", aggregateText)
}

text += ")"
return NewPQLBaseQuery(text, idx, nil)
}

// GroupBy creates a GroupBy query with the given Rows queries
func (idx *Index) GroupBy(rowsQueries ...*PQLRowsQuery) *PQLBaseQuery {
if len(rowsQueries) < 1 {
Expand Down
72 changes: 72 additions & 0 deletions orm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,78 @@ func TestGroupByLimitFilter(t *testing.T) {
}
}

func TestGroupByBase(t *testing.T) {
field := sampleIndex.Field("test")
comparePQL(t,
"GroupBy(Rows(field='collaboration'))",
sampleIndex.GroupByBase(
OptGroupByBuilderRows(collabField.Rows()),
),
)
comparePQL(t,
"GroupBy(Rows(field='collaboration'),Rows(field='test'))",
sampleIndex.GroupByBase(
OptGroupByBuilderRows(collabField.Rows(), field.Rows()),
),
)

comparePQL(t,
"GroupBy(Rows(field='collaboration'),limit=10)",
sampleIndex.GroupByBase(
OptGroupByBuilderLimit(10),
OptGroupByBuilderRows(collabField.Rows()),
),
)
comparePQL(t,
"GroupBy(Rows(field='collaboration'),Rows(field='test'),limit=10)",
sampleIndex.GroupByBase(
OptGroupByBuilderLimit(10),
OptGroupByBuilderRows(collabField.Rows(), field.Rows()),
),
)

comparePQL(t,
"GroupBy(Rows(field='collaboration'),filter=Row(test=5))",
sampleIndex.GroupByBase(
OptGroupByBuilderFilter(field.Row(5)),
OptGroupByBuilderRows(collabField.Rows()),
),
)
comparePQL(t,
"GroupBy(Rows(field='collaboration'),Rows(field='test'),filter=Row(test=5))",
sampleIndex.GroupByBase(
OptGroupByBuilderFilter(field.Row(5)),
OptGroupByBuilderRows(collabField.Rows(), field.Rows()),
),
)

comparePQL(t,
"GroupBy(Rows(field='collaboration'),limit=10,filter=Row(test=5))",
sampleIndex.GroupByBase(
OptGroupByBuilderLimit(10),
OptGroupByBuilderFilter(field.Row(5)),
OptGroupByBuilderRows(collabField.Rows()),
),
)
comparePQL(t,
"GroupBy(Rows(field='collaboration'),Rows(field='test'),limit=10,filter=Row(test=5))",
sampleIndex.GroupByBase(
OptGroupByBuilderLimit(10),
OptGroupByBuilderFilter(field.Row(5)),
OptGroupByBuilderRows(collabField.Rows(), field.Rows()),
),
)

field2 := sampleIndex.Field("age")
comparePQL(t,
"GroupBy(Rows(field='collaboration'),Rows(field='test'),aggregate=Sum(Row(age=20),field='age'))",
sampleIndex.GroupByBase(
OptGroupByBuilderRows(collabField.Rows(), field.Rows()),
OptGroupByBuilderAggregate(field2.Sum(field2.Row(20))),
),
)
}

func TestFieldOptions(t *testing.T) {
field := sampleIndex.Field("foo", OptFieldKeys(true))
if true != field.Opts().Keys() {
Expand Down

0 comments on commit 64c8d57

Please sign in to comment.