query_part.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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. var groupByTimeFunctions = [];
  22. function aliasRenderer(part, innerExpr) {
  23. return innerExpr + ' AS ' + '"' + part.params[0] + '"';
  24. }
  25. function aggregateRenderer(part, innerExpr) {
  26. return part.params[0] + '(' + innerExpr + ')';
  27. }
  28. function columnRenderer(part, innerExpr) {
  29. return '"' + part.params[0] + '"';
  30. }
  31. function replaceAggregationAddStrategy(selectParts, partModel) {
  32. // look for existing aggregation
  33. for (var i = 0; i < selectParts.length; i++) {
  34. var part = selectParts[i];
  35. if (part.def.category === categories.Aggregations) {
  36. selectParts[i] = partModel;
  37. return;
  38. }
  39. }
  40. selectParts.splice(1, 0, partModel);
  41. }
  42. function addMathStrategy(selectParts, partModel) {
  43. var partCount = selectParts.length;
  44. if (partCount > 0) {
  45. // if last is math, replace it
  46. if (selectParts[partCount - 1].def.type === 'math') {
  47. selectParts[partCount - 1] = partModel;
  48. return;
  49. }
  50. // if next to last is math, replace it
  51. if (partCount > 1 && selectParts[partCount - 2].def.type === 'math') {
  52. selectParts[partCount - 2] = partModel;
  53. return;
  54. } else if (selectParts[partCount - 1].def.type === 'alias') {
  55. // if last is alias add it before
  56. selectParts.splice(partCount - 1, 0, partModel);
  57. return;
  58. }
  59. }
  60. selectParts.push(partModel);
  61. }
  62. function addAliasStrategy(selectParts, partModel) {
  63. var partCount = selectParts.length;
  64. if (partCount > 0) {
  65. // if last is alias, replace it
  66. if (selectParts[partCount - 1].def.type === 'alias') {
  67. selectParts[partCount - 1] = partModel;
  68. return;
  69. }
  70. }
  71. selectParts.push(partModel);
  72. }
  73. function addColumnStrategy(selectParts, partModel, query) {
  74. // copy all parts
  75. var parts = _.map(selectParts, function(part: any) {
  76. return createPart({ type: part.def.type, params: _.clone(part.params) });
  77. });
  78. query.selectModels.push(parts);
  79. }
  80. register({
  81. type: 'column',
  82. addStrategy: addColumnStrategy,
  83. category: categories.Columns,
  84. params: [{ type: 'column', dynamicLookup: true }],
  85. defaultParams: ['value'],
  86. renderer: columnRenderer,
  87. });
  88. register({
  89. type: 'aggregate',
  90. addStrategy: replaceAggregationAddStrategy,
  91. category: categories.Aggregations,
  92. params: [{name: 'name', type: 'string', dynamicLookup: true}],
  93. defaultParams: ['avg'],
  94. renderer: aggregateRenderer,
  95. });
  96. register({
  97. type: 'math',
  98. addStrategy: addMathStrategy,
  99. category: categories.Math,
  100. params: [{ name: 'expr', type: 'string' }],
  101. defaultParams: [' / 100'],
  102. renderer: suffixRenderer,
  103. });
  104. register({
  105. type: 'alias',
  106. addStrategy: addAliasStrategy,
  107. category: categories.Aliasing,
  108. params: [{ name: 'name', type: 'string', quote: 'double' }],
  109. defaultParams: ['alias'],
  110. renderMode: 'suffix',
  111. renderer: aliasRenderer,
  112. });
  113. register({
  114. type: 'time',
  115. category: groupByTimeFunctions,
  116. params: [
  117. {
  118. name: 'interval',
  119. type: 'interval',
  120. options: ['$__interval', '1s', '10s', '1m', '5m', '10m', '15m', '1h'],
  121. },
  122. {
  123. name: 'fill',
  124. type: 'string',
  125. options: ['none', 'NULL', '0'],
  126. },
  127. ],
  128. defaultParams: ['$__interval','none'],
  129. renderer: functionRenderer,
  130. });
  131. export default {
  132. create: createPart,
  133. getCategories: function() {
  134. return categories;
  135. },
  136. };