query_builder.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import _ from 'lodash';
  2. import kbn from 'app/core/utils/kbn';
  3. function renderTagCondition(tag, index) {
  4. let str = '';
  5. let operator = tag.operator;
  6. let value = tag.value;
  7. if (index > 0) {
  8. str = (tag.condition || 'AND') + ' ';
  9. }
  10. if (!operator) {
  11. if (/^\/.*\/$/.test(tag.value)) {
  12. operator = '=~';
  13. } else {
  14. operator = '=';
  15. }
  16. }
  17. // quote value unless regex or number
  18. if (operator !== '=~' && operator !== '!~' && isNaN(+value)) {
  19. value = "'" + value + "'";
  20. }
  21. return str + '"' + tag.key + '" ' + operator + ' ' + value;
  22. }
  23. export class InfluxQueryBuilder {
  24. constructor(private target, private database?) {}
  25. buildExploreQuery(type: string, withKey?: string, withMeasurementFilter?: string) {
  26. let query;
  27. let measurement;
  28. let policy;
  29. if (type === 'TAG_KEYS') {
  30. query = 'SHOW TAG KEYS';
  31. measurement = this.target.measurement;
  32. policy = this.target.policy;
  33. } else if (type === 'TAG_VALUES') {
  34. query = 'SHOW TAG VALUES';
  35. measurement = this.target.measurement;
  36. policy = this.target.policy;
  37. } else if (type === 'MEASUREMENTS') {
  38. query = 'SHOW MEASUREMENTS';
  39. if (withMeasurementFilter) {
  40. query += ' WITH MEASUREMENT =~ /' + kbn.regexEscape(withMeasurementFilter) + '/';
  41. }
  42. } else if (type === 'FIELDS') {
  43. measurement = this.target.measurement;
  44. policy = this.target.policy;
  45. if (!measurement.match('^/.*/')) {
  46. measurement = '"' + measurement + '"';
  47. if (policy && policy !== 'default') {
  48. policy = '"' + policy + '"';
  49. measurement = policy + '.' + measurement;
  50. }
  51. }
  52. return 'SHOW FIELD KEYS FROM ' + measurement;
  53. } else if (type === 'RETENTION POLICIES') {
  54. query = 'SHOW RETENTION POLICIES on "' + this.database + '"';
  55. return query;
  56. }
  57. if (measurement) {
  58. if (!measurement.match('^/.*/') && !measurement.match(/^merge\(.*\)/)) {
  59. measurement = '"' + measurement + '"';
  60. }
  61. if (policy && policy !== 'default') {
  62. policy = '"' + policy + '"';
  63. measurement = policy + '.' + measurement;
  64. }
  65. query += ' FROM ' + measurement;
  66. }
  67. if (withKey) {
  68. query += ' WITH KEY = "' + withKey + '"';
  69. }
  70. if (this.target.tags && this.target.tags.length > 0) {
  71. const whereConditions = _.reduce(
  72. this.target.tags,
  73. (memo, tag) => {
  74. // do not add a condition for the key we want to explore for
  75. if (tag.key === withKey) {
  76. return memo;
  77. }
  78. memo.push(renderTagCondition(tag, memo.length));
  79. return memo;
  80. },
  81. []
  82. );
  83. if (whereConditions.length > 0) {
  84. query += ' WHERE ' + whereConditions.join(' ');
  85. }
  86. }
  87. if (type === 'MEASUREMENTS') {
  88. query += ' LIMIT 100';
  89. //Solve issue #2524 by limiting the number of measurements returned
  90. //LIMIT must be after WITH MEASUREMENT and WHERE clauses
  91. //This also could be used for TAG KEYS and TAG VALUES, if desired
  92. }
  93. return query;
  94. }
  95. }