Browse Source

sql: better client-side handling and validation

boyska 5 years ago
parent
commit
89419185ed
1 changed files with 34 additions and 19 deletions
  1. 34 19
      cmd/circolog-tail/main.go

+ 34 - 19
cmd/circolog-tail/main.go

@@ -21,21 +21,34 @@ import (
 	"gopkg.in/mgo.v2/bson"
 )
 
-// TODO: type ExpressionValue
+type ExprValue struct {
+	Node expr.Node
+}
+
+func (e *ExprValue) String() string {
+	if e.Node != nil {
+		return e.Node.String()
+	} else {
+		return "<Empty Expression>"
+	}
+}
+func (e *ExprValue) Set(value string) error {
+	ast, err := expr.ParseExpression(value)
+	if err != nil {
+		return err
+	}
+	e.Node = ast
+	return nil
+}
 
 func main() {
 	addr := flag.String("addr", "localhost:9080", "http service address")
 	querySocket := flag.String("socket", "", "Path to a unix domain socket for the HTTP server")
 	backlogLimit := flag.Int("n", -1, "Limit the backlog length, defaults to no limit (-1)")
-	filter := flag.String("where", "", "sql-like query to filter logs")
+	var filter ExprValue
+	flag.Var(&filter, "where", "sql-like query to filter logs")
 	flag.Parse()
 
-	filterExpr, err := expr.ParseExpression(*filter)
-	if err != nil {
-		fmt.Fprintln(os.Stderr, "invalid filter:", err)
-		os.Exit(2)
-	}
-
 	interrupt := make(chan os.Signal, 1)
 	signal.Notify(interrupt, os.Interrupt)
 	var d *websocket.Dialer
@@ -85,17 +98,19 @@ func main() {
 				log.Println("invalid BSON", err)
 				continue
 			}
-			context := datasource.NewContextSimpleNative(parsed)
-			val, ok := vm.Eval(context, filterExpr)
-			if !ok || val == nil { // errors when evaluating
-				continue
-			}
-			if val.Type() != value.BoolType {
-				fmt.Fprintln(os.Stderr, "WARNING: The expression doesn't return a boolean")
-				continue
-			}
-			if val.Value().(bool) != true {
-				continue
+			if filter.Node != nil {
+				context := datasource.NewContextSimpleNative(parsed)
+				val, ok := vm.Eval(context, filter.Node)
+				if !ok || val == nil { // errors when evaluating
+					continue
+				}
+				if val.Type() != value.BoolType {
+					fmt.Fprintln(os.Stderr, "WARNING: The 'where' expression doesn't return a boolean")
+					continue
+				}
+				if val.Value().(bool) != true {
+					continue
+				}
 			}
 			if err := formatter.WriteFormatted(os.Stdout, formatter.FormatSyslog, parsed); err != nil {
 				log.Println("error printing", err)