Commit 1d587450 by David Kaltschmidt

IFQL range variable expansion

parent 08ee1da6
...@@ -54,23 +54,32 @@ export default class InfluxDatasource { ...@@ -54,23 +54,32 @@ export default class InfluxDatasource {
this.supportMetrics = true; this.supportMetrics = true;
} }
query(options) { prepareQueries(options) {
const targets = _.cloneDeep(options.targets); const targets = _.cloneDeep(options.targets);
const queryTargets = targets.filter(t => t.query); const timeFilter = this.getTimeFilter(options);
options.scopedVars.range = { value: timeFilter };
// Filter empty queries and replace grafana variables
const queryTargets = targets.filter(t => t.query).map(t => {
const interpolated = this.templateSrv.replace(t.query, options.scopedVars);
return {
...t,
query: interpolated,
};
});
return queryTargets;
}
query(options) {
const queryTargets = this.prepareQueries(options);
if (queryTargets.length === 0) { if (queryTargets.length === 0) {
return Promise.resolve({ data: [] }); return Promise.resolve({ data: [] });
} }
// replace grafana variables
const timeFilter = this.getTimeFilter(options);
options.scopedVars.timeFilter = { value: timeFilter };
const queries = queryTargets.map(target => { const queries = queryTargets.map(target => {
const { query, resultFormat } = target; const { query, resultFormat } = target;
// TODO replace templated variables
// allQueries = this.templateSrv.replace(allQueries, scopedVars);
if (resultFormat === 'table') { if (resultFormat === 'table') {
return ( return (
this._seriesQuery(query, options) this._seriesQuery(query, options)
...@@ -224,32 +233,29 @@ export default class InfluxDatasource { ...@@ -224,32 +233,29 @@ export default class InfluxDatasource {
} }
getTimeFilter(options) { getTimeFilter(options) {
var from = this.getInfluxTime(options.rangeRaw.from, false); const from = this.getInfluxTime(options.rangeRaw.from, false);
var until = this.getInfluxTime(options.rangeRaw.to, true); const to = this.getInfluxTime(options.rangeRaw.to, true);
var fromIsAbsolute = from[from.length - 1] === 'ms'; if (to === 'now') {
return `start: ${from}`;
if (until === 'now()' && !fromIsAbsolute) {
return 'time >= ' + from;
} }
return `start: ${from}, stop: ${to}`;
return 'time >= ' + from + ' and time <= ' + until;
} }
getInfluxTime(date, roundUp) { getInfluxTime(date, roundUp) {
if (_.isString(date)) { if (_.isString(date)) {
if (date === 'now') { if (date === 'now') {
return 'now()'; return date;
} }
var parts = /^now-(\d+)([d|h|m|s])$/.exec(date); const parts = /^now\s*-\s*(\d+)([d|h|m|s])$/.exec(date);
if (parts) { if (parts) {
var amount = parseInt(parts[1]); const amount = parseInt(parts[1]);
var unit = parts[2]; const unit = parts[2];
return 'now() - ' + amount + unit; return '-' + amount + unit;
} }
date = dateMath.parse(date, roundUp); date = dateMath.parse(date, roundUp);
} }
return date.valueOf() + 'ms'; return date.toISOString();
} }
} }
import InfluxDatasource from './datasource'; import InfluxDatasource from './datasource';
import { InfluxQueryCtrl } from './query_ctrl'; import { InfluxIfqlQueryCtrl } from './query_ctrl';
class InfluxConfigCtrl { class InfluxConfigCtrl {
static templateUrl = 'partials/config.html'; static templateUrl = 'partials/config.html';
...@@ -11,7 +11,7 @@ class InfluxAnnotationsQueryCtrl { ...@@ -11,7 +11,7 @@ class InfluxAnnotationsQueryCtrl {
export { export {
InfluxDatasource as Datasource, InfluxDatasource as Datasource,
InfluxQueryCtrl as QueryCtrl, InfluxIfqlQueryCtrl as QueryCtrl,
InfluxConfigCtrl as ConfigCtrl, InfluxConfigCtrl as ConfigCtrl,
InfluxAnnotationsQueryCtrl as AnnotationsQueryCtrl, InfluxAnnotationsQueryCtrl as AnnotationsQueryCtrl,
}; };
import { QueryCtrl } from 'app/plugins/sdk'; import { QueryCtrl } from 'app/plugins/sdk';
export class InfluxQueryCtrl extends QueryCtrl { function makeDefaultQuery(database) {
return `from(db: "${database}")
|> range($range)
|> limit(n:1000)
`;
}
export class InfluxIfqlQueryCtrl extends QueryCtrl {
static templateUrl = 'partials/query.editor.html'; static templateUrl = 'partials/query.editor.html';
resultFormats: any[]; resultFormats: any[];
...@@ -8,6 +14,10 @@ export class InfluxQueryCtrl extends QueryCtrl { ...@@ -8,6 +14,10 @@ export class InfluxQueryCtrl extends QueryCtrl {
/** @ngInject **/ /** @ngInject **/
constructor($scope, $injector) { constructor($scope, $injector) {
super($scope, $injector); super($scope, $injector);
if (this.target.query === undefined) {
this.target.query = makeDefaultQuery(this.datasource.database);
}
this.resultFormats = [{ text: 'Time series', value: 'time_series' }, { text: 'Table', value: 'table' }]; this.resultFormats = [{ text: 'Time series', value: 'time_series' }, { text: 'Table', value: 'table' }];
} }
......
import moment from 'moment';
import { TemplateSrv } from 'app/features/templating/template_srv';
import Datasource from '../datasource';
describe('InfluxDB (IFQL)', () => {
const templateSrv = new TemplateSrv();
const ds = new Datasource({ url: '' }, {}, templateSrv);
const DEFAULT_OPTIONS = {
rangeRaw: { to: 'now', from: 'now - 3h' },
scopedVars: {},
targets: [],
};
let queries: any[];
describe('prepareQueries()', () => {
it('filters empty queries', () => {
queries = ds.prepareQueries(DEFAULT_OPTIONS);
expect(queries.length).toBe(0);
queries = ds.prepareQueries({
...DEFAULT_OPTIONS,
targets: [{ query: '' }],
});
expect(queries.length).toBe(0);
});
it('replaces $range variable', () => {
queries = ds.prepareQueries({
...DEFAULT_OPTIONS,
targets: [{ query: 'from(db: "test") |> range($range)' }],
});
expect(queries.length).toBe(1);
expect(queries[0].query).toBe('from(db: "test") |> range(start: -3h)');
});
it('replaces $range variable with custom dates', () => {
const to = moment();
const from = moment().subtract(1, 'hours');
queries = ds.prepareQueries({
...DEFAULT_OPTIONS,
rangeRaw: { to, from },
targets: [{ query: 'from(db: "test") |> range($range)' }],
});
expect(queries.length).toBe(1);
const start = from.toISOString();
const stop = to.toISOString();
expect(queries[0].query).toBe(`from(db: "test") |> range(start: ${start}, stop: ${stop})`);
});
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment