query_part.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. package influxdb
  2. import (
  3. "fmt"
  4. "strings"
  5. "github.com/grafana/grafana/pkg/tsdb"
  6. )
  7. var renders map[string]QueryDefinition
  8. type DefinitionParameters struct {
  9. Name string
  10. Type string
  11. }
  12. type QueryDefinition struct {
  13. Renderer func(queryContext *tsdb.QueryContext, part *QueryPart, innerExpr string) string
  14. Params []DefinitionParameters
  15. }
  16. func init() {
  17. renders = make(map[string]QueryDefinition)
  18. renders["field"] = QueryDefinition{Renderer: fieldRenderer}
  19. renders["spread"] = QueryDefinition{Renderer: functionRenderer}
  20. renders["count"] = QueryDefinition{Renderer: functionRenderer}
  21. renders["distinct"] = QueryDefinition{Renderer: functionRenderer}
  22. renders["integral"] = QueryDefinition{Renderer: functionRenderer}
  23. renders["mean"] = QueryDefinition{Renderer: functionRenderer}
  24. renders["median"] = QueryDefinition{Renderer: functionRenderer}
  25. renders["sum"] = QueryDefinition{Renderer: functionRenderer}
  26. renders["derivative"] = QueryDefinition{
  27. Renderer: functionRenderer,
  28. Params: []DefinitionParameters{{Name: "duration", Type: "interval"}},
  29. }
  30. renders["non_negative_derivative"] = QueryDefinition{
  31. Renderer: functionRenderer,
  32. Params: []DefinitionParameters{{Name: "duration", Type: "interval"}},
  33. }
  34. renders["difference"] = QueryDefinition{Renderer: functionRenderer}
  35. renders["moving_average"] = QueryDefinition{
  36. Renderer: functionRenderer,
  37. Params: []DefinitionParameters{{Name: "window", Type: "number"}},
  38. }
  39. renders["stddev"] = QueryDefinition{Renderer: functionRenderer}
  40. renders["time"] = QueryDefinition{
  41. Renderer: functionRenderer,
  42. Params: []DefinitionParameters{{Name: "interval", Type: "time"}},
  43. }
  44. renders["fill"] = QueryDefinition{
  45. Renderer: functionRenderer,
  46. Params: []DefinitionParameters{{Name: "fill", Type: "string"}},
  47. }
  48. renders["elapsed"] = QueryDefinition{
  49. Renderer: functionRenderer,
  50. Params: []DefinitionParameters{{Name: "duration", Type: "interval"}},
  51. }
  52. renders["bottom"] = QueryDefinition{
  53. Renderer: functionRenderer,
  54. Params: []DefinitionParameters{{Name: "count", Type: "int"}},
  55. }
  56. renders["first"] = QueryDefinition{Renderer: functionRenderer}
  57. renders["last"] = QueryDefinition{Renderer: functionRenderer}
  58. renders["max"] = QueryDefinition{Renderer: functionRenderer}
  59. renders["min"] = QueryDefinition{Renderer: functionRenderer}
  60. renders["percentile"] = QueryDefinition{
  61. Renderer: functionRenderer,
  62. Params: []DefinitionParameters{{Name: "nth", Type: "int"}},
  63. }
  64. renders["top"] = QueryDefinition{
  65. Renderer: functionRenderer,
  66. Params: []DefinitionParameters{{Name: "count", Type: "int"}},
  67. }
  68. renders["tag"] = QueryDefinition{
  69. Renderer: fieldRenderer,
  70. Params: []DefinitionParameters{{Name: "tag", Type: "string"}},
  71. }
  72. renders["math"] = QueryDefinition{Renderer: suffixRenderer}
  73. renders["alias"] = QueryDefinition{Renderer: aliasRenderer}
  74. }
  75. func fieldRenderer(queryContext *tsdb.QueryContext, part *QueryPart, innerExpr string) string {
  76. if part.Params[0] == "*" {
  77. return "*"
  78. }
  79. return fmt.Sprintf(`"%s"`, part.Params[0])
  80. }
  81. func functionRenderer(queryContext *tsdb.QueryContext, part *QueryPart, innerExpr string) string {
  82. for i, v := range part.Params {
  83. if v == "$interval" {
  84. part.Params[i] = tsdb.CalculateInterval(queryContext.TimeRange)
  85. }
  86. }
  87. if innerExpr != "" {
  88. part.Params = append([]string{innerExpr}, part.Params...)
  89. }
  90. params := strings.Join(part.Params, ", ")
  91. return fmt.Sprintf("%s(%s)", part.Type, params)
  92. }
  93. func suffixRenderer(queryContext *tsdb.QueryContext, part *QueryPart, innerExpr string) string {
  94. return fmt.Sprintf("%s %s", innerExpr, part.Params[0])
  95. }
  96. func aliasRenderer(queryContext *tsdb.QueryContext, part *QueryPart, innerExpr string) string {
  97. return fmt.Sprintf(`%s AS "%s"`, innerExpr, part.Params[0])
  98. }
  99. func (r QueryDefinition) Render(queryContext *tsdb.QueryContext, part *QueryPart, innerExpr string) string {
  100. return r.Renderer(queryContext, part, innerExpr)
  101. }
  102. func NewQueryPart(typ string, params []string) (*QueryPart, error) {
  103. def, exist := renders[typ]
  104. if !exist {
  105. return nil, fmt.Errorf("Missing query definition for %s", typ)
  106. }
  107. return &QueryPart{
  108. Type: typ,
  109. Params: params,
  110. Def: def,
  111. }, nil
  112. }
  113. type QueryPart struct {
  114. Def QueryDefinition
  115. Type string
  116. Params []string
  117. }
  118. func (qp *QueryPart) Render(queryContext *tsdb.QueryContext, expr string) string {
  119. return qp.Def.Renderer(queryContext, qp, expr)
  120. }