sql_part.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import _ from 'lodash';
  2. import { SqlPartDef, SqlPart, functionRenderer, suffixRenderer } from 'app/core/components/sql_part/sql_part';
  3. var index = [];
  4. function createPart(part): any {
  5. var def = index[part.type];
  6. if (!def) {
  7. throw { message: 'Could not find query part ' + part.type };
  8. }
  9. return new SqlPart(part, def);
  10. }
  11. function register(options: any) {
  12. index[options.type] = new SqlPartDef(options);
  13. }
  14. function aliasRenderer(part, innerExpr) {
  15. return innerExpr + ' AS ' + '"' + part.params[0] + '"';
  16. }
  17. function aggregateRenderer(part, innerExpr) {
  18. return part.params[0] + '(' + innerExpr + ')';
  19. }
  20. function columnRenderer(part, innerExpr) {
  21. return '"' + part.params[0] + '"';
  22. }
  23. function replaceAggregationAddStrategy(selectParts, partModel) {
  24. // look for existing aggregation
  25. for (var i = 0; i < selectParts.length; i++) {
  26. var part = selectParts[i];
  27. if (part.def.type === 'aggregate') {
  28. selectParts[i] = partModel;
  29. return;
  30. }
  31. }
  32. selectParts.splice(1, 0, partModel);
  33. }
  34. function addMathStrategy(selectParts, partModel) {
  35. var partCount = selectParts.length;
  36. if (partCount > 0) {
  37. // if last is math, replace it
  38. if (selectParts[partCount - 1].def.type === 'math') {
  39. selectParts[partCount - 1] = partModel;
  40. return;
  41. }
  42. // if next to last is math, replace it
  43. if (partCount > 1 && selectParts[partCount - 2].def.type === 'math') {
  44. selectParts[partCount - 2] = partModel;
  45. return;
  46. } else if (selectParts[partCount - 1].def.type === 'alias') {
  47. // if last is alias add it before
  48. selectParts.splice(partCount - 1, 0, partModel);
  49. return;
  50. }
  51. }
  52. selectParts.push(partModel);
  53. }
  54. function addAliasStrategy(selectParts, partModel) {
  55. var partCount = selectParts.length;
  56. if (partCount > 0) {
  57. // if last is alias, replace it
  58. if (selectParts[partCount - 1].def.type === 'alias') {
  59. selectParts[partCount - 1] = partModel;
  60. return;
  61. }
  62. }
  63. selectParts.push(partModel);
  64. }
  65. function addColumnStrategy(selectParts, partModel, query) {
  66. // copy all parts
  67. var parts = _.map(selectParts, function(part: any) {
  68. return createPart({ type: part.def.type, params: _.clone(part.params) });
  69. });
  70. query.selectModels.push(parts);
  71. }
  72. function addExpressionStrategy(selectParts, partModel, query) {
  73. // copy all parts
  74. var parts = _.map(selectParts, function(part: any) {
  75. return createPart({ type: part.def.type, params: _.clone(part.params) });
  76. });
  77. query.selectModels.push(parts);
  78. }
  79. register({
  80. type: 'column',
  81. style: 'label',
  82. addStrategy: addColumnStrategy,
  83. params: [{ type: 'column', dynamicLookup: true }],
  84. defaultParams: ['value'],
  85. renderer: columnRenderer,
  86. });
  87. register({
  88. type: 'expression',
  89. style: 'expression',
  90. label: 'Expr:',
  91. addStrategy: addExpressionStrategy,
  92. params: [
  93. { name: 'left', type: 'string', dynamicLookup: true },
  94. { name: 'op', type: 'string', dynamicLookup: true },
  95. { name: 'right', type: 'string', dynamicLookup: true },
  96. ],
  97. defaultParams: ['value', '=', 'value'],
  98. renderer: columnRenderer,
  99. });
  100. register({
  101. type: 'aggregate',
  102. style: 'label',
  103. addStrategy: replaceAggregationAddStrategy,
  104. params: [{ name: 'name', type: 'string', dynamicLookup: true }],
  105. defaultParams: ['avg'],
  106. renderer: aggregateRenderer,
  107. });
  108. register({
  109. type: 'math',
  110. style: 'label',
  111. addStrategy: addMathStrategy,
  112. params: [{ name: 'expr', type: 'string' }],
  113. defaultParams: [' / 100'],
  114. renderer: suffixRenderer,
  115. });
  116. register({
  117. type: 'alias',
  118. style: 'label',
  119. addStrategy: addAliasStrategy,
  120. params: [{ name: 'name', type: 'string', quote: 'double' }],
  121. defaultParams: ['alias'],
  122. renderMode: 'suffix',
  123. renderer: aliasRenderer,
  124. });
  125. register({
  126. type: 'time',
  127. style: 'function',
  128. label: 'time',
  129. params: [
  130. {
  131. name: 'interval',
  132. type: 'interval',
  133. options: ['$__interval', '1s', '10s', '1m', '5m', '10m', '15m', '1h'],
  134. },
  135. {
  136. name: 'fill',
  137. type: 'string',
  138. options: ['none', 'NULL', '0'],
  139. },
  140. ],
  141. defaultParams: ['$__interval', 'none'],
  142. renderer: functionRenderer,
  143. });
  144. export default {
  145. create: createPart,
  146. };