diff --git a/public/app/plugins/datasource/influxdb/datasource.js b/public/app/plugins/datasource/influxdb/datasource.js index 35fb495c740..56b01772c55 100644 --- a/public/app/plugins/datasource/influxdb/datasource.js +++ b/public/app/plugins/datasource/influxdb/datasource.js @@ -74,7 +74,7 @@ function (angular, _, kbn, InfluxSeries, InfluxQueryBuilder) { }); }; - InfluxDatasource.prototype.metricFindQuery = function (query, queryType) { + InfluxDatasource.prototype.metricFindQuery = function (query) { var interpolated; try { interpolated = templateSrv.replace(query); @@ -83,39 +83,33 @@ function (angular, _, kbn, InfluxSeries, InfluxQueryBuilder) { return $q.reject(err); } - console.log('metricFindQuery called with: ' + [query, queryType].join(', ')); - - return this._seriesQuery(interpolated, queryType).then(function (results) { + return this._seriesQuery(interpolated).then(function (results) { if (!results || results.results.length === 0) { return []; } var influxResults = results.results[0]; if (!influxResults.series) { return []; } - - console.log('metric find query response', results); var series = influxResults.series[0]; - switch (queryType) { - case 'MEASUREMENTS': + if (query.indexOf('SHOW MEASUREMENTS') === 0) { return _.map(series.values, function(value) { return { text: value[0], expandable: true }; }); - case 'TAG_KEYS': - var tagKeys = _.flatten(series.values); - return _.map(tagKeys, function(tagKey) { return { text: tagKey, expandable: true }; }); - case 'TAG_VALUES': - var tagValues = _.flatten(series.values); - return _.map(tagValues, function(tagValue) { return { text: tagValue, expandable: true }; }); - default: // template values service does not pass in a a query type - var flattenedValues = _.flatten(series.values); - return _.map(flattenedValues, function(value) { return { text: value, expandable: true }; }); } + + var flattenedValues = _.flatten(series.values); + return _.map(flattenedValues, function(value) { return { text: value, expandable: true }; }); }); }; function retry(deferred, callback, delay) { return callback().then(undefined, function(reason) { if (reason.status !== 0 || reason.status >= 300) { - reason.message = 'InfluxDB Error:
' + reason.data; + if (reason.data && reason.data.error) { + reason.message = 'InfluxDB Error Response: ' + reason.data.error; + } + else { + reason.message = 'InfluxDB Error: ' + reason.message; + } deferred.reject(reason); } else { diff --git a/public/app/plugins/datasource/influxdb/queryBuilder.js b/public/app/plugins/datasource/influxdb/queryBuilder.js index fa2069ea35d..1b522ba8eca 100644 --- a/public/app/plugins/datasource/influxdb/queryBuilder.js +++ b/public/app/plugins/datasource/influxdb/queryBuilder.js @@ -14,11 +14,41 @@ function (_) { return this.target.rawQuery ? this._modifyRawQuery() : this._buildQuery(); }; - p.showTagsQuery = function() { - var query = 'SHOW TAG KEYS'; + p.buildExploreQuery = function(type, withKey) { + var query; + var measurement; - if (this.target.measurement) { - query += ' FROM "' + this.target.measurement + '"'; + if (type === 'TAG_KEYS') { + query = 'SHOW TAG KEYS'; + measurement= this.target.measurement; + } else if (type === 'TAG_VALUES') { + query = 'SHOW TAG VALUES'; + measurement= this.target.measurement; + } else if (type === 'MEASUREMENTS') { + query = 'SHOW MEASUREMENTS'; + } + + if (measurement) { + query += ' FROM "' + measurement + '"'; + } + + if (withKey) { + query += ' WITH KEY = "' + withKey + '"'; + } + + if (this.target.tags && this.target.tags.length > 0) { + var whereConditions = _.reduce(this.target.tags, function(memo, tag) { + // do not add a condition for the key we want to explore for + if (tag.key === withKey) { + return memo; + } + memo.push(' ' + tag.key + '=' + "'" + tag.value + "'"); + return memo; + }, []); + + if (whereConditions.length > 0) { + query += ' WHERE' + whereConditions.join('AND'); + } } return query; diff --git a/public/app/plugins/datasource/influxdb/queryCtrl.js b/public/app/plugins/datasource/influxdb/queryCtrl.js index 826ef26565d..828ab3809b0 100644 --- a/public/app/plugins/datasource/influxdb/queryCtrl.js +++ b/public/app/plugins/datasource/influxdb/queryCtrl.js @@ -108,7 +108,8 @@ function (angular, _, InfluxQueryBuilder) { }; $scope.getMeasurements = function () { - return $scope.datasource.metricFindQuery('SHOW MEASUREMENTS', 'MEASUREMENTS') + var query = $scope.queryBuilder.buildExploreQuery('MEASUREMENTS'); + return $scope.datasource.metricFindQuery(query) .then($scope.transformToSegments) .then($scope.addTemplateVariableSegments) .then(null, $scope.handleQueryError); @@ -133,13 +134,12 @@ function (angular, _, InfluxQueryBuilder) { }; $scope.getTagsOrValues = function(segment, index) { - var query, queryType; + var query; + if (segment.type === 'key' || segment.type === 'plus-button') { - queryType = 'TAG_KEYS'; - query = $scope.queryBuilder.showTagsQuery(); + query = $scope.queryBuilder.buildExploreQuery('TAG_KEYS'); } else if (segment.type === 'value') { - queryType = 'TAG_VALUES'; - query = 'SHOW TAG VALUES FROM "' + $scope.target.measurement + '" WITH KEY = ' + $scope.tagSegments[index-2].value; + query = $scope.queryBuilder.buildExploreQuery('TAG_VALUES', $scope.tagSegments[index-2].value); } else if (segment.type === 'condition') { return $q.when([new MetricSegment('AND'), new MetricSegment('OR')]); } @@ -147,11 +147,11 @@ function (angular, _, InfluxQueryBuilder) { return $q.when([]); } - return $scope.datasource.metricFindQuery(query, queryType) + return $scope.datasource.metricFindQuery(query) .then($scope.transformToSegments) .then($scope.addTemplateVariableSegments) .then(function(results) { - if (queryType === 'TAG_KEYS' && segment.type === 'key') { + if (segment.type === 'key') { results.splice(0, 0, angular.copy($scope.removeTagFilterSegment)); } return results; @@ -160,9 +160,9 @@ function (angular, _, InfluxQueryBuilder) { }; $scope.getGroupByTagSegments = function(segment) { - var query = 'SHOW TAG KEYS FROM "' + $scope.target.measurement + '"'; + var query = $scope.queryBuilder.buildExploreQuery('TAG_KEYS'); - return $scope.datasource.metricFindQuery(query, 'TAG_KEYS') + return $scope.datasource.metricFindQuery(query) .then($scope.transformToSegments) .then($scope.addTemplateVariableSegments) .then(function(results) { diff --git a/public/test/specs/influx09-querybuilder-specs.js b/public/test/specs/influx09-querybuilder-specs.js index 81602da51f7..2b1660f0a90 100644 --- a/public/test/specs/influx09-querybuilder-specs.js +++ b/public/test/specs/influx09-querybuilder-specs.js @@ -62,30 +62,48 @@ define([ }); }); - describe('when building tag keys query', function() { + describe('when building explore queries', function() { - describe('given picked measurement', function() { - it('build query with measurement filter', function() { - var builder = new InfluxQueryBuilder({ measurement: 'cpu', tags: [] }); - var query = builder.showTagsQuery(); - expect(query).to.be('SHOW TAG KEYS FROM "cpu"'); - }); + it('should only have measurement condition in tag keys query given query with measurement', function() { + var builder = new InfluxQueryBuilder({ measurement: 'cpu', tags: [] }); + var query = builder.buildExploreQuery('TAG_KEYS'); + expect(query).to.be('SHOW TAG KEYS FROM "cpu"'); }); - describe('given no picked measurement', function() { - it('build query without filter', function() { - var builder = new InfluxQueryBuilder({ measurement: '', tags: [] }); - var query = builder.showTagsQuery(); - expect(query).to.be('SHOW TAG KEYS'); - }); + it('should have no conditions in tags keys query given query with no measurement or tag', function() { + var builder = new InfluxQueryBuilder({ measurement: '', tags: [] }); + var query = builder.buildExploreQuery('TAG_KEYS'); + expect(query).to.be('SHOW TAG KEYS'); }); - describe('given an existing tag', function() { - it('build query with filter', function() { - var builder = new InfluxQueryBuilder({ measurement: '', tags: [{key: 'host', value: 'se1'}] }); - var query = builder.showTagsQuery(); - expect(query).to.be('SHOW TAG KEYS'); - }); + it('should have where condition in tag keys query with tags', function() { + var builder = new InfluxQueryBuilder({ measurement: '', tags: [{key: 'host', value: 'se1'}] }); + var query = builder.buildExploreQuery('TAG_KEYS'); + expect(query).to.be("SHOW TAG KEYS WHERE host='se1'"); + }); + + it('should have no conditions in measurement query for query with no tags', function() { + var builder = new InfluxQueryBuilder({ measurement: '', tags: [] }); + var query = builder.buildExploreQuery('MEASUREMENTS'); + expect(query).to.be('SHOW MEASUREMENTS'); + }); + + it('should have where condition in measurement query for query with tags', function() { + var builder = new InfluxQueryBuilder({measurement: '', tags: [{key: 'app', value: 'email'}]}); + var query = builder.buildExploreQuery('MEASUREMENTS'); + expect(query).to.be("SHOW MEASUREMENTS WHERE app='email'"); + }); + + it('should have where tag name IN filter in tag values query for query with one tag', function() { + var builder = new InfluxQueryBuilder({measurement: '', tags: [{key: 'app', value: 'asdsadsad'}]}); + var query = builder.buildExploreQuery('TAG_VALUES', 'app'); + expect(query).to.be('SHOW TAG VALUES WITH KEY = "app"'); + }); + + it('should have measurement tag condition and tag name IN filter in tag values query', function() { + var builder = new InfluxQueryBuilder({measurement: 'cpu', tags: [{key: 'app', value: 'email'}, {key: 'host', value: 'server1'}]}); + var query = builder.buildExploreQuery('TAG_VALUES', 'app'); + expect(query).to.be('SHOW TAG VALUES FROM "cpu" WITH KEY = "app" WHERE host=\'server1\''); }); });