grafana/pkg/tsdb/influxdb/flux/macros.go
Andreas Christou f5926af99a
InfluxDB: Update macro regexp (#93040)
Update macro and tests
2024-09-11 14:26:09 +01:00

73 lines
2.3 KiB
Go

package flux
import (
"regexp"
"strconv"
"strings"
"time"
"github.com/grafana/grafana-plugin-sdk-go/backend/gtime"
)
// $__interval_ms is the exact value in milliseconds
// $__interval is rounded to nice whole values
// v.windowPeriod is the exact value string-formatted
func interpolateInterval(flux string, interval time.Duration) string {
intervalMs := int64(interval / time.Millisecond)
intervalText := gtime.FormatInterval(interval)
flux = strings.ReplaceAll(flux, "$__interval_ms", strconv.FormatInt(intervalMs, 10))
flux = strings.ReplaceAll(flux, "$__interval", intervalText)
return flux
}
var fluxVariableFilterExp = regexp.MustCompile(`(?m)(v)\.([a-zA-Z]+)`)
func interpolateFluxSpecificVariables(query queryModel) string {
rawQuery := query.RawQuery
flux := query.RawQuery
matches := fluxVariableFilterExp.FindAllStringSubmatchIndex(rawQuery, -1)
if matches != nil {
timeRange := query.TimeRange
from := timeRange.From.UTC().Format(time.RFC3339Nano)
to := timeRange.To.UTC().Format(time.RFC3339Nano)
for _, match := range matches {
// For query "range(start: v.timeRangeStart, stop: v.timeRangeStop)"
// rawQuery[match[0]:match[1]] will be v.timeRangeStart
// rawQuery[match[2]:match[3]] will be v
// rawQuery[match[4]:match[5]] will be timeRangeStart
fullMatch := rawQuery[match[0]:match[1]]
key := rawQuery[match[4]:match[5]]
switch key {
case "timeRangeStart":
flux = strings.ReplaceAll(flux, fullMatch, from)
case "timeRangeStop":
flux = strings.ReplaceAll(flux, fullMatch, to)
case "windowPeriod":
flux = strings.ReplaceAll(flux, fullMatch, query.Interval.String())
case "bucket":
// Check if 'bucket' is part of a join query
beforeMatch := rawQuery[:match[0]]
if strings.Contains(beforeMatch, "join.") {
continue
}
flux = strings.ReplaceAll(flux, fullMatch, "\""+query.Options.Bucket+"\"")
case "defaultBucket":
flux = strings.ReplaceAll(flux, fullMatch, "\""+query.Options.DefaultBucket+"\"")
case "organization":
flux = strings.ReplaceAll(flux, fullMatch, "\""+query.Options.Organization+"\"")
}
}
}
return flux
}
func interpolate(query queryModel) string {
flux := interpolateFluxSpecificVariables(query)
flux = interpolateInterval(flux, query.Interval)
return flux
}