query_part.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import { clone, each, map } from 'lodash';
  2. export class QueryPartDef {
  3. type: string;
  4. params: any[];
  5. defaultParams: any[];
  6. renderer: any;
  7. category: any;
  8. addStrategy: any;
  9. constructor(options: any) {
  10. this.type = options.type;
  11. this.params = options.params;
  12. this.defaultParams = options.defaultParams;
  13. this.renderer = options.renderer;
  14. this.category = options.category;
  15. this.addStrategy = options.addStrategy;
  16. }
  17. }
  18. export class QueryPart {
  19. part: any;
  20. def: QueryPartDef;
  21. params: any[];
  22. text: string;
  23. constructor(part: any, def: any) {
  24. this.part = part;
  25. this.def = def;
  26. if (!this.def) {
  27. throw { message: 'Could not find query part ' + part.type };
  28. }
  29. part.params = part.params || clone(this.def.defaultParams);
  30. this.params = part.params;
  31. this.text = '';
  32. this.updateText();
  33. }
  34. render(innerExpr: string) {
  35. return this.def.renderer(this, innerExpr);
  36. }
  37. hasMultipleParamsInString(strValue: string, index: number) {
  38. if (strValue.indexOf(',') === -1) {
  39. return false;
  40. }
  41. return this.def.params[index + 1] && this.def.params[index + 1].optional;
  42. }
  43. updateParam(strValue: string, index: number) {
  44. // handle optional parameters
  45. // if string contains ',' and next param is optional, split and update both
  46. if (this.hasMultipleParamsInString(strValue, index)) {
  47. each(strValue.split(','), (partVal, idx) => {
  48. this.updateParam(partVal.trim(), idx);
  49. });
  50. return;
  51. }
  52. if (strValue === '' && this.def.params[index].optional) {
  53. this.params.splice(index, 1);
  54. } else {
  55. this.params[index] = strValue;
  56. }
  57. this.part.params = this.params;
  58. this.updateText();
  59. }
  60. updateText() {
  61. if (this.params.length === 0) {
  62. this.text = this.def.type + '()';
  63. return;
  64. }
  65. let text = this.def.type + '(';
  66. text += this.params.join(', ');
  67. text += ')';
  68. this.text = text;
  69. }
  70. }
  71. export function functionRenderer(part: any, innerExpr: string) {
  72. const str = part.def.type + '(';
  73. const parameters = map(part.params, (value, index) => {
  74. const paramType = part.def.params[index];
  75. if (paramType.type === 'time') {
  76. if (value === 'auto') {
  77. value = '$__interval';
  78. }
  79. }
  80. if (paramType.quote === 'single') {
  81. return "'" + value + "'";
  82. } else if (paramType.quote === 'double') {
  83. return '"' + value + '"';
  84. }
  85. return value;
  86. });
  87. if (innerExpr) {
  88. parameters.unshift(innerExpr);
  89. }
  90. return str + parameters.join(', ') + ')';
  91. }
  92. export function suffixRenderer(part: QueryPart, innerExpr: string) {
  93. return innerExpr + ' ' + part.params[0];
  94. }
  95. export function identityRenderer(part: QueryPart, innerExpr: string) {
  96. return part.params[0];
  97. }
  98. export function quotedIdentityRenderer(part: QueryPart, innerExpr: string) {
  99. return '"' + part.params[0] + '"';
  100. }