diff --git a/public/app/plugins/datasource/influxdb/queryBuilder.js b/public/app/plugins/datasource/influxdb/queryBuilder.js
index c738be685d3..a46c380e1d4 100644
--- a/public/app/plugins/datasource/influxdb/queryBuilder.js
+++ b/public/app/plugins/datasource/influxdb/queryBuilder.js
@@ -84,6 +84,14 @@ function (_) {
return query;
};
+
+ p._getGroupByTimeInterval = function(interval) {
+ if (interval === 'auto') {
+ return '$interval';
+ }
+ return interval;
+ };
+
p._buildQuery = function() {
var target = this.target;
@@ -103,6 +111,14 @@ function (_) {
query += ', ';
}
query += field.func + '("' + field.name + '")';
+ if (field.mathExpr) {
+ query += field.mathExpr;
+ }
+ if (field.asExpr) {
+ query += ' AS "' + field.asExpr + '"';
+ } else {
+ query += ' AS "' + field.name + '"';
+ }
}
var measurement = target.measurement;
@@ -122,9 +138,9 @@ function (_) {
for (i = 0; i < target.groupBy.length; i++) {
var group = target.groupBy[i];
if (group.type === 'time') {
- query += ' time(10s)';
+ query += ' time(' + this._getGroupByTimeInterval(group.interval) + ')';
} else {
- query += ', ' + group.key;
+ query += ', "' + group.key + '"';
}
}
diff --git a/public/app/plugins/datasource/influxdb/queryCtrl.js b/public/app/plugins/datasource/influxdb/queryCtrl.js
index 0da5adc0f92..47d21afc752 100644
--- a/public/app/plugins/datasource/influxdb/queryCtrl.js
+++ b/public/app/plugins/datasource/influxdb/queryCtrl.js
@@ -29,8 +29,6 @@ function (angular, _, InfluxQueryBuilder) {
$scope.measurementSegment = uiSegmentSrv.newSegment(target.measurement);
}
- $scope.addFieldSegment = uiSegmentSrv.newPlusButton();
-
$scope.tagSegments = [];
_.each(target.tags, function(tag) {
if (!tag.operator) {
@@ -73,23 +71,13 @@ function (angular, _, InfluxQueryBuilder) {
$scope.get_data();
};
- $scope.groupByTagUpdated = function(segment, index) {
- if (segment.value === $scope.removeGroupBySegment.value) {
- $scope.target.groupByTags.splice(index, 1);
- $scope.groupBySegments.splice(index, 1);
- $scope.$parent.get_data();
- return;
- }
+ $scope.addSelect = function() {
+ $scope.target.fields.push({name: "select field", func: 'mean'});
+ };
- if (index === $scope.groupBySegments.length-1) {
- $scope.groupBySegments.push(uiSegmentSrv.newPlusButton());
- }
-
- segment.type = 'group-by-key';
- segment.fake = false;
-
- $scope.target.groupByTags[index] = segment.value;
- $scope.$parent.get_data();
+ $scope.removeSelect = function(index) {
+ $scope.target.fields.splice(index, 1);
+ $scope.get_data();
};
$scope.changeFunction = function(func) {
@@ -105,13 +93,7 @@ function (angular, _, InfluxQueryBuilder) {
$scope.getFields = function() {
var fieldsQuery = $scope.queryBuilder.buildExploreQuery('FIELDS');
return $scope.datasource.metricFindQuery(fieldsQuery)
- .then(function(results) {
- var values = _.pluck(results, 'text');
- if ($scope.target.fields.length > 1) {
- values.splice(0, 0, "-- remove from select --");
- }
- return values;
- });
+ .then($scope.transformToSegments(false), $scope.handleQueryError);
};
$scope.toggleQueryMode = function () {
@@ -121,8 +103,16 @@ function (angular, _, InfluxQueryBuilder) {
$scope.getMeasurements = function () {
var query = $scope.queryBuilder.buildExploreQuery('MEASUREMENTS');
return $scope.datasource.metricFindQuery(query)
- .then($scope.transformToSegments(true))
- .then(null, $scope.handleQueryError);
+ .then($scope.transformToSegments(true), $scope.handleQueryError);
+ };
+
+ $scope.getFunctions = function () {
+ var functionList = ['count', 'mean', 'sum', 'min', 'max', 'mode', 'distinct', 'median',
+ 'derivative', 'non_negative_derivative', 'stddev', 'first', 'last'
+ ];
+ return $q.when(_.map(functionList, function(func) {
+ return uiSegmentSrv.newSegment(func);
+ }));
};
$scope.handleQueryError = function(err) {
diff --git a/public/test/specs/influx09-querybuilder-specs.js b/public/test/specs/influx09-querybuilder-specs.js
index 098ceeb6ca4..cfbb7ddffe1 100644
--- a/public/test/specs/influx09-querybuilder-specs.js
+++ b/public/test/specs/influx09-querybuilder-specs.js
@@ -6,76 +6,96 @@ define([
describe('InfluxQueryBuilder', function() {
describe('series with mesurement only', function() {
- var builder = new InfluxQueryBuilder({
- measurement: 'cpu',
- });
-
- var query = builder.build();
-
it('should generate correct query', function() {
- expect(query).to.be('SELECT mean("value") FROM "cpu" WHERE $timeFilter GROUP BY time($interval)');
- });
+ var builder = new InfluxQueryBuilder({
+ measurement: 'cpu',
+ groupBy: [{type: 'time', interval: 'auto'}]
+ });
+ var query = builder.build();
+
+ expect(query).to.be('SELECT mean("value") AS "value" FROM "cpu" WHERE $timeFilter GROUP BY time($interval)');
+ });
+ });
+
+ describe('series with math expr and as expr', function() {
+ it('should generate correct query', function() {
+ var builder = new InfluxQueryBuilder({
+ measurement: 'cpu',
+ fields: [{name: 'test', func: 'max', mathExpr: '*2', asExpr: 'new_name'}],
+ groupBy: [{type: 'time', interval: 'auto'}]
+ });
+
+ var query = builder.build();
+
+ expect(query).to.be('SELECT max("test")*2 AS "new_name" FROM "cpu" WHERE $timeFilter GROUP BY time($interval)');
+ });
});
describe('series with single tag only', function() {
- var builder = new InfluxQueryBuilder({
- measurement: 'cpu',
- tags: [{key: 'hostname', value: 'server1'}]
- });
-
- var query = builder.build();
-
it('should generate correct query', function() {
- expect(query).to.be('SELECT mean("value") FROM "cpu" WHERE "hostname" = \'server1\' AND $timeFilter'
+ var builder = new InfluxQueryBuilder({
+ measurement: 'cpu',
+ groupBy: [{type: 'time', interval: 'auto'}],
+ tags: [{key: 'hostname', value: 'server1'}]
+ });
+
+ var query = builder.build();
+
+ expect(query).to.be('SELECT mean("value") AS "value" FROM "cpu" WHERE "hostname" = \'server1\' AND $timeFilter'
+ ' GROUP BY time($interval)');
});
it('should switch regex operator with tag value is regex', function() {
- var builder = new InfluxQueryBuilder({measurement: 'cpu', tags: [{key: 'app', value: '/e.*/'}]});
+ var builder = new InfluxQueryBuilder({
+ measurement: 'cpu',
+ groupBy: [{type: 'time', interval: 'auto'}],
+ tags: [{key: 'app', value: '/e.*/'}]
+ });
+
var query = builder.build();
- expect(query).to.be('SELECT mean("value") FROM "cpu" WHERE "app" =~ /e.*/ AND $timeFilter GROUP BY time($interval)');
+ expect(query).to.be('SELECT mean("value") AS "value" FROM "cpu" WHERE "app" =~ /e.*/ AND $timeFilter GROUP BY time($interval)');
});
});
describe('series with multiple fields', function() {
- var builder = new InfluxQueryBuilder({
- measurement: 'cpu',
- tags: [],
- fields: [{ name: 'tx_in', func: 'sum' }, { name: 'tx_out', func: 'mean' }]
- });
-
- var query = builder.build();
-
it('should generate correct query', function() {
- expect(query).to.be('SELECT sum("tx_in"), mean("tx_out") FROM "cpu" WHERE $timeFilter GROUP BY time($interval)');
+ var builder = new InfluxQueryBuilder({
+ measurement: 'cpu',
+ tags: [],
+ groupBy: [{type: 'time', interval: 'auto'}],
+ fields: [{ name: 'tx_in', func: 'sum' }, { name: 'tx_out', func: 'mean' }]
+ });
+
+ var query = builder.build();
+ expect(query).to.be('SELECT sum("tx_in") AS "tx_in", mean("tx_out") AS "tx_out" FROM "cpu" WHERE $timeFilter GROUP BY time($interval)');
});
});
describe('series with multiple tags only', function() {
- var builder = new InfluxQueryBuilder({
- measurement: 'cpu',
- tags: [{key: 'hostname', value: 'server1'}, {key: 'app', value: 'email', condition: "AND"}]
- });
-
- var query = builder.build();
-
it('should generate correct query', function() {
- expect(query).to.be('SELECT mean("value") FROM "cpu" WHERE "hostname" = \'server1\' AND "app" = \'email\' AND ' +
+ var builder = new InfluxQueryBuilder({
+ measurement: 'cpu',
+ groupBy: [{type: 'time', interval: 'auto'}],
+ tags: [{key: 'hostname', value: 'server1'}, {key: 'app', value: 'email', condition: "AND"}]
+ });
+
+ var query = builder.build();
+ expect(query).to.be('SELECT mean("value") AS "value" FROM "cpu" WHERE "hostname" = \'server1\' AND "app" = \'email\' AND ' +
'$timeFilter GROUP BY time($interval)');
});
});
describe('series with tags OR condition', function() {
- var builder = new InfluxQueryBuilder({
- measurement: 'cpu',
- tags: [{key: 'hostname', value: 'server1'}, {key: 'hostname', value: 'server2', condition: "OR"}]
- });
-
- var query = builder.build();
-
it('should generate correct query', function() {
- expect(query).to.be('SELECT mean("value") FROM "cpu" WHERE "hostname" = \'server1\' OR "hostname" = \'server2\' AND ' +
+ var builder = new InfluxQueryBuilder({
+ measurement: 'cpu',
+ groupBy: [{type: 'time', interval: 'auto'}],
+ tags: [{key: 'hostname', value: 'server1'}, {key: 'hostname', value: 'server2', condition: "OR"}]
+ });
+
+ var query = builder.build();
+ expect(query).to.be('SELECT mean("value") AS "value" FROM "cpu" WHERE "hostname" = \'server1\' OR "hostname" = \'server2\' AND ' +
'$timeFilter GROUP BY time($interval)');
});
});
@@ -85,12 +105,12 @@ define([
var builder = new InfluxQueryBuilder({
measurement: 'cpu',
tags: [],
- groupByTags: ["host"]
+ groupBy: [{type: 'time', interval: 'auto'}, {type: 'tag', key: 'host'}],
});
var query = builder.build();
- expect(query).to.be('SELECT mean("value") FROM "cpu" WHERE $timeFilter ' +
- 'GROUP BY time($interval), "host"');
+ expect(query).to.be('SELECT mean("value") AS "value" FROM "cpu" WHERE $timeFilter ' +
+ 'GROUP BY time($interval), "host"');
});
});
@@ -103,7 +123,10 @@ define([
});
it('should handle regex measurement in tag keys query', function() {
- var builder = new InfluxQueryBuilder({ measurement: '/.*/', tags: [] });
+ var builder = new InfluxQueryBuilder({
+ measurement: '/.*/',
+ tags: []
+ });
var query = builder.buildExploreQuery('TAG_KEYS');
expect(query).to.be('SHOW TAG KEYS FROM /.*/');
});
diff --git a/public/test/specs/influxdbQueryCtrl-specs.js b/public/test/specs/influxdbQueryCtrl-specs.js
index 03e4318e94e..82e98abb07b 100644
--- a/public/test/specs/influxdbQueryCtrl-specs.js
+++ b/public/test/specs/influxdbQueryCtrl-specs.js
@@ -184,39 +184,5 @@ define([
});
});
- describe('when adding group by', function() {
- beforeEach(function() {
- ctx.scope.init();
- ctx.scope.groupByTagUpdated({value: 'host', type: 'plus-button' }, 0);
- });
-
- it('should add group by', function() {
- expect(ctx.scope.target.groupByTags.length).to.be(1);
- expect(ctx.scope.target.groupByTags[0]).to.be('host');
- });
-
- it('should add another plus button segment', function() {
- expect(ctx.scope.groupBySegments[1].type).to.be('plus-button');
- });
- });
-
- describe('when removing group by', function() {
- beforeEach(function() {
- ctx.scope.init();
- ctx.scope.groupByTagUpdated({value: 'host', type: 'plus-button' }, 0);
- ctx.scope.groupByTagUpdated(ctx.scope.removeGroupBySegment, 0);
- });
-
- it('should add group by', function() {
- expect(ctx.scope.target.groupByTags.length).to.be(0);
- });
-
- it('should remove segment', function() {
- expect(ctx.scope.groupBySegments.length).to.be(1);
- expect(ctx.scope.groupBySegments[0].type).to.be('plus-button');
- });
- });
-
-
});
});