From c128865c4c7411c29a59fca9a3a2f95537686d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20B=C3=BCtow?= Date: Mon, 20 Jan 2020 18:41:05 +0000 Subject: Move commands to cmd/ and move internal dependencies to internal/ --- internal/mapr/selectcondition.go | 96 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 internal/mapr/selectcondition.go (limited to 'internal/mapr/selectcondition.go') diff --git a/internal/mapr/selectcondition.go b/internal/mapr/selectcondition.go new file mode 100644 index 0000000..1882b7e --- /dev/null +++ b/internal/mapr/selectcondition.go @@ -0,0 +1,96 @@ +package mapr + +import ( + "errors" + "fmt" + "strings" +) + +// AggregateOperation is to specify the aggregate operation type. +type AggregateOperation int + +// Aggregate operation types +const ( + UndefAggregateOperation AggregateOperation = iota + Count AggregateOperation = iota + Sum AggregateOperation = iota + Min AggregateOperation = iota + Max AggregateOperation = iota + Last AggregateOperation = iota + Avg AggregateOperation = iota + Len AggregateOperation = iota +) + +// Represents a parsed "select" clause, used by mapr.Query. +type selectCondition struct { + Field string + FieldStorage string + Operation AggregateOperation +} + +func (sc selectCondition) String() string { + return fmt.Sprintf("selectCondition(Field:%s,FieldStorage:%s,Operation:%v)", + sc.Field, + sc.FieldStorage, + sc.Operation) +} + +func makeSelectConditions(tokens []token) ([]selectCondition, error) { + var sel []selectCondition + + // Parse select aggregation, e.g. sum(foo) + parse := func(token token) (selectCondition, error) { + var sc selectCondition + tokenStr := strings.ToLower(token.str) + + if !strings.Contains(tokenStr, "(") && !strings.Contains(tokenStr, ")") { + sc.Field = tokenStr + sc.FieldStorage = tokenStr + sc.Operation = Last + return sc, nil + } + + a := strings.Split(tokenStr, "(") + if len(a) != 2 { + return sc, errors.New(invalidQuery + "Can't parse 'select' aggregation: " + token.str) + } + agg := a[0] // Aggregation, e.g. 'sum' + + b := strings.Split(a[1], ")") + if len(b) != 2 { + return sc, errors.New(invalidQuery + "Can't parse 'select' field name from aggregation: " + token.str) + } + sc.Field = b[0] // Field name, e.g. 'foo' + sc.FieldStorage = tokenStr // e.g. 'sum(foo)' + + switch agg { + case "count": + sc.Operation = Count + case "sum": + sc.Operation = Sum + case "min": + sc.Operation = Min + case "max": + sc.Operation = Max + case "last": + sc.Operation = Last + case "avg": + sc.Operation = Avg + case "len": + sc.Operation = Len + default: + return sc, errors.New(invalidQuery + "Unknown aggregation in 'select' clause: " + agg) + } + + return sc, nil + } + + for _, token := range tokens { + sc, err := parse(token) + if err != nil { + return nil, err + } + sel = append(sel, sc) + } + return sel, nil +} -- cgit v1.2.3