| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- // Copyright 2019 Yunion
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package influxdb
- import (
- "fmt"
- "strings"
- "yunion.io/x/onecloud/pkg/monitor/tsdb"
- )
- var renders map[string]QueryDefinition
- type DefinitionParameters struct {
- Name string
- Type string
- }
- type QueryDefinition struct {
- Renderer func(query *Query, queryCtx *tsdb.TsdbQuery, part *QueryPart, innerExpr string) string
- Params []DefinitionParameters
- }
- func init() {
- renders = make(map[string]QueryDefinition)
- renders["field"] = QueryDefinition{Renderer: fieldRenderer}
- renders["func_field"] = QueryDefinition{Renderer: funFieldRenderer}
- 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}
- renders["mode"] = QueryDefinition{Renderer: functionRenderer}
- renders["cumulative_sum"] = QueryDefinition{Renderer: functionRenderer}
- renders["non_negative_difference"] = QueryDefinition{Renderer: functionRenderer}
- 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"}},
- }
- renders["derivative"] = QueryDefinition{
- Renderer: functionRenderer,
- Params: []DefinitionParameters{{Name: "duration", Type: "interval"}},
- }
- renders["non_negative_derivative"] = QueryDefinition{
- Renderer: functionRenderer,
- Params: []DefinitionParameters{{Name: "duration", Type: "interval"}},
- }
- renders["difference"] = QueryDefinition{Renderer: functionRenderer}
- renders["moving_average"] = QueryDefinition{
- Renderer: functionRenderer,
- Params: []DefinitionParameters{{Name: "window", Type: "number"}},
- }
- renders["stddev"] = QueryDefinition{Renderer: functionRenderer}
- renders["time"] = QueryDefinition{
- Renderer: functionRenderer,
- Params: []DefinitionParameters{{Name: "interval", Type: "time"}, {Name: "offset", Type: "time"}},
- }
- renders["fill"] = QueryDefinition{
- Renderer: functionRenderer,
- Params: []DefinitionParameters{{Name: "fill", Type: "string"}},
- }
- renders["elapsed"] = QueryDefinition{
- Renderer: functionRenderer,
- Params: []DefinitionParameters{{Name: "duration", Type: "interval"}},
- }
- renders["bottom"] = QueryDefinition{
- Renderer: functionRenderer,
- Params: []DefinitionParameters{{Name: "count", Type: "int"}},
- }
- renders["first"] = QueryDefinition{Renderer: functionRenderer}
- renders["last"] = QueryDefinition{Renderer: functionRenderer}
- renders["max"] = QueryDefinition{Renderer: functionRenderer}
- renders["min"] = QueryDefinition{Renderer: functionRenderer}
- renders["abs"] = QueryDefinition{Renderer: functionRenderer}
- renders["percentile"] = QueryDefinition{
- Renderer: functionRenderer,
- Params: []DefinitionParameters{{Name: "nth", Type: "int"}},
- }
- renders["top"] = QueryDefinition{
- Renderer: functionRenderer,
- Params: []DefinitionParameters{{Name: "count", Type: "int"}},
- }
- renders["tag"] = QueryDefinition{
- Renderer: tagRenderer,
- Params: []DefinitionParameters{{Name: "tag", Type: "string"}},
- }
- renders["math"] = QueryDefinition{Renderer: suffixRenderer}
- renders["alias"] = QueryDefinition{Renderer: aliasRenderer}
- renders["slimit"] = QueryDefinition{Renderer: typeRenderer}
- renders["soffset"] = QueryDefinition{Renderer: typeRenderer}
- }
- func fieldRenderer(query *Query, queryCtx *tsdb.TsdbQuery, part *QueryPart, innerExpr string) string {
- if part.Params[0] == "*" {
- // return "*::field"
- return "*"
- }
- // return fmt.Sprintf(`"%s"::field`, part.Params[0])
- return fmt.Sprintf(`"%s"`, part.Params[0])
- }
- func funFieldRenderer(query *Query, queryCtx *tsdb.TsdbQuery, part *QueryPart, innerExpr string) string {
- if part.Params[0] == "*" {
- // return "*::field"
- return "*"
- }
- if len(innerExpr) != 0 {
- part.Params = append([]string{innerExpr}, part.Params...)
- }
- stringB := strings.Builder{}
- for i, str := range part.Params {
- stringB.WriteString(fmt.Sprintf(`"%s"`, str))
- if i != len(part.Params)-1 {
- stringB.WriteString(",")
- }
- }
- return stringB.String()
- }
- func tagRenderer(query *Query, queryCtx *tsdb.TsdbQuery, part *QueryPart, innerExpr string) string {
- if part.Params[0] == "*" {
- // return "*::tag"
- return "*"
- }
- // return fmt.Sprintf(`"%s"::tag`, part.Params[0])
- return fmt.Sprintf(`"%s"`, part.Params[0])
- }
- func functionRenderer(query *Query, queryCtx *tsdb.TsdbQuery, part *QueryPart, innerExpr string) string {
- for i, param := range part.Params {
- if part.Type == "time" && param == "auto" {
- part.Params[i] = "$__interval"
- }
- }
- if innerExpr != "" {
- part.Params = append([]string{innerExpr}, part.Params...)
- }
- params := strings.Join(part.Params, ", ")
- return fmt.Sprintf("%s(%s)", part.Type, params)
- }
- func suffixRenderer(query *Query, queryCtx *tsdb.TsdbQuery, part *QueryPart, innerExpr string) string {
- return fmt.Sprintf("%s %s", innerExpr, part.Params[0])
- }
- func aliasRenderer(query *Query, queryCtx *tsdb.TsdbQuery, part *QueryPart, innerExpr string) string {
- return fmt.Sprintf(`%s AS "%s"`, innerExpr, part.Params[0])
- }
- func typeRenderer(query *Query, queryCtx *tsdb.TsdbQuery, part *QueryPart, innerExpr string) string {
- return fmt.Sprintf(" %s %s", part.Type, part.Params[0])
- }
- func (r QueryDefinition) Render(query *Query, queryCtx *tsdb.TsdbQuery, part *QueryPart, innerExpr string) string {
- return r.Renderer(query, queryCtx, part, innerExpr)
- }
- func NewQueryPart(typ string, params []string) (*QueryPart, error) {
- def, exist := renders[typ]
- if !exist {
- return nil, fmt.Errorf("Missing query definition for %s", typ)
- }
- return &QueryPart{
- Def: def,
- Type: typ,
- Params: params,
- }, nil
- }
- type QueryPart struct {
- Def QueryDefinition
- Type string
- Params []string
- }
- func (qp *QueryPart) Render(query *Query, queryCtx *tsdb.TsdbQuery, expr string) string {
- return qp.Def.Renderer(query, queryCtx, qp, expr)
- }
|