feat(tsdb): add interval calculator
This commit is contained in:
@@ -30,11 +30,11 @@ func renderTags(query *Query) []string {
|
||||
}
|
||||
|
||||
func (*QueryBuilder) Build(query *Query, queryContext *tsdb.QueryContext) (string, error) {
|
||||
res := renderSelectors(query)
|
||||
res := renderSelectors(query, queryContext)
|
||||
res += renderMeasurement(query)
|
||||
res += renderWhereClause(query)
|
||||
res += renderTimeFilter(query, queryContext)
|
||||
res += renderGroupBy(query)
|
||||
res += renderGroupBy(query, queryContext)
|
||||
|
||||
return res, nil
|
||||
}
|
||||
@@ -50,7 +50,7 @@ func renderTimeFilter(query *Query, queryContext *tsdb.QueryContext) string {
|
||||
return fmt.Sprintf("time > %s%s", from, to)
|
||||
}
|
||||
|
||||
func renderSelectors(query *Query) string {
|
||||
func renderSelectors(query *Query, queryContext *tsdb.QueryContext) string {
|
||||
res := "SELECT "
|
||||
|
||||
var selectors []string
|
||||
@@ -58,7 +58,7 @@ func renderSelectors(query *Query) string {
|
||||
|
||||
stk := ""
|
||||
for _, s := range *sel {
|
||||
stk = s.Render(stk)
|
||||
stk = s.Render(queryContext, stk)
|
||||
}
|
||||
selectors = append(selectors, stk)
|
||||
}
|
||||
@@ -87,7 +87,7 @@ func renderWhereClause(query *Query) string {
|
||||
return res
|
||||
}
|
||||
|
||||
func renderGroupBy(query *Query) string {
|
||||
func renderGroupBy(query *Query, queryContext *tsdb.QueryContext) string {
|
||||
groupBy := ""
|
||||
for i, group := range query.GroupBy {
|
||||
if i == 0 {
|
||||
@@ -100,7 +100,7 @@ func renderGroupBy(query *Query) string {
|
||||
groupBy += " "
|
||||
}
|
||||
|
||||
groupBy += group.Render("")
|
||||
groupBy += group.Render(queryContext, "")
|
||||
}
|
||||
|
||||
return groupBy
|
||||
|
||||
@@ -37,7 +37,7 @@ func TestInfluxdbQueryBuilder(t *testing.T) {
|
||||
|
||||
rawQuery, err := builder.Build(query, queryContext)
|
||||
So(err, ShouldBeNil)
|
||||
So(rawQuery, ShouldEqual, `SELECT mean("value") FROM "policy"."cpu" WHERE time > now() - 5m GROUP BY time(10s) fill(null)`)
|
||||
So(rawQuery, ShouldEqual, `SELECT mean("value") FROM "policy"."cpu" WHERE time > now() - 5m GROUP BY time(200ms) fill(null)`)
|
||||
})
|
||||
|
||||
Convey("can build query with group bys", func() {
|
||||
@@ -51,7 +51,7 @@ func TestInfluxdbQueryBuilder(t *testing.T) {
|
||||
|
||||
rawQuery, err := builder.Build(query, queryContext)
|
||||
So(err, ShouldBeNil)
|
||||
So(rawQuery, ShouldEqual, `SELECT mean("value") FROM "cpu" WHERE "hostname" = 'server1' OR "hostname" = 'server2' AND time > now() - 5m GROUP BY time(10s), "datacenter" fill(null)`)
|
||||
So(rawQuery, ShouldEqual, `SELECT mean("value") FROM "cpu" WHERE "hostname" = 'server1' OR "hostname" = 'server2' AND time > now() - 5m GROUP BY time(200ms), "datacenter" fill(null)`)
|
||||
})
|
||||
|
||||
Convey("can render time range", func() {
|
||||
|
||||
@@ -3,6 +3,8 @@ package influxdb
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/tsdb"
|
||||
)
|
||||
|
||||
var renders map[string]QueryDefinition
|
||||
@@ -13,7 +15,7 @@ type DefinitionParameters struct {
|
||||
}
|
||||
|
||||
type QueryDefinition struct {
|
||||
Renderer func(part *QueryPart, innerExpr string) string
|
||||
Renderer func(queryContext *tsdb.QueryContext, part *QueryPart, innerExpr string) string
|
||||
Params []DefinitionParameters
|
||||
}
|
||||
|
||||
@@ -83,17 +85,17 @@ func init() {
|
||||
renders["alias"] = QueryDefinition{Renderer: aliasRenderer}
|
||||
}
|
||||
|
||||
func fieldRenderer(part *QueryPart, innerExpr string) string {
|
||||
func fieldRenderer(queryContext *tsdb.QueryContext, part *QueryPart, innerExpr string) string {
|
||||
if part.Params[0] == "*" {
|
||||
return "*"
|
||||
}
|
||||
return fmt.Sprintf(`"%s"`, part.Params[0])
|
||||
}
|
||||
|
||||
func functionRenderer(part *QueryPart, innerExpr string) string {
|
||||
func functionRenderer(queryContext *tsdb.QueryContext, part *QueryPart, innerExpr string) string {
|
||||
for i, v := range part.Params {
|
||||
if v == "$interval" {
|
||||
part.Params[i] = "10s"
|
||||
part.Params[i] = tsdb.CalculateInterval(queryContext.TimeRange)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,16 +108,16 @@ func functionRenderer(part *QueryPart, innerExpr string) string {
|
||||
return fmt.Sprintf("%s(%s)", part.Type, params)
|
||||
}
|
||||
|
||||
func suffixRenderer(part *QueryPart, innerExpr string) string {
|
||||
func suffixRenderer(queryContext *tsdb.QueryContext, part *QueryPart, innerExpr string) string {
|
||||
return fmt.Sprintf("%s %s", innerExpr, part.Params[0])
|
||||
}
|
||||
|
||||
func aliasRenderer(part *QueryPart, innerExpr string) string {
|
||||
func aliasRenderer(queryContext *tsdb.QueryContext, part *QueryPart, innerExpr string) string {
|
||||
return fmt.Sprintf(`%s AS "%s"`, innerExpr, part.Params[0])
|
||||
}
|
||||
|
||||
func (r QueryDefinition) Render(part *QueryPart, innerExpr string) string {
|
||||
return r.Renderer(part, innerExpr)
|
||||
func (r QueryDefinition) Render(queryContext *tsdb.QueryContext, part *QueryPart, innerExpr string) string {
|
||||
return r.Renderer(queryContext, part, innerExpr)
|
||||
}
|
||||
|
||||
func NewQueryPart(typ string, params []string) (*QueryPart, error) {
|
||||
@@ -138,6 +140,6 @@ type QueryPart struct {
|
||||
Params []string
|
||||
}
|
||||
|
||||
func (qp *QueryPart) Render(expr string) string {
|
||||
return qp.Def.Renderer(qp, expr)
|
||||
func (qp *QueryPart) Render(queryContext *tsdb.QueryContext, expr string) string {
|
||||
return qp.Def.Renderer(queryContext, qp, expr)
|
||||
}
|
||||
|
||||
@@ -3,17 +3,22 @@ package influxdb
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/tsdb"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestInfluxdbQueryPart(t *testing.T) {
|
||||
Convey("Influxdb query parts", t, func() {
|
||||
|
||||
queryContext := &tsdb.QueryContext{
|
||||
TimeRange: tsdb.NewTimeRange("5m", "now"),
|
||||
}
|
||||
|
||||
Convey("render field ", func() {
|
||||
part, err := NewQueryPart("field", []string{"value"})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
res := part.Render("value")
|
||||
res := part.Render(queryContext, "value")
|
||||
So(res, ShouldEqual, `"value"`)
|
||||
})
|
||||
|
||||
@@ -21,7 +26,7 @@ func TestInfluxdbQueryPart(t *testing.T) {
|
||||
part, err := NewQueryPart("derivative", []string{"10s"})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
res := part.Render("mean(value)")
|
||||
res := part.Render(queryContext, "mean(value)")
|
||||
So(res, ShouldEqual, "derivative(mean(value), 10s)")
|
||||
})
|
||||
|
||||
@@ -29,7 +34,7 @@ func TestInfluxdbQueryPart(t *testing.T) {
|
||||
part, err := NewQueryPart("bottom", []string{"3"})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
res := part.Render("value")
|
||||
res := part.Render(queryContext, "value")
|
||||
So(res, ShouldEqual, "bottom(value, 3)")
|
||||
})
|
||||
|
||||
@@ -37,15 +42,15 @@ func TestInfluxdbQueryPart(t *testing.T) {
|
||||
part, err := NewQueryPart("time", []string{"$interval"})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
res := part.Render("")
|
||||
So(res, ShouldEqual, "time(10s)")
|
||||
res := part.Render(queryContext, "")
|
||||
So(res, ShouldEqual, "time(200ms)")
|
||||
})
|
||||
|
||||
Convey("render spread", func() {
|
||||
part, err := NewQueryPart("spread", []string{})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
res := part.Render("value")
|
||||
res := part.Render(queryContext, "value")
|
||||
So(res, ShouldEqual, `spread(value)`)
|
||||
})
|
||||
|
||||
@@ -53,7 +58,7 @@ func TestInfluxdbQueryPart(t *testing.T) {
|
||||
part, err := NewQueryPart("math", []string{"/ 100"})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
res := part.Render("mean(value)")
|
||||
res := part.Render(queryContext, "mean(value)")
|
||||
So(res, ShouldEqual, "mean(value) / 100")
|
||||
})
|
||||
|
||||
@@ -61,7 +66,7 @@ func TestInfluxdbQueryPart(t *testing.T) {
|
||||
part, err := NewQueryPart("alias", []string{"test"})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
res := part.Render("mean(value)")
|
||||
res := part.Render(queryContext, "mean(value)")
|
||||
So(res, ShouldEqual, `mean(value) AS "test"`)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -18,9 +18,11 @@ func (rp *ResponseParser) Parse(response *Response) *tsdb.QueryResult {
|
||||
rp.parseResult(result.Series, queryRes)
|
||||
}
|
||||
|
||||
for _, serie := range queryRes.Series {
|
||||
glog.Debug("result", "name", serie.Name, "points", serie.Points)
|
||||
}
|
||||
/*
|
||||
for _, serie := range queryRes.Series {
|
||||
glog.Debug("result", "name", serie.Name, "points", serie.Points)
|
||||
}
|
||||
*/
|
||||
|
||||
return queryRes
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user