query_part.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. ///<reference path="../../../headers/common.d.ts" />
  2. import _ = require('lodash');
  3. var index = [];
  4. var categories = {
  5. Combine: [],
  6. Transform: [],
  7. Calculate: [],
  8. Filter: [],
  9. Special: []
  10. };
  11. class QueryPartDef {
  12. name: string;
  13. params: any[];
  14. defaultParams: any[];
  15. constructor(options: any) {
  16. this.name = options.name;
  17. this.params = options.params;
  18. this.defaultParams = options.defaultParams;
  19. }
  20. static register(options: any) {
  21. index[options.name] = new QueryPartDef(options);
  22. }
  23. }
  24. QueryPartDef.register({
  25. name: 'field',
  26. category: categories.Transform,
  27. params: [{type: 'field'}],
  28. defaultParams: ['value'],
  29. });
  30. QueryPartDef.register({
  31. name: 'mean',
  32. category: categories.Transform,
  33. params: [],
  34. defaultParams: [],
  35. });
  36. QueryPartDef.register({
  37. name: 'derivate',
  38. category: categories.Transform,
  39. params: [{ name: "rate", type: "interval", options: ['1s', '10s', '1m', '5min', '10m', '15m', '1h'] }],
  40. defaultParams: ['10s'],
  41. });
  42. QueryPartDef.register({
  43. name: 'time',
  44. category: categories.Transform,
  45. params: [{ name: "rate", type: "interval", options: ['$interval', '1s', '10s', '1m', '5min', '10m', '15m', '1h'] }],
  46. defaultParams: ['$interval'],
  47. });
  48. QueryPartDef.register({
  49. name: 'math',
  50. category: categories.Transform,
  51. params: [{ name: "expr", type: "string"}],
  52. defaultParams: [' / 100'],
  53. });
  54. QueryPartDef.register({
  55. name: 'alias',
  56. category: categories.Transform,
  57. params: [{ name: "name", type: "string"}],
  58. defaultParams: ['alias'],
  59. });
  60. class QueryPart {
  61. part: any;
  62. def: QueryPartDef;
  63. params: any[];
  64. text: string;
  65. constructor(part: any) {
  66. this.part = part;
  67. this.def = index[part.name];
  68. if (!this.def) {
  69. throw {message: 'Could not find query part ' + part.name};
  70. }
  71. this.params = part.params || _.clone(this.def.defaultParams);
  72. }
  73. render(innerExpr: string) {
  74. var str = this.def.name + '(';
  75. var parameters = _.map(this.params, (value, index) => {
  76. var paramType = this.def.params[index].type;
  77. if (paramType === 'int' || paramType === 'value_or_series' || paramType === 'boolean') {
  78. return value;
  79. }
  80. else if (paramType === 'int_or_interval' && _.isNumber(value)) {
  81. return value;
  82. }
  83. return "'" + value + "'";
  84. });
  85. if (innerExpr) {
  86. parameters.unshift(innerExpr);
  87. }
  88. return str + parameters.join(', ') + ')';
  89. }
  90. hasMultipleParamsInString (strValue, index) {
  91. if (strValue.indexOf(',') === -1) {
  92. return false;
  93. }
  94. return this.def.params[index + 1] && this.def.params[index + 1].optional;
  95. }
  96. updateParam (strValue, index) {
  97. // handle optional parameters
  98. // if string contains ',' and next param is optional, split and update both
  99. if (this.hasMultipleParamsInString(strValue, index)) {
  100. _.each(strValue.split(','), function(partVal: string, idx) {
  101. this.updateParam(partVal.trim(), idx);
  102. }, this);
  103. return;
  104. }
  105. if (strValue === '' && this.def.params[index].optional) {
  106. this.params.splice(index, 1);
  107. }
  108. else {
  109. this.params[index] = strValue;
  110. }
  111. this.part.params = this.params;
  112. this.updateText();
  113. }
  114. updateText() {
  115. if (this.params.length === 0) {
  116. this.text = this.def.name + '()';
  117. return;
  118. }
  119. var text = this.def.name + '(';
  120. text += this.params.join(', ');
  121. text += ')';
  122. this.text = text;
  123. }
  124. }
  125. export = {
  126. create: function(part): any {
  127. return new QueryPart(part);
  128. },
  129. getFuncDef: function(name) {
  130. return index[name];
  131. },
  132. getCategories: function() {
  133. return categories;
  134. }
  135. };