Add InfluxQL template rendering
parent
8781d1fedc
commit
f17cf6bb09
|
@ -0,0 +1,53 @@
|
||||||
|
package influx
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
// TempValue is a value use to replace a template in an InfluxQL query
|
||||||
|
type TempValue struct {
|
||||||
|
Value string `json:"value"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TempVar is a named variable within an InfluxQL query to be replaced with Values
|
||||||
|
type TempVar struct {
|
||||||
|
Var string `json:"tempVar"`
|
||||||
|
Values []TempValue `json:"values"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// String converts the template variable into a correct InfluxQL string based
|
||||||
|
// on its type
|
||||||
|
func (t TempVar) String() string {
|
||||||
|
if len(t.Values) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
switch t.Values[0].Type {
|
||||||
|
case "tagKey", "fieldKey":
|
||||||
|
return `"` + t.Values[0].Value + `"`
|
||||||
|
case "tagValue":
|
||||||
|
return `'` + t.Values[0].Value + `'`
|
||||||
|
case "csv":
|
||||||
|
return t.Values[0].Value
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TempVars are template variables to replace within an InfluxQL query
|
||||||
|
type TempVars struct {
|
||||||
|
Vars []TempVar `json:"tempVars"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TemplateReplace replaces templates with values within the query string
|
||||||
|
func TemplateReplace(query string, templates TempVars) string {
|
||||||
|
replacements := []string{}
|
||||||
|
for _, v := range templates.Vars {
|
||||||
|
newVal := v.String()
|
||||||
|
if newVal != "" {
|
||||||
|
replacements = append(replacements, v.Var, newVal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
replacer := strings.NewReplacer(replacements...)
|
||||||
|
replaced := replacer.Replace(query)
|
||||||
|
return replaced
|
||||||
|
}
|
|
@ -0,0 +1,139 @@
|
||||||
|
package influx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTemplateReplace(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
query string
|
||||||
|
vars TempVars
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "select with parameters",
|
||||||
|
query: "$METHOD field1, $field FROM $measurement WHERE temperature > $temperature",
|
||||||
|
vars: TempVars{
|
||||||
|
Vars: []TempVar{
|
||||||
|
{
|
||||||
|
Var: "$temperature",
|
||||||
|
Values: []TempValue{
|
||||||
|
{
|
||||||
|
Type: "csv",
|
||||||
|
Value: "10",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Var: "$field",
|
||||||
|
Values: []TempValue{
|
||||||
|
{
|
||||||
|
Type: "fieldKey",
|
||||||
|
Value: "field2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Var: "$METHOD",
|
||||||
|
Values: []TempValue{
|
||||||
|
{
|
||||||
|
Type: "csv",
|
||||||
|
Value: "SELECT",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Var: "$measurement",
|
||||||
|
Values: []TempValue{
|
||||||
|
{
|
||||||
|
Type: "csv",
|
||||||
|
Value: `"cpu"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: `SELECT field1, "field2" FROM "cpu" WHERE temperature > 10`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "select with parameters and aggregates",
|
||||||
|
query: `SELECT mean($field) FROM "cpu" WHERE $tag = $value GROUP BY $tag`,
|
||||||
|
vars: TempVars{
|
||||||
|
Vars: []TempVar{
|
||||||
|
{
|
||||||
|
Var: "$value",
|
||||||
|
Values: []TempValue{
|
||||||
|
{
|
||||||
|
Type: "tagValue",
|
||||||
|
Value: "howdy.com",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Var: "$tag",
|
||||||
|
Values: []TempValue{
|
||||||
|
{
|
||||||
|
Type: "tagKey",
|
||||||
|
Value: "host",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Var: "$field",
|
||||||
|
Values: []TempValue{
|
||||||
|
{
|
||||||
|
Type: "fieldKey",
|
||||||
|
Value: "field",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: `SELECT mean("field") FROM "cpu" WHERE "host" = 'howdy.com' GROUP BY "host"`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Non-existant parameters",
|
||||||
|
query: `SELECT $field FROM "cpu"`,
|
||||||
|
want: `SELECT $field FROM "cpu"`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "var without a value",
|
||||||
|
query: `SELECT $field FROM "cpu"`,
|
||||||
|
vars: TempVars{
|
||||||
|
Vars: []TempVar{
|
||||||
|
{
|
||||||
|
Var: "$field",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: `SELECT $field FROM "cpu"`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "var with unknown type",
|
||||||
|
query: `SELECT $field FROM "cpu"`,
|
||||||
|
vars: TempVars{
|
||||||
|
Vars: []TempVar{
|
||||||
|
{
|
||||||
|
Var: "$field",
|
||||||
|
Values: []TempValue{
|
||||||
|
{
|
||||||
|
Type: "who knows?",
|
||||||
|
Value: "field",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: `SELECT $field FROM "cpu"`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := TemplateReplace(tt.query, tt.vars)
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("TestParse %s =\n%s\nwant\n%s", tt.name, got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue