The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/public/app/plugins/datasource/influxdb/query_builder.ts

111 lines
3.0 KiB

import _ from 'lodash';
import kbn from 'app/core/utils/kbn';
function renderTagCondition(tag, index) {
let str = '';
let operator = tag.operator;
let value = tag.value;
if (index > 0) {
str = (tag.condition || 'AND') + ' ';
}
if (!operator) {
if (/^\/.*\/$/.test(tag.value)) {
operator = '=~';
} else {
operator = '=';
}
}
// quote value unless regex or number
if (operator !== '=~' && operator !== '!~' && isNaN(+value)) {
value = "'" + value + "'";
}
return str + '"' + tag.key + '" ' + operator + ' ' + value;
}
export class InfluxQueryBuilder {
constructor(private target, private database?) {}
buildExploreQuery(type: string, withKey?: string, withMeasurementFilter?: string) {
let query;
let measurement;
let policy;
if (type === 'TAG_KEYS') {
query = 'SHOW TAG KEYS';
measurement = this.target.measurement;
policy = this.target.policy;
} else if (type === 'TAG_VALUES') {
query = 'SHOW TAG VALUES';
measurement = this.target.measurement;
policy = this.target.policy;
} else if (type === 'MEASUREMENTS') {
query = 'SHOW MEASUREMENTS';
if (withMeasurementFilter) {
query += ' WITH MEASUREMENT =~ /' + kbn.regexEscape(withMeasurementFilter) + '/';
}
} else if (type === 'FIELDS') {
measurement = this.target.measurement;
policy = this.target.policy;
if (!measurement.match('^/.*/')) {
measurement = '"' + measurement + '"';
if (policy && policy !== 'default') {
policy = '"' + policy + '"';
measurement = policy + '.' + measurement;
}
}
return 'SHOW FIELD KEYS FROM ' + measurement;
} else if (type === 'RETENTION POLICIES') {
query = 'SHOW RETENTION POLICIES on "' + this.database + '"';
return query;
}
if (measurement) {
if (!measurement.match('^/.*/') && !measurement.match(/^merge\(.*\)/)) {
measurement = '"' + measurement + '"';
}
if (policy && policy !== 'default') {
policy = '"' + policy + '"';
measurement = policy + '.' + measurement;
}
query += ' FROM ' + measurement;
}
if (withKey) {
query += ' WITH KEY = "' + withKey + '"';
}
if (this.target.tags && this.target.tags.length > 0) {
const whereConditions = _.reduce(
this.target.tags,
(memo, tag) => {
// do not add a condition for the key we want to explore for
if (tag.key === withKey) {
return memo;
}
memo.push(renderTagCondition(tag, memo.length));
return memo;
},
[]
);
if (whereConditions.length > 0) {
query += ' WHERE ' + whereConditions.join(' ');
}
}
if (type === 'MEASUREMENTS') {
query += ' LIMIT 100';
//Solve issue #2524 by limiting the number of measurements returned
//LIMIT must be after WITH MEASUREMENT and WHERE clauses
//This also could be used for TAG KEYS and TAG VALUES, if desired
}
return query;
}
}