mirror of https://github.com/grafana/grafana
parent
62d11c147b
commit
e164eba677
@ -0,0 +1,75 @@ |
||||
package mysql |
||||
|
||||
import ( |
||||
"fmt" |
||||
"regexp" |
||||
|
||||
"github.com/grafana/grafana/pkg/tsdb" |
||||
) |
||||
|
||||
//const rsString = `(?:"([^"]*)")`;
|
||||
const rsIdentifier = `([_a-zA-Z0-9]+)` |
||||
const sExpr = `\$` + rsIdentifier + `\((.*)\)` |
||||
|
||||
type SqlMacroEngine interface { |
||||
Interpolate(sql string) (string, error) |
||||
} |
||||
|
||||
type MySqlMacroEngine struct { |
||||
TimeRange *tsdb.TimeRange |
||||
} |
||||
|
||||
func NewMysqlMacroEngine(timeRange *tsdb.TimeRange) SqlMacroEngine { |
||||
return &MySqlMacroEngine{ |
||||
TimeRange: timeRange, |
||||
} |
||||
} |
||||
|
||||
func (m *MySqlMacroEngine) Interpolate(sql string) (string, error) { |
||||
rExp, _ := regexp.Compile(sExpr) |
||||
var macroError error |
||||
|
||||
sql = ReplaceAllStringSubmatchFunc(rExp, sql, func(groups []string) string { |
||||
res, err := m.EvaluateMacro(groups[1], groups[2:len(groups)]) |
||||
if macroError != nil { |
||||
macroError = err |
||||
return "macro_error()" |
||||
} |
||||
return res |
||||
}) |
||||
|
||||
if macroError != nil { |
||||
return "", macroError |
||||
} |
||||
|
||||
return sql, nil |
||||
} |
||||
|
||||
func 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:] |
||||
} |
||||
|
||||
func (m *MySqlMacroEngine) EvaluateMacro(name string, args []string) (string, error) { |
||||
switch name { |
||||
case "__time": |
||||
if len(args) == 0 { |
||||
return "", fmt.Errorf("missing time column argument for macro %v", name) |
||||
} |
||||
return "UNIX_TIMESTAMP(" + args[0] + ") as time_sec", nil |
||||
default: |
||||
return "", fmt.Errorf("Unknown macro %v", name) |
||||
} |
||||
} |
||||
@ -0,0 +1,22 @@ |
||||
package mysql |
||||
|
||||
import ( |
||||
"testing" |
||||
|
||||
. "github.com/smartystreets/goconvey/convey" |
||||
) |
||||
|
||||
func TestMacroEngine(t *testing.T) { |
||||
Convey("MacroEngine", t, func() { |
||||
|
||||
Convey("interpolate simple function", func() { |
||||
engine := &MySqlMacroEngine{} |
||||
|
||||
sql, err := engine.Interpolate("select $__time(time_column)") |
||||
So(err, ShouldBeNil) |
||||
|
||||
So(sql, ShouldEqual, "select UNIX_TIMESTAMP(time_column) as time_sec") |
||||
}) |
||||
|
||||
}) |
||||
} |
||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Loading…
Reference in new issue