Introduce TSDB service (#31520)
* Introduce TSDB service Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> Co-authored-by: Erik Sundell <erik.sundell87@gmail.com> Co-authored-by: Will Browne <will.browne@grafana.com> Co-authored-by: Torkel Ödegaard <torkel@grafana.org> Co-authored-by: Will Browne <wbrowne@users.noreply.github.com> Co-authored-by: Zoltán Bedi <zoltan.bedi@gmail.com>
This commit is contained in:
co-authored by
Erik Sundell
Will Browne
Torkel Ödegaard
Will Browne
Zoltán Bedi
parent
c899bf3592
commit
b79e61656a
@@ -7,26 +7,28 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/gtime"
|
||||
"github.com/grafana/grafana/pkg/tsdb"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/tsdb/sqleng"
|
||||
)
|
||||
|
||||
const rsIdentifier = `([_a-zA-Z0-9]+)`
|
||||
const sExpr = `\$` + rsIdentifier + `\(([^\)]*)\)`
|
||||
|
||||
type msSqlMacroEngine struct {
|
||||
*sqleng.SqlMacroEngineBase
|
||||
timeRange *tsdb.TimeRange
|
||||
query *tsdb.Query
|
||||
type msSQLMacroEngine struct {
|
||||
*sqleng.SQLMacroEngineBase
|
||||
timeRange plugins.DataTimeRange
|
||||
query plugins.DataSubQuery
|
||||
}
|
||||
|
||||
func newMssqlMacroEngine() sqleng.SqlMacroEngine {
|
||||
return &msSqlMacroEngine{SqlMacroEngineBase: sqleng.NewSqlMacroEngineBase()}
|
||||
func newMssqlMacroEngine() sqleng.SQLMacroEngine {
|
||||
return &msSQLMacroEngine{SQLMacroEngineBase: sqleng.NewSQLMacroEngineBase()}
|
||||
}
|
||||
|
||||
func (m *msSqlMacroEngine) Interpolate(query *tsdb.Query, timeRange *tsdb.TimeRange, sql string) (string, error) {
|
||||
func (m *msSQLMacroEngine) Interpolate(query plugins.DataSubQuery, timeRange plugins.DataTimeRange,
|
||||
sql string) (string, error) {
|
||||
m.timeRange = timeRange
|
||||
m.query = query
|
||||
// TODO: Return any error
|
||||
rExp, _ := regexp.Compile(sExpr)
|
||||
var macroError error
|
||||
|
||||
@@ -50,7 +52,7 @@ func (m *msSqlMacroEngine) Interpolate(query *tsdb.Query, timeRange *tsdb.TimeRa
|
||||
return sql, nil
|
||||
}
|
||||
|
||||
func (m *msSqlMacroEngine) evaluateMacro(name string, args []string) (string, error) {
|
||||
func (m *msSQLMacroEngine) evaluateMacro(name string, args []string) (string, error) {
|
||||
switch name {
|
||||
case "__time":
|
||||
if len(args) == 0 {
|
||||
|
||||
@@ -8,38 +8,40 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/tsdb"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestMacroEngine(t *testing.T) {
|
||||
Convey("MacroEngine", t, func() {
|
||||
engine := &msSqlMacroEngine{}
|
||||
query := &tsdb.Query{
|
||||
engine := &msSQLMacroEngine{}
|
||||
query := plugins.DataSubQuery{
|
||||
Model: simplejson.New(),
|
||||
}
|
||||
|
||||
dfltTimeRange := plugins.DataTimeRange{}
|
||||
|
||||
Convey("Given a time range between 2018-04-12 00:00 and 2018-04-12 00:05", func() {
|
||||
from := time.Date(2018, 4, 12, 18, 0, 0, 0, time.UTC)
|
||||
to := from.Add(5 * time.Minute)
|
||||
timeRange := tsdb.NewFakeTimeRange("5m", "now", to)
|
||||
timeRange := plugins.DataTimeRange{From: "5m", Now: to, To: "now"}
|
||||
|
||||
Convey("interpolate __time function", func() {
|
||||
sql, err := engine.Interpolate(query, nil, "select $__time(time_column)")
|
||||
sql, err := engine.Interpolate(query, dfltTimeRange, "select $__time(time_column)")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(sql, ShouldEqual, "select time_column AS time")
|
||||
})
|
||||
|
||||
Convey("interpolate __timeEpoch function", func() {
|
||||
sql, err := engine.Interpolate(query, nil, "select $__timeEpoch(time_column)")
|
||||
sql, err := engine.Interpolate(query, dfltTimeRange, "select $__timeEpoch(time_column)")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(sql, ShouldEqual, "select DATEDIFF(second, '1970-01-01', time_column) AS time")
|
||||
})
|
||||
|
||||
Convey("interpolate __timeEpoch function wrapped in aggregation", func() {
|
||||
sql, err := engine.Interpolate(query, nil, "select min($__timeEpoch(time_column))")
|
||||
sql, err := engine.Interpolate(query, dfltTimeRange, "select min($__timeEpoch(time_column))")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(sql, ShouldEqual, "select min(DATEDIFF(second, '1970-01-01', time_column) AS time)")
|
||||
@@ -166,7 +168,9 @@ func TestMacroEngine(t *testing.T) {
|
||||
Convey("Given a time range between 1960-02-01 07:00 and 1965-02-03 08:00", func() {
|
||||
from := time.Date(1960, 2, 1, 7, 0, 0, 0, time.UTC)
|
||||
to := time.Date(1965, 2, 3, 8, 0, 0, 0, time.UTC)
|
||||
timeRange := tsdb.NewTimeRange(strconv.FormatInt(from.UnixNano()/int64(time.Millisecond), 10), strconv.FormatInt(to.UnixNano()/int64(time.Millisecond), 10))
|
||||
timeRange := plugins.NewDataTimeRange(
|
||||
strconv.FormatInt(from.UnixNano()/int64(time.Millisecond), 10),
|
||||
strconv.FormatInt(to.UnixNano()/int64(time.Millisecond), 10))
|
||||
|
||||
Convey("interpolate __timeFilter function", func() {
|
||||
sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)")
|
||||
@@ -193,7 +197,9 @@ func TestMacroEngine(t *testing.T) {
|
||||
Convey("Given a time range between 1960-02-01 07:00 and 1980-02-03 08:00", func() {
|
||||
from := time.Date(1960, 2, 1, 7, 0, 0, 0, time.UTC)
|
||||
to := time.Date(1980, 2, 3, 8, 0, 0, 0, time.UTC)
|
||||
timeRange := tsdb.NewTimeRange(strconv.FormatInt(from.UnixNano()/int64(time.Millisecond), 10), strconv.FormatInt(to.UnixNano()/int64(time.Millisecond), 10))
|
||||
timeRange := plugins.NewDataTimeRange(
|
||||
strconv.FormatInt(from.UnixNano()/int64(time.Millisecond), 10),
|
||||
strconv.FormatInt(to.UnixNano()/int64(time.Millisecond), 10))
|
||||
|
||||
Convey("interpolate __timeFilter function", func() {
|
||||
sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)")
|
||||
|
||||
@@ -13,27 +13,24 @@ import (
|
||||
mssql "github.com/denisenkom/go-mssqldb"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/tsdb"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/tsdb/sqleng"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
func init() {
|
||||
tsdb.RegisterTsdbQueryEndpoint("mssql", newMssqlQueryEndpoint)
|
||||
}
|
||||
|
||||
var logger = log.New("tsdb.mssql")
|
||||
|
||||
func newMssqlQueryEndpoint(datasource *models.DataSource) (tsdb.TsdbQueryEndpoint, error) {
|
||||
func NewExecutor(datasource *models.DataSource) (plugins.DataPlugin, error) {
|
||||
cnnstr, err := generateConnectionString(datasource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// TODO: Don't use global
|
||||
if setting.Env == setting.Dev {
|
||||
logger.Debug("getEngine", "connection", cnnstr)
|
||||
}
|
||||
|
||||
config := sqleng.SqlQueryEndpointConfiguration{
|
||||
config := sqleng.DataPluginConfiguration{
|
||||
DriverName: "mssql",
|
||||
ConnectionString: cnnstr,
|
||||
Datasource: datasource,
|
||||
@@ -44,7 +41,7 @@ func newMssqlQueryEndpoint(datasource *models.DataSource) (tsdb.TsdbQueryEndpoin
|
||||
log: logger,
|
||||
}
|
||||
|
||||
return sqleng.NewSqlQueryEndpoint(&config, &queryResultTransformer, newMssqlMacroEngine(), logger)
|
||||
return sqleng.NewDataPlugin(config, &queryResultTransformer, newMssqlMacroEngine(), logger)
|
||||
}
|
||||
|
||||
// ParseURL tries to parse an MSSQL URL string into a URL object.
|
||||
@@ -105,7 +102,8 @@ type mssqlQueryResultTransformer struct {
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func (t *mssqlQueryResultTransformer) TransformQueryResult(columnTypes []*sql.ColumnType, rows *core.Rows) (tsdb.RowValues, error) {
|
||||
func (t *mssqlQueryResultTransformer) TransformQueryResult(columnTypes []*sql.ColumnType, rows *core.Rows) (
|
||||
plugins.DataRowValues, error) {
|
||||
values := make([]interface{}, len(columnTypes))
|
||||
valuePtrs := make([]interface{}, len(columnTypes))
|
||||
|
||||
|
||||
+120
-119
@@ -11,8 +11,8 @@ import (
|
||||
"github.com/grafana/grafana/pkg/components/securejsondata"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/sqlutil"
|
||||
"github.com/grafana/grafana/pkg/tsdb"
|
||||
"github.com/grafana/grafana/pkg/tsdb/sqleng"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
"xorm.io/xorm"
|
||||
@@ -38,11 +38,11 @@ func TestMSSQL(t *testing.T) {
|
||||
}
|
||||
|
||||
origInterpolate := sqleng.Interpolate
|
||||
sqleng.Interpolate = func(query *tsdb.Query, timeRange *tsdb.TimeRange, sql string) (string, error) {
|
||||
sqleng.Interpolate = func(query plugins.DataSubQuery, timeRange plugins.DataTimeRange, sql string) (string, error) {
|
||||
return sql, nil
|
||||
}
|
||||
|
||||
endpoint, err := newMssqlQueryEndpoint(&models.DataSource{
|
||||
endpoint, err := NewExecutor(&models.DataSource{
|
||||
JsonData: simplejson.New(),
|
||||
SecureJsonData: securejsondata.SecureJsonData{},
|
||||
})
|
||||
@@ -122,19 +122,19 @@ func TestMSSQL(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("When doing a table query should map MSSQL column types to Go types", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": "SELECT * FROM mssql_types",
|
||||
"format": "table",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
queryResult := resp.Results["A"]
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -214,19 +214,19 @@ func TestMSSQL(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("When doing a metric query using timeGroup", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": "SELECT $__timeGroup(time, '5m') AS time, avg(value) as value FROM metric GROUP BY $__timeGroup(time, '5m') ORDER BY 1",
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -257,23 +257,23 @@ func TestMSSQL(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("When doing a metric query using timeGroup with NULL fill enabled", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": "SELECT $__timeGroup(time, '5m', NULL) AS time, avg(value) as value FROM metric GROUP BY $__timeGroup(time, '5m') ORDER BY 1",
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
TimeRange: &tsdb.TimeRange{
|
||||
TimeRange: &plugins.DataTimeRange{
|
||||
From: fmt.Sprintf("%v", fromStart.Unix()*1000),
|
||||
To: fmt.Sprintf("%v", fromStart.Add(34*time.Minute).Unix()*1000),
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -317,24 +317,24 @@ func TestMSSQL(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Should replace $__interval", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
DataSource: &models.DataSource{},
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": "SELECT $__timeGroup(time, $__interval) AS time, avg(value) as value FROM metric GROUP BY $__timeGroup(time, $__interval) ORDER BY 1",
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
TimeRange: &tsdb.TimeRange{
|
||||
TimeRange: &plugins.DataTimeRange{
|
||||
From: fmt.Sprintf("%v", fromStart.Unix()*1000),
|
||||
To: fmt.Sprintf("%v", fromStart.Add(30*time.Minute).Unix()*1000),
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -343,23 +343,23 @@ func TestMSSQL(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("When doing a metric query using timeGroup with float fill enabled", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": "SELECT $__timeGroup(time, '5m', 1.5) AS time, avg(value) as value FROM metric GROUP BY $__timeGroup(time, '5m') ORDER BY 1",
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
TimeRange: &tsdb.TimeRange{
|
||||
TimeRange: &plugins.DataTimeRange{
|
||||
From: fmt.Sprintf("%v", fromStart.Unix()*1000),
|
||||
To: fmt.Sprintf("%v", fromStart.Add(34*time.Minute).Unix()*1000),
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -437,19 +437,19 @@ func TestMSSQL(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("When doing a metric query using epoch (int64) as time column and value column (int64) should return metric with time in milliseconds", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": `SELECT TOP 1 timeInt64 as time, timeInt64 FROM metric_values ORDER BY time`,
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -459,19 +459,19 @@ func TestMSSQL(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("When doing a metric query using epoch (int64 nullable) as time column and value column (int64 nullable) should return metric with time in milliseconds", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": `SELECT TOP 1 timeInt64Nullable as time, timeInt64Nullable FROM metric_values ORDER BY time`,
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -481,19 +481,19 @@ func TestMSSQL(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("When doing a metric query using epoch (float64) as time column and value column (float64) should return metric with time in milliseconds", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": `SELECT TOP 1 timeFloat64 as time, timeFloat64 FROM metric_values ORDER BY time`,
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -503,19 +503,19 @@ func TestMSSQL(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("When doing a metric query using epoch (float64 nullable) as time column and value column (float64 nullable) should return metric with time in milliseconds", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": `SELECT TOP 1 timeFloat64Nullable as time, timeFloat64Nullable FROM metric_values ORDER BY time`,
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -525,19 +525,19 @@ func TestMSSQL(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("When doing a metric query using epoch (int32) as time column and value column (int32) should return metric with time in milliseconds", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": `SELECT TOP 1 timeInt32 as time, timeInt32 FROM metric_values ORDER BY time`,
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -547,19 +547,19 @@ func TestMSSQL(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("When doing a metric query using epoch (int32 nullable) as time column and value column (int32 nullable) should return metric with time in milliseconds", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": `SELECT TOP 1 timeInt32Nullable as time, timeInt32Nullable FROM metric_values ORDER BY time`,
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -569,19 +569,19 @@ func TestMSSQL(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("When doing a metric query using epoch (float32) as time column and value column (float32) should return metric with time in milliseconds", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": `SELECT TOP 1 timeFloat32 as time, timeFloat32 FROM metric_values ORDER BY time`,
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -591,19 +591,19 @@ func TestMSSQL(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("When doing a metric query using epoch (float32 nullable) as time column and value column (float32 nullable) should return metric with time in milliseconds", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": `SELECT TOP 1 timeFloat32Nullable as time, timeFloat32Nullable FROM metric_values ORDER BY time`,
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -613,19 +613,19 @@ func TestMSSQL(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("When doing a metric query grouping by time and select metric column should return correct series", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": "SELECT $__timeEpoch(time), measurement + ' - value one' as metric, valueOne FROM metric_values ORDER BY 1",
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -636,19 +636,19 @@ func TestMSSQL(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("When doing a metric query grouping by time should return correct series", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": "SELECT $__timeEpoch(time), valueOne, valueTwo FROM metric_values ORDER BY 1",
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -659,19 +659,19 @@ func TestMSSQL(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("When doing a metric query with metric column and multiple value columns", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": "SELECT $__timeEpoch(time), measurement, valueOne, valueTwo FROM metric_values ORDER BY 1",
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -685,21 +685,22 @@ func TestMSSQL(t *testing.T) {
|
||||
|
||||
Convey("When doing a query with timeFrom,timeTo,unixEpochFrom,unixEpochTo macros", func() {
|
||||
sqleng.Interpolate = origInterpolate
|
||||
query := &tsdb.TsdbQuery{
|
||||
TimeRange: tsdb.NewFakeTimeRange("5m", "now", fromStart),
|
||||
Queries: []*tsdb.Query{
|
||||
timeRange := plugins.DataTimeRange{From: "5m", To: "now", Now: fromStart}
|
||||
query := plugins.DataQuery{
|
||||
TimeRange: &timeRange,
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
DataSource: &models.DataSource{JsonData: simplejson.New()},
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": `SELECT time FROM metric_values WHERE time > $__timeFrom() OR time < $__timeFrom() OR 1 < $__unixEpochFrom() OR $__unixEpochTo() > 1 ORDER BY 1`,
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -751,8 +752,8 @@ func TestMSSQL(t *testing.T) {
|
||||
|
||||
Convey("When doing a metric query using stored procedure should return correct result", func() {
|
||||
sqleng.Interpolate = origInterpolate
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
DataSource: &models.DataSource{JsonData: simplejson.New()},
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
@@ -763,16 +764,16 @@ func TestMSSQL(t *testing.T) {
|
||||
EXEC dbo.sp_test_epoch @from, @to`,
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
TimeRange: &tsdb.TimeRange{
|
||||
TimeRange: &plugins.DataTimeRange{
|
||||
From: "1521117000000",
|
||||
To: "1521122100000",
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
queryResult := resp.Results["A"]
|
||||
So(err, ShouldBeNil)
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -830,8 +831,8 @@ func TestMSSQL(t *testing.T) {
|
||||
|
||||
Convey("When doing a metric query using stored procedure should return correct result", func() {
|
||||
sqleng.Interpolate = origInterpolate
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
DataSource: &models.DataSource{JsonData: simplejson.New()},
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
@@ -842,16 +843,16 @@ func TestMSSQL(t *testing.T) {
|
||||
EXEC dbo.sp_test_epoch @from, @to`,
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
TimeRange: &tsdb.TimeRange{
|
||||
TimeRange: &plugins.DataTimeRange{
|
||||
From: "1521117000000",
|
||||
To: "1521122100000",
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
queryResult := resp.Results["A"]
|
||||
So(err, ShouldBeNil)
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -911,46 +912,46 @@ func TestMSSQL(t *testing.T) {
|
||||
}
|
||||
|
||||
Convey("When doing an annotation query of deploy events should return expected result", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": "SELECT time_sec as time, description as [text], tags FROM [event] WHERE $__unixEpochFilter(time_sec) AND tags='deploy' ORDER BY 1 ASC",
|
||||
"format": "table",
|
||||
}),
|
||||
RefId: "Deploys",
|
||||
RefID: "Deploys",
|
||||
},
|
||||
},
|
||||
TimeRange: &tsdb.TimeRange{
|
||||
TimeRange: &plugins.DataTimeRange{
|
||||
From: fmt.Sprintf("%v", fromStart.Add(-20*time.Minute).Unix()*1000),
|
||||
To: fmt.Sprintf("%v", fromStart.Add(40*time.Minute).Unix()*1000),
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
queryResult := resp.Results["Deploys"]
|
||||
So(err, ShouldBeNil)
|
||||
So(len(queryResult.Tables[0].Rows), ShouldEqual, 3)
|
||||
})
|
||||
|
||||
Convey("When doing an annotation query of ticket events should return expected result", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": "SELECT time_sec as time, description as [text], tags FROM [event] WHERE $__unixEpochFilter(time_sec) AND tags='ticket' ORDER BY 1 ASC",
|
||||
"format": "table",
|
||||
}),
|
||||
RefId: "Tickets",
|
||||
RefID: "Tickets",
|
||||
},
|
||||
},
|
||||
TimeRange: &tsdb.TimeRange{
|
||||
TimeRange: &plugins.DataTimeRange{
|
||||
From: fmt.Sprintf("%v", fromStart.Add(-20*time.Minute).Unix()*1000),
|
||||
To: fmt.Sprintf("%v", fromStart.Add(40*time.Minute).Unix()*1000),
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
queryResult := resp.Results["Tickets"]
|
||||
So(err, ShouldBeNil)
|
||||
So(len(queryResult.Tables[0].Rows), ShouldEqual, 3)
|
||||
@@ -960,8 +961,8 @@ func TestMSSQL(t *testing.T) {
|
||||
dt := time.Date(2018, 3, 14, 21, 20, 6, 527e6, time.UTC)
|
||||
dtFormat := "2006-01-02 15:04:05.999999999"
|
||||
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": fmt.Sprintf(`SELECT
|
||||
@@ -971,12 +972,12 @@ func TestMSSQL(t *testing.T) {
|
||||
`, dt.Format(dtFormat)),
|
||||
"format": "table",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -990,8 +991,8 @@ func TestMSSQL(t *testing.T) {
|
||||
Convey("When doing an annotation query with a time column in epoch second format should return ms", func() {
|
||||
dt := time.Date(2018, 3, 14, 21, 20, 6, 527e6, time.UTC)
|
||||
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": fmt.Sprintf(`SELECT
|
||||
@@ -1001,12 +1002,12 @@ func TestMSSQL(t *testing.T) {
|
||||
`, dt.Unix()),
|
||||
"format": "table",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -1020,8 +1021,8 @@ func TestMSSQL(t *testing.T) {
|
||||
Convey("When doing an annotation query with a time column in epoch second format (int) should return ms", func() {
|
||||
dt := time.Date(2018, 3, 14, 21, 20, 6, 527e6, time.UTC)
|
||||
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": fmt.Sprintf(`SELECT
|
||||
@@ -1031,12 +1032,12 @@ func TestMSSQL(t *testing.T) {
|
||||
`, dt.Unix()),
|
||||
"format": "table",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -1050,8 +1051,8 @@ func TestMSSQL(t *testing.T) {
|
||||
Convey("When doing an annotation query with a time column in epoch millisecond format should return ms", func() {
|
||||
dt := time.Date(2018, 3, 14, 21, 20, 6, 527e6, time.UTC)
|
||||
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": fmt.Sprintf(`SELECT
|
||||
@@ -1061,12 +1062,12 @@ func TestMSSQL(t *testing.T) {
|
||||
`, dt.Unix()*1000),
|
||||
"format": "table",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -1078,8 +1079,8 @@ func TestMSSQL(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("When doing an annotation query with a time column holding a bigint null value should return nil", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": `SELECT
|
||||
@@ -1089,12 +1090,12 @@ func TestMSSQL(t *testing.T) {
|
||||
`,
|
||||
"format": "table",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
@@ -1106,8 +1107,8 @@ func TestMSSQL(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("When doing an annotation query with a time column holding a datetime null value should return nil", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
query := plugins.DataQuery{
|
||||
Queries: []plugins.DataSubQuery{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": `SELECT
|
||||
@@ -1117,12 +1118,12 @@ func TestMSSQL(t *testing.T) {
|
||||
`,
|
||||
"format": "table",
|
||||
}),
|
||||
RefId: "A",
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(context.Background(), nil, query)
|
||||
resp, err := endpoint.DataQuery(context.Background(), nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
|
||||
Reference in New Issue
Block a user