2016-10-05 03:56:34 -05:00
|
|
|
package influxdb
|
|
|
|
|
2016-10-05 07:42:06 -05:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
2016-10-10 00:12:21 -05:00
|
|
|
|
2021-07-19 04:32:33 -05:00
|
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
2016-10-05 07:42:06 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
var renders map[string]QueryDefinition
|
|
|
|
|
2016-10-05 09:59:33 -05:00
|
|
|
type DefinitionParameters struct {
|
|
|
|
Name string
|
|
|
|
Type string
|
|
|
|
}
|
|
|
|
|
2016-10-05 07:42:06 -05:00
|
|
|
type QueryDefinition struct {
|
2021-07-19 04:32:33 -05:00
|
|
|
Renderer func(query *Query, queryContext *backend.QueryDataRequest, part *QueryPart, innerExpr string) string
|
2016-10-05 09:59:33 -05:00
|
|
|
Params []DefinitionParameters
|
2016-10-05 07:42:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
renders = make(map[string]QueryDefinition)
|
|
|
|
|
|
|
|
renders["field"] = QueryDefinition{Renderer: fieldRenderer}
|
|
|
|
|
|
|
|
renders["spread"] = QueryDefinition{Renderer: functionRenderer}
|
|
|
|
renders["count"] = QueryDefinition{Renderer: functionRenderer}
|
|
|
|
renders["distinct"] = QueryDefinition{Renderer: functionRenderer}
|
|
|
|
renders["integral"] = QueryDefinition{Renderer: functionRenderer}
|
|
|
|
renders["mean"] = QueryDefinition{Renderer: functionRenderer}
|
|
|
|
renders["median"] = QueryDefinition{Renderer: functionRenderer}
|
|
|
|
renders["sum"] = QueryDefinition{Renderer: functionRenderer}
|
2018-06-14 13:18:30 -05:00
|
|
|
renders["mode"] = QueryDefinition{Renderer: functionRenderer}
|
2018-12-04 11:06:48 -06:00
|
|
|
renders["cumulative_sum"] = QueryDefinition{Renderer: functionRenderer}
|
2019-02-13 06:25:31 -06:00
|
|
|
renders["non_negative_difference"] = QueryDefinition{Renderer: functionRenderer}
|
2016-10-05 07:42:06 -05:00
|
|
|
|
2016-12-21 16:54:56 -06:00
|
|
|
renders["holt_winters"] = QueryDefinition{
|
|
|
|
Renderer: functionRenderer,
|
|
|
|
Params: []DefinitionParameters{{Name: "number", Type: "number"}, {Name: "season", Type: "number"}},
|
|
|
|
}
|
|
|
|
renders["holt_winters_with_fit"] = QueryDefinition{
|
|
|
|
Renderer: functionRenderer,
|
|
|
|
Params: []DefinitionParameters{{Name: "number", Type: "number"}, {Name: "season", Type: "number"}},
|
|
|
|
}
|
|
|
|
|
2016-10-05 07:42:06 -05:00
|
|
|
renders["derivative"] = QueryDefinition{
|
|
|
|
Renderer: functionRenderer,
|
2016-10-05 09:59:33 -05:00
|
|
|
Params: []DefinitionParameters{{Name: "duration", Type: "interval"}},
|
2016-10-05 07:42:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
renders["non_negative_derivative"] = QueryDefinition{
|
|
|
|
Renderer: functionRenderer,
|
2016-10-05 09:59:33 -05:00
|
|
|
Params: []DefinitionParameters{{Name: "duration", Type: "interval"}},
|
2016-10-05 07:42:06 -05:00
|
|
|
}
|
|
|
|
renders["difference"] = QueryDefinition{Renderer: functionRenderer}
|
|
|
|
renders["moving_average"] = QueryDefinition{
|
|
|
|
Renderer: functionRenderer,
|
2016-10-05 09:59:33 -05:00
|
|
|
Params: []DefinitionParameters{{Name: "window", Type: "number"}},
|
2016-10-05 07:42:06 -05:00
|
|
|
}
|
|
|
|
renders["stddev"] = QueryDefinition{Renderer: functionRenderer}
|
|
|
|
renders["time"] = QueryDefinition{
|
|
|
|
Renderer: functionRenderer,
|
2016-12-21 16:54:56 -06:00
|
|
|
Params: []DefinitionParameters{{Name: "interval", Type: "time"}, {Name: "offset", Type: "time"}},
|
2016-10-05 07:42:06 -05:00
|
|
|
}
|
|
|
|
renders["fill"] = QueryDefinition{
|
|
|
|
Renderer: functionRenderer,
|
2016-10-05 09:59:33 -05:00
|
|
|
Params: []DefinitionParameters{{Name: "fill", Type: "string"}},
|
2016-10-05 07:42:06 -05:00
|
|
|
}
|
|
|
|
renders["elapsed"] = QueryDefinition{
|
|
|
|
Renderer: functionRenderer,
|
2016-10-05 09:59:33 -05:00
|
|
|
Params: []DefinitionParameters{{Name: "duration", Type: "interval"}},
|
2016-10-05 07:42:06 -05:00
|
|
|
}
|
|
|
|
renders["bottom"] = QueryDefinition{
|
|
|
|
Renderer: functionRenderer,
|
2016-10-05 09:59:33 -05:00
|
|
|
Params: []DefinitionParameters{{Name: "count", Type: "int"}},
|
2016-10-05 07:42:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
renders["first"] = QueryDefinition{Renderer: functionRenderer}
|
|
|
|
renders["last"] = QueryDefinition{Renderer: functionRenderer}
|
|
|
|
renders["max"] = QueryDefinition{Renderer: functionRenderer}
|
|
|
|
renders["min"] = QueryDefinition{Renderer: functionRenderer}
|
|
|
|
renders["percentile"] = QueryDefinition{
|
|
|
|
Renderer: functionRenderer,
|
2016-10-05 09:59:33 -05:00
|
|
|
Params: []DefinitionParameters{{Name: "nth", Type: "int"}},
|
2016-10-05 07:42:06 -05:00
|
|
|
}
|
|
|
|
renders["top"] = QueryDefinition{
|
|
|
|
Renderer: functionRenderer,
|
2016-10-05 09:59:33 -05:00
|
|
|
Params: []DefinitionParameters{{Name: "count", Type: "int"}},
|
2016-10-05 07:42:06 -05:00
|
|
|
}
|
|
|
|
renders["tag"] = QueryDefinition{
|
|
|
|
Renderer: fieldRenderer,
|
2016-10-05 09:59:33 -05:00
|
|
|
Params: []DefinitionParameters{{Name: "tag", Type: "string"}},
|
2016-10-05 07:42:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
renders["math"] = QueryDefinition{Renderer: suffixRenderer}
|
|
|
|
renders["alias"] = QueryDefinition{Renderer: aliasRenderer}
|
|
|
|
}
|
|
|
|
|
2021-07-19 04:32:33 -05:00
|
|
|
func fieldRenderer(query *Query, queryContext *backend.QueryDataRequest, part *QueryPart, innerExpr string) string {
|
2016-10-05 07:42:06 -05:00
|
|
|
if part.Params[0] == "*" {
|
|
|
|
return "*"
|
|
|
|
}
|
2016-10-05 09:59:33 -05:00
|
|
|
return fmt.Sprintf(`"%s"`, part.Params[0])
|
2016-10-05 07:42:06 -05:00
|
|
|
}
|
|
|
|
|
2021-07-19 04:32:33 -05:00
|
|
|
func functionRenderer(query *Query, queryContext *backend.QueryDataRequest, part *QueryPart, innerExpr string) string {
|
2016-10-14 02:14:13 -05:00
|
|
|
for i, param := range part.Params {
|
2017-01-11 05:10:26 -06:00
|
|
|
if part.Type == "time" && param == "auto" {
|
|
|
|
part.Params[i] = "$__interval"
|
2016-10-06 05:51:45 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-05 13:36:05 -05:00
|
|
|
if innerExpr != "" {
|
|
|
|
part.Params = append([]string{innerExpr}, part.Params...)
|
2016-10-05 07:42:06 -05:00
|
|
|
}
|
|
|
|
|
2016-10-05 13:36:05 -05:00
|
|
|
params := strings.Join(part.Params, ", ")
|
|
|
|
|
|
|
|
return fmt.Sprintf("%s(%s)", part.Type, params)
|
2016-10-05 07:42:06 -05:00
|
|
|
}
|
|
|
|
|
2021-07-19 04:32:33 -05:00
|
|
|
func suffixRenderer(query *Query, queryContext *backend.QueryDataRequest, part *QueryPart, innerExpr string) string {
|
2016-10-05 07:42:06 -05:00
|
|
|
return fmt.Sprintf("%s %s", innerExpr, part.Params[0])
|
|
|
|
}
|
|
|
|
|
2021-07-19 04:32:33 -05:00
|
|
|
func aliasRenderer(query *Query, queryContext *backend.QueryDataRequest, part *QueryPart, innerExpr string) string {
|
2016-10-05 07:42:06 -05:00
|
|
|
return fmt.Sprintf(`%s AS "%s"`, innerExpr, part.Params[0])
|
|
|
|
}
|
|
|
|
|
2016-10-05 09:59:33 -05:00
|
|
|
func NewQueryPart(typ string, params []string) (*QueryPart, error) {
|
|
|
|
def, exist := renders[typ]
|
|
|
|
if !exist {
|
2020-08-13 10:50:53 -05:00
|
|
|
return nil, fmt.Errorf("missing query definition for %q", typ)
|
2016-10-05 09:59:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return &QueryPart{
|
|
|
|
Type: typ,
|
|
|
|
Params: params,
|
|
|
|
Def: def,
|
|
|
|
}, nil
|
2016-10-05 07:42:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
type QueryPart struct {
|
2016-10-05 09:59:33 -05:00
|
|
|
Def QueryDefinition
|
2016-10-05 07:42:06 -05:00
|
|
|
Type string
|
|
|
|
Params []string
|
|
|
|
}
|
|
|
|
|
2021-07-19 04:32:33 -05:00
|
|
|
func (qp *QueryPart) Render(query *Query, queryContext *backend.QueryDataRequest, expr string) string {
|
2016-10-13 04:42:51 -05:00
|
|
|
return qp.Def.Renderer(query, queryContext, qp, expr)
|
2016-10-05 03:56:34 -05:00
|
|
|
}
|