summaryrefslogtreecommitdiff
path: root/internal/mapr/setcondition.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/mapr/setcondition.go')
-rw-r--r--internal/mapr/setcondition.go93
1 files changed, 93 insertions, 0 deletions
diff --git a/internal/mapr/setcondition.go b/internal/mapr/setcondition.go
new file mode 100644
index 0000000..8c5cfc9
--- /dev/null
+++ b/internal/mapr/setcondition.go
@@ -0,0 +1,93 @@
+package mapr
+
+import (
+ "errors"
+ "fmt"
+ "strconv"
+ "strings"
+
+ "github.com/mimecast/dtail/internal/mapr/funcs"
+)
+
+// Represent a parsed "set" clause, used by mapr.Query
+type setCondition struct {
+ lString string
+
+ rType fieldType
+ rString string
+ rFloat float64
+
+ // For now only text functions are supported.
+ // Maybe in the future we can have typed functions too
+ // so that a float input/output is possible.
+ functionStack funcs.FunctionStack
+}
+
+func (sc *setCondition) String() string {
+ return fmt.Sprintf("setCondition(lString:%s,rString:%s,rType:%s,functionStack:%v)",
+ sc.lString, sc.rString, sc.rType.String(), sc.functionStack)
+}
+
+func makeSetConditions(tokens []token) (set []setCondition, err error) {
+ parse := func(tokens []token) (setCondition, []token, error) {
+ var sc setCondition
+ if len(tokens) < 3 {
+ return sc, nil, errors.New(invalidQuery + "Not enough arguments in 'set' clause")
+ }
+
+ setOp := strings.ToLower(tokens[1].str)
+ switch setOp {
+ case "=":
+ default:
+ return sc, nil, errors.New(invalidQuery + "Unknown operation in 'set' clause: " + setOp)
+ }
+
+ if !tokens[0].isBareword {
+ return sc, nil, errors.New(invalidQuery + "Expected bareword at 'set' clause's lValue: " + tokens[0].str)
+ }
+
+ sc.lString = tokens[0].str
+ if !strings.HasPrefix(sc.lString, "$") {
+ return sc, nil, errors.New(invalidQuery + "Expected field variable name (starting with $) at 'set' clause's lValue: " + tokens[0].str)
+ }
+ sc.rType = Field
+
+ rString := tokens[2].str
+ // Seems like a function call?
+ if strings.HasSuffix(rString, ")") {
+ functionStack, functionArg, err := funcs.NewFunctionStack(tokens[2].str)
+ if err != nil {
+ return sc, nil, err
+ }
+ sc.functionStack = functionStack
+ sc.rType = FunctionStack
+ sc.rString = functionArg
+ return sc, tokens[3:], nil
+ }
+
+ sc.rString = rString
+ if f, err := strconv.ParseFloat(sc.rString, 64); err == nil {
+ sc.rFloat = f
+ sc.rType = Float
+ } else {
+ sc.rType = Field
+ }
+
+ return sc, tokens[3:], nil
+ }
+
+ for len(tokens) > 0 {
+ var sc setCondition
+ var err error
+
+ sc, tokens, err = parse(tokens)
+ if err != nil {
+ return nil, err
+ }
+
+ set = append(set, sc)
+ tokens = tokensConsumeOptional(tokens, ",")
+ }
+
+ return
+}