Commit 11806dfa by Torkel Ödegaard

mysql: progress

parent 1e29d4fc
......@@ -45,10 +45,11 @@ func (br *BatchResult) WithError(err error) *BatchResult {
}
type QueryResult struct {
Error error `json:"-"`
ErrorString string `json:"error"`
RefId string `json:"refId"`
Series TimeSeriesSlice `json:"series"`
Error error `json:"-"`
ErrorString string `json:"error,omitempty"`
RefId string `json:"refId"`
Meta *simplejson.Json `json:"meta,omitempty"`
Series TimeSeriesSlice `json:"series"`
}
type TimeSeries struct {
......
......@@ -30,8 +30,8 @@ func (m *MySqlMacroEngine) Interpolate(sql string) (string, error) {
var macroError error
sql = ReplaceAllStringSubmatchFunc(rExp, sql, func(groups []string) string {
res, err := m.EvaluateMacro(groups[1], groups[2:len(groups)])
if macroError != nil {
res, err := m.EvaluateMacro(groups[1], groups[2:])
if err != nil && macroError == nil {
macroError = err
return "macro_error()"
}
......@@ -68,7 +68,12 @@ func (m *MySqlMacroEngine) EvaluateMacro(name string, args []string) (string, er
if len(args) == 0 {
return "", fmt.Errorf("missing time column argument for macro %v", name)
}
return "UNIX_TIMESTAMP(" + args[0] + ") as time_sec", nil
return fmt.Sprintf("UNIX_TIMESTAMP(%s) as time_sec", args[0]), nil
case "__timeFilter":
if len(args) == 0 {
return "", fmt.Errorf("missing time column argument for macro %v", name)
}
return fmt.Sprintf("UNIX_TIMESTAMP(%s) > %d AND UNIX_TIMESTAMP(%s) < %d", args[0], uint64(m.TimeRange.GetFromAsMsEpoch()/1000), args[0], uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil
default:
return "", fmt.Errorf("Unknown macro %v", name)
}
......
......@@ -3,13 +3,14 @@ package mysql
import (
"testing"
"github.com/grafana/grafana/pkg/tsdb"
. "github.com/smartystreets/goconvey/convey"
)
func TestMacroEngine(t *testing.T) {
Convey("MacroEngine", t, func() {
Convey("interpolate simple function", func() {
Convey("interpolate __time function", func() {
engine := &MySqlMacroEngine{}
sql, err := engine.Interpolate("select $__time(time_column)")
......@@ -18,5 +19,16 @@ func TestMacroEngine(t *testing.T) {
So(sql, ShouldEqual, "select UNIX_TIMESTAMP(time_column) as time_sec")
})
Convey("interpolate __timeFilter function", func() {
engine := &MySqlMacroEngine{
TimeRange: &tsdb.TimeRange{From: "5m", To: "now"},
}
sql, err := engine.Interpolate("WHERE $__timeFilter(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, "WHERE UNIX_TIMESTAMP(time_column) > 18446744066914186738 AND UNIX_TIMESTAMP(time_column) < 18446744066914187038")
})
})
}
......@@ -10,6 +10,7 @@ import (
"github.com/go-xorm/core"
"github.com/go-xorm/xorm"
"github.com/grafana/grafana/pkg/components/null"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/tsdb"
......@@ -81,6 +82,7 @@ func (e *MysqlExecutor) Execute(ctx context.Context, queries tsdb.QuerySlice, co
QueryResults: make(map[string]*tsdb.QueryResult),
}
macroEngine := NewMysqlMacroEngine(context.TimeRange)
session := e.engine.NewSession()
defer session.Close()
db := session.DB()
......@@ -91,9 +93,20 @@ func (e *MysqlExecutor) Execute(ctx context.Context, queries tsdb.QuerySlice, co
continue
}
queryResult := &tsdb.QueryResult{Meta: simplejson.New(), RefId: query.RefId}
result.QueryResults[query.RefId] = queryResult
rawSql, err := macroEngine.Interpolate(rawSql)
if err != nil {
queryResult.Error = err
continue
}
queryResult.Meta.Set("sql", rawSql)
rows, err := db.Query(rawSql)
if err != nil {
result.QueryResults[query.RefId] = &tsdb.QueryResult{Error: err}
queryResult.Error = err
continue
}
......@@ -101,16 +114,24 @@ func (e *MysqlExecutor) Execute(ctx context.Context, queries tsdb.QuerySlice, co
res, err := e.TransformToTimeSeries(query, rows)
if err != nil {
result.Error = err
queryResult.Error = err
return result
}
result.QueryResults[query.RefId] = &tsdb.QueryResult{RefId: query.RefId, Series: res}
queryResult.Series = res
queryResult.Meta.Set("rowCount", countPointsInAllSeries(res))
}
return result
}
func countPointsInAllSeries(seriesList tsdb.TimeSeriesSlice) (count int) {
for _, series := range seriesList {
count += len(series.Points)
}
return count
}
func (e MysqlExecutor) TransformToTimeSeries(query *tsdb.Query, rows *core.Rows) (tsdb.TimeSeriesSlice, error) {
pointsBySeries := make(map[string]*tsdb.TimeSeries)
columnNames, err := rows.Columns()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment