Browse Source

feat(influxdb): render select and groupby

bergquist 9 năm trước cách đây
mục cha
commit
4387d20222

+ 8 - 2
pkg/tsdb/influxdb/influxdb.go

@@ -12,13 +12,15 @@ import (
 
 type InfluxDBExecutor struct {
 	*tsdb.DataSourceInfo
-	QueryParser *InfluxdbQueryParser
+	QueryParser  *InfluxdbQueryParser
+	QueryBuilder *QueryBuild
 }
 
 func NewInfluxDBExecutor(dsInfo *tsdb.DataSourceInfo) tsdb.Executor {
 	return &InfluxDBExecutor{
 		DataSourceInfo: dsInfo,
 		QueryParser:    &InfluxdbQueryParser{},
+		QueryBuilder:   &QueryBuild{},
 	}
 }
 
@@ -46,12 +48,16 @@ func (e *InfluxDBExecutor) Execute(ctx context.Context, queries tsdb.QuerySlice,
 	for _, v := range queries {
 
 		query, err := e.QueryParser.Parse(v.Model)
-
 		if err != nil {
 			result.Error = err
 			return result
 		}
+
 		glog.Info("Influxdb executor", "query", query)
+
+		rawQuery, err := e.QueryBuilder.Build(query)
+
+		glog.Info("Influxdb", "error", err, "rawQuery", rawQuery)
 	}
 
 	return result

+ 57 - 2
pkg/tsdb/influxdb/query_builder.go

@@ -1,10 +1,65 @@
 package influxdb
 
-import "fmt"
+import (
+	"fmt"
+	"strings"
+)
 
 type QueryBuild struct{}
 
+func renderTags(query *Query) []string {
+	var res []string
+	for i, tag := range query.Tags {
+		str := ""
+
+		if i > 0 {
+			if tag.Condition == "" {
+				str += "AND"
+			} else {
+				str += tag.Condition
+			}
+			str += " "
+		}
+
+		res = append(res, fmt.Sprintf(`%s"%s" %s '%s'`, str, tag.Key, tag.Operator, tag.Value))
+	}
+
+	return res
+}
+
 func (*QueryBuild) Build(query *Query) (string, error) {
+	res := "SELECT "
+
+	var selectors []string
+	for _, sel := range query.Selects {
+
+		stk := ""
+		for _, s := range *sel {
+			stk = s.Render(stk)
+		}
+		selectors = append(selectors, stk)
+	}
+	res += strings.Join(selectors, ", ")
+
+	res += fmt.Sprintf(` FROM "%s"`, query.Measurement)
+
+	res += " WHERE "
+	conditions := renderTags(query)
+	res += strings.Join(conditions, " ")
+	if len(conditions) > 0 {
+		res += " AND "
+	}
+
+	res += "$timeFilter"
+
+	var groupBy []string
+	for _, group := range query.GroupBy {
+		groupBy = append(groupBy, group.Render(""))
+	}
+
+	if len(groupBy) > 0 {
+		res += " GROUP BY " + strings.Join(groupBy, " ")
+	}
 
-	return "", fmt.Errorf("query is not valid")
+	return res, nil
 }

+ 29 - 39
pkg/tsdb/influxdb/query_builder_test.go

@@ -8,50 +8,40 @@ import (
 
 func TestInfluxdbQueryBuilder(t *testing.T) {
 	Convey("Influxdb query builder", t, func() {
+		builder := QueryBuild{}
 
-		builder := &QueryBuild{}
+		qp1, _ := NewQueryPart("field", []string{"value"})
+		qp2, _ := NewQueryPart("mean", []string{})
+
+		groupBy1, _ := NewQueryPart("time", []string{"$interval"})
+		groupBy2, _ := NewQueryPart("fill", []string{"null"})
+
+		tag1 := &Tag{Key: "hostname", Value: "server1", Operator: "="}
+		tag2 := &Tag{Key: "hostname", Value: "server2", Operator: "=", Condition: "OR"}
 
 		Convey("can build query", func() {
-			//query := &Query{}
-			//res, err := builder.Build(query)
-			//So(err, ShouldBeNil)
+			query := &Query{
+				Selects:     []*Select{{*qp1, *qp2}},
+				Measurement: "cpu",
+				GroupBy:     []*QueryPart{groupBy1, groupBy2},
+			}
+
+			rawQuery, err := builder.Build(query)
+			So(err, ShouldBeNil)
+			So(rawQuery, ShouldEqual, `SELECT mean("value") FROM "cpu" WHERE $timeFilter GROUP BY time($interval) fill(null)`)
 		})
 
-		Convey("empty queries should return error", func() {
-			query := &Query{}
-
-			res, err := builder.Build(query)
-			So(err, ShouldNotBeNil)
-			So(res, ShouldEqual, "")
+		Convey("can asd query", func() {
+			query := &Query{
+				Selects:     []*Select{{*qp1, *qp2}},
+				Measurement: "cpu",
+				GroupBy:     []*QueryPart{groupBy1},
+				Tags:        []*Tag{tag1, tag2},
+			}
+
+			rawQuery, err := builder.Build(query)
+			So(err, ShouldBeNil)
+			So(rawQuery, ShouldEqual, `SELECT mean("value") FROM "cpu" WHERE "hostname" = 'server1' OR "hostname" = 'server2' AND $timeFilter GROUP BY time($interval)`)
 		})
 	})
 }
-
-/*
-  describe('render series with mesurement only', function() {
-    it('should generate correct query', function() {
-      var query = new InfluxQuery({
-        measurement: 'cpu',
-      }, templateSrv, {});
-
-      var queryText = query.render();
-      expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE $timeFilter GROUP BY time($interval) fill(null)');
-    });
-  });
-*/
-
-/*
-  describe('series with tags OR condition', function() {
-    it('should generate correct query', function() {
-      var query = new InfluxQuery({
-        measurement: 'cpu',
-        groupBy: [{type: 'time', params: ['auto']}],
-        tags: [{key: 'hostname', value: 'server1'}, {key: 'hostname', value: 'server2', condition: "OR"}]
-      }, templateSrv, {});
-
-      var queryText = query.render();
-      expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE "hostname" = \'server1\' OR "hostname" = \'server2\' AND ' +
-                          '$timeFilter GROUP BY time($interval)');
-    });
-  });
-*/

+ 5 - 5
pkg/tsdb/influxdb/query_part.go

@@ -91,13 +91,13 @@ func fieldRenderer(part *QueryPart, innerExpr string) string {
 }
 
 func functionRenderer(part *QueryPart, innerExpr string) string {
-	params := strings.Join(part.Params, ", ")
-
-	if len(part.Params) > 0 {
-		return fmt.Sprintf("%s(%s, %s)", part.Type, innerExpr, params)
+	if innerExpr != "" {
+		part.Params = append([]string{innerExpr}, part.Params...)
 	}
 
-	return fmt.Sprintf("%s(%s)", part.Type, innerExpr)
+	params := strings.Join(part.Params, ", ")
+
+	return fmt.Sprintf("%s(%s)", part.Type, params)
 }
 
 func suffixRenderer(part *QueryPart, innerExpr string) string {