query_part.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. import _ from 'lodash';
  2. import { QueryPartDef, QueryPart, functionRenderer, suffixRenderer } from 'app/core/components/query_part/query_part';
  3. var index = [];
  4. var categories = {
  5. Aggregations: [],
  6. Math: [],
  7. Aliasing: [],
  8. Columns: [],
  9. };
  10. function createPart(part): any {
  11. var def = index[part.type];
  12. if (!def) {
  13. throw { message: 'Could not find query part ' + part.type };
  14. }
  15. return new QueryPart(part, def);
  16. }
  17. function register(options: any) {
  18. index[options.type] = new QueryPartDef(options);
  19. options.category.push(index[options.type]);
  20. }
  21. function registerAggregate(name: string) {
  22. register({
  23. type: name,
  24. addStrategy: replaceAggregationAddStrategy,
  25. category: categories.Aggregations,
  26. params: [],
  27. defaultParams: [],
  28. renderer: functionRenderer,
  29. });
  30. }
  31. var groupByTimeFunctions = [];
  32. function aliasRenderer(part, innerExpr) {
  33. return innerExpr + ' AS ' + '"' + part.params[0] + '"';
  34. }
  35. function columnRenderer(part, innerExpr) {
  36. return '"' + part.params[0] + '"';
  37. }
  38. function replaceAggregationAddStrategy(selectParts, partModel) {
  39. // look for existing aggregation
  40. for (var i = 0; i < selectParts.length; i++) {
  41. var part = selectParts[i];
  42. if (part.def.category === categories.Aggregations) {
  43. selectParts[i] = partModel;
  44. return;
  45. }
  46. }
  47. selectParts.splice(1, 0, partModel);
  48. }
  49. function addMathStrategy(selectParts, partModel) {
  50. var partCount = selectParts.length;
  51. if (partCount > 0) {
  52. // if last is math, replace it
  53. if (selectParts[partCount - 1].def.type === 'math') {
  54. selectParts[partCount - 1] = partModel;
  55. return;
  56. }
  57. // if next to last is math, replace it
  58. if (partCount > 1 && selectParts[partCount - 2].def.type === 'math') {
  59. selectParts[partCount - 2] = partModel;
  60. return;
  61. } else if (selectParts[partCount - 1].def.type === 'alias') {
  62. // if last is alias add it before
  63. selectParts.splice(partCount - 1, 0, partModel);
  64. return;
  65. }
  66. }
  67. selectParts.push(partModel);
  68. }
  69. function addAliasStrategy(selectParts, partModel) {
  70. var partCount = selectParts.length;
  71. if (partCount > 0) {
  72. // if last is alias, replace it
  73. if (selectParts[partCount - 1].def.type === 'alias') {
  74. selectParts[partCount - 1] = partModel;
  75. return;
  76. }
  77. }
  78. selectParts.push(partModel);
  79. }
  80. function addColumnStrategy(selectParts, partModel, query) {
  81. // copy all parts
  82. var parts = _.map(selectParts, function(part: any) {
  83. return createPart({ type: part.def.type, params: _.clone(part.params) });
  84. });
  85. query.selectModels.push(parts);
  86. }
  87. register({
  88. type: 'column',
  89. addStrategy: addColumnStrategy,
  90. category: categories.Columns,
  91. params: [{ type: 'column', dynamicLookup: true }],
  92. defaultParams: ['value'],
  93. renderer: columnRenderer,
  94. });
  95. // Aggregations
  96. register({
  97. type: 'avg',
  98. addStrategy: replaceAggregationAddStrategy,
  99. category: categories.Aggregations,
  100. params: [],
  101. defaultParams: [],
  102. renderer: functionRenderer,
  103. });
  104. register({
  105. type: 'count',
  106. addStrategy: replaceAggregationAddStrategy,
  107. category: categories.Aggregations,
  108. params: [],
  109. defaultParams: [],
  110. renderer: functionRenderer,
  111. });
  112. register({
  113. type: 'sum',
  114. addStrategy: replaceAggregationAddStrategy,
  115. category: categories.Aggregations,
  116. params: [],
  117. defaultParams: [],
  118. renderer: functionRenderer,
  119. });
  120. register({
  121. type: 'stddev',
  122. addStrategy: replaceAggregationAddStrategy,
  123. category: categories.Aggregations,
  124. params: [],
  125. defaultParams: [],
  126. renderer: functionRenderer,
  127. });
  128. register({
  129. type: 'min',
  130. addStrategy: replaceAggregationAddStrategy,
  131. category: categories.Aggregations,
  132. params: [],
  133. defaultParams: [],
  134. renderer: functionRenderer,
  135. });
  136. register({
  137. type: 'max',
  138. addStrategy: replaceAggregationAddStrategy,
  139. category: categories.Aggregations,
  140. params: [],
  141. defaultParams: [],
  142. renderer: functionRenderer,
  143. });
  144. register({
  145. type: 'math',
  146. addStrategy: addMathStrategy,
  147. category: categories.Math,
  148. params: [{ name: 'expr', type: 'string' }],
  149. defaultParams: [' / 100'],
  150. renderer: suffixRenderer,
  151. });
  152. register({
  153. type: 'alias',
  154. addStrategy: addAliasStrategy,
  155. category: categories.Aliasing,
  156. params: [{ name: 'name', type: 'string', quote: 'double' }],
  157. defaultParams: ['alias'],
  158. renderMode: 'suffix',
  159. renderer: aliasRenderer,
  160. });
  161. register({
  162. type: 'time',
  163. category: groupByTimeFunctions,
  164. params: [
  165. {
  166. name: 'interval',
  167. type: 'interval',
  168. options: ['$__interval', '1s', '10s', '1m', '5m', '10m', '15m', '1h'],
  169. },
  170. {
  171. name: 'fill',
  172. type: 'string',
  173. options: ['none', 'NULL', '0'],
  174. },
  175. ],
  176. defaultParams: ['$__interval','none'],
  177. renderer: functionRenderer,
  178. });
  179. export default {
  180. create: createPart,
  181. registerAggregate: registerAggregate,
  182. clearAggregates: function() { categories.Aggregations = []; },
  183. hasAggregates: function() {
  184. // FIXME
  185. return categories.Aggregations.length > 6;
  186. },
  187. getCategories: function() {
  188. return categories;
  189. },
  190. };