diff options
Diffstat (limited to 'internal/mapr/setcondition.go')
| -rw-r--r-- | internal/mapr/setcondition.go | 93 |
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 +} |
