Interpolate $__interval in backend for alerting with sql datasources (#13156)
add support for interpolate $__interval and $__interval_ms in sql datasources
This commit is contained in:
committed by
Marcus Efraimsson
parent
bae560717d
commit
0254a29e35
+49
-1
@@ -6,6 +6,7 @@ import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"math"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -43,6 +44,8 @@ var engineCache = engineCacheType{
|
||||
versions: make(map[int64]int),
|
||||
}
|
||||
|
||||
var sqlIntervalCalculator = NewIntervalCalculator(nil)
|
||||
|
||||
var NewXormEngine = func(driverName string, connectionString string) (*xorm.Engine, error) {
|
||||
return xorm.NewEngine(driverName, connectionString)
|
||||
}
|
||||
@@ -126,7 +129,15 @@ func (e *sqlQueryEndpoint) Query(ctx context.Context, dsInfo *models.DataSource,
|
||||
queryResult := &QueryResult{Meta: simplejson.New(), RefId: query.RefId}
|
||||
result.Results[query.RefId] = queryResult
|
||||
|
||||
rawSQL, err := e.macroEngine.Interpolate(query, tsdbQuery.TimeRange, rawSQL)
|
||||
// global substitutions
|
||||
rawSQL, err := Interpolate(query, tsdbQuery.TimeRange, rawSQL)
|
||||
if err != nil {
|
||||
queryResult.Error = err
|
||||
continue
|
||||
}
|
||||
|
||||
// datasource specific substitutions
|
||||
rawSQL, err = e.macroEngine.Interpolate(query, tsdbQuery.TimeRange, rawSQL)
|
||||
if err != nil {
|
||||
queryResult.Error = err
|
||||
continue
|
||||
@@ -163,6 +174,20 @@ func (e *sqlQueryEndpoint) Query(ctx context.Context, dsInfo *models.DataSource,
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// global macros/substitutions for all sql datasources
|
||||
var Interpolate = func(query *Query, timeRange *TimeRange, sql string) (string, error) {
|
||||
minInterval, err := GetIntervalFrom(query.DataSource, query.Model, time.Second*60)
|
||||
if err != nil {
|
||||
return sql, nil
|
||||
}
|
||||
interval := sqlIntervalCalculator.Calculate(timeRange, minInterval)
|
||||
|
||||
sql = strings.Replace(sql, "$__interval_ms", strconv.FormatInt(interval.Milliseconds(), 10), -1)
|
||||
sql = strings.Replace(sql, "$__interval", interval.Text, -1)
|
||||
|
||||
return sql, nil
|
||||
}
|
||||
|
||||
func (e *sqlQueryEndpoint) transformToTable(query *Query, rows *core.Rows, result *QueryResult, tsdbQuery *TsdbQuery) error {
|
||||
columnNames, err := rows.Columns()
|
||||
columnCount := len(columnNames)
|
||||
@@ -589,3 +614,26 @@ func SetupFillmode(query *Query, interval time.Duration, fillmode string) error
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type SqlMacroEngineBase struct{}
|
||||
|
||||
func NewSqlMacroEngineBase() *SqlMacroEngineBase {
|
||||
return &SqlMacroEngineBase{}
|
||||
}
|
||||
|
||||
func (m *SqlMacroEngineBase) ReplaceAllStringSubmatchFunc(re *regexp.Regexp, str string, repl func([]string) string) string {
|
||||
result := ""
|
||||
lastIndex := 0
|
||||
|
||||
for _, v := range re.FindAllSubmatchIndex([]byte(str), -1) {
|
||||
groups := []string{}
|
||||
for i := 0; i < len(v); i += 2 {
|
||||
groups = append(groups, str[v[i]:v[i+1]])
|
||||
}
|
||||
|
||||
result += str[lastIndex:v[0]] + repl(groups)
|
||||
lastIndex = v[1]
|
||||
}
|
||||
|
||||
return result + str[lastIndex:]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user