Commit 3f167d7f by Torkel Ödegaard

more work on influxdb 0.9 query editor and query builder, can now handle regex…

more work on influxdb 0.9 query editor and query builder, can now handle regex conditions, tag operator  and tag value quotes changes automatically depending if the tag value is a regex or not, #1525
parent dd8d6bc7
......@@ -8,6 +8,13 @@ function (_) {
this.target = target;
}
function renderTagCondition (key, value) {
if (value && value[0] === '/' && value[value.length - 1] === '/') {
return key + ' =~ ' + value;
}
return key + " = '" + value + "'";
}
var p = InfluxQueryBuilder.prototype;
p.build = function() {
......@@ -42,12 +49,12 @@ function (_) {
if (tag.key === withKey) {
return memo;
}
memo.push(' ' + tag.key + '=' + "'" + tag.value + "'");
memo.push(renderTagCondition(tag.key, tag.value));
return memo;
}, []);
if (whereConditions.length > 0) {
query += ' WHERE' + whereConditions.join('AND');
query += ' WHERE ' + whereConditions.join(' AND ');
}
}
......@@ -72,11 +79,11 @@ function (_) {
query += aggregationFunc + '(value)';
query += ' FROM ' + measurement + ' WHERE ';
var conditions = _.map(target.tags, function(tag) {
return tag.key + '=' + "'" + tag.value + "' ";
return renderTagCondition(tag.key, tag.value);
});
conditions.push('$timeFilter');
query += conditions.join('AND ');
query += conditions.join(' AND ');
query += ' GROUP BY time($interval)';
if (target.groupByTags && target.groupByTags.length > 0) {
......
......@@ -39,7 +39,7 @@ function (angular, _, InfluxQueryBuilder) {
$scope.tagSegments.push(MetricSegment.newCondition(tag.condition));
}
$scope.tagSegments.push(new MetricSegment({value: tag.key, type: 'key', cssClass: 'query-segment-key' }));
$scope.tagSegments.push(new MetricSegment({fake: true, value: "=", cssClass: 'query-segment-operator'}));
$scope.tagSegments.push(new MetricSegment.newOperator("="));
$scope.tagSegments.push(new MetricSegment({value: tag.value, type: 'value', cssClass: 'query-segment-value'}));
});
......@@ -177,6 +177,7 @@ function (angular, _, InfluxQueryBuilder) {
$scope.tagSegmentUpdated = function(segment, index) {
$scope.tagSegments[index] = segment;
// handle remove tag condition
if (segment.value === $scope.removeTagFilterSegment.value) {
$scope.tagSegments.splice(index, 3);
if ($scope.tagSegments.length === 0) {
......@@ -193,7 +194,7 @@ function (angular, _, InfluxQueryBuilder) {
if (index > 2) {
$scope.tagSegments.splice(index, 0, MetricSegment.newCondition('AND'));
}
$scope.tagSegments.push(MetricSegment.newFake('=', 'operator', 'query-segment-operator'));
$scope.tagSegments.push(MetricSegment.newOperator('='));
$scope.tagSegments.push(MetricSegment.newFake('select tag value', 'value', 'query-segment-value'));
segment.type = 'key';
segment.cssClass = 'query-segment-key';
......@@ -210,7 +211,7 @@ function (angular, _, InfluxQueryBuilder) {
$scope.rebuildTargetTagConditions = function() {
var tags = [];
var tagIndex = 0;
_.each($scope.tagSegments, function(segment2) {
_.each($scope.tagSegments, function(segment2, index) {
if (segment2.type === 'key') {
if (tags.length === 0) {
tags.push({});
......@@ -219,6 +220,7 @@ function (angular, _, InfluxQueryBuilder) {
}
else if (segment2.type === 'value') {
tags[tagIndex].value = segment2.value;
$scope.tagSegments[index-1] = $scope.getTagValueOperator(segment2.value);
}
else if (segment2.type === 'condition') {
tags.push({ condition: segment2.value });
......@@ -230,6 +232,14 @@ function (angular, _, InfluxQueryBuilder) {
$scope.$parent.get_data();
};
$scope.getTagValueOperator = function(tagValue) {
if (tagValue[0] === '/' && tagValue[tagValue.length - 1] === '/') {
return MetricSegment.newOperator('=~');
}
return MetricSegment.newOperator('=');
};
function MetricSegment(options) {
if (options === '*' || options.value === '*') {
this.value = '*';
......@@ -265,6 +275,10 @@ function (angular, _, InfluxQueryBuilder) {
return new MetricSegment({value: condition, type: 'condition', cssClass: 'query-keyword' });
};
MetricSegment.newOperator = function(op) {
return new MetricSegment({value: op, type: 'operator', cssClass: 'query-segment-operator' });
};
MetricSegment.newPlusButton = function() {
return new MetricSegment({fake: true, html: '<i class="fa fa-plus "></i>', type: 'plus-button' });
};
......
......@@ -27,10 +27,15 @@ define([
var query = builder.build();
it('should generate correct query', function() {
expect(query).to.be('SELECT mean(value) FROM "cpu" WHERE hostname=\'server1\' AND $timeFilter'
expect(query).to.be('SELECT mean(value) FROM "cpu" WHERE hostname = \'server1\' AND $timeFilter'
+ ' GROUP BY time($interval) ORDER BY asc');
});
it('should switch regex operator with tag value is regex', function() {
var builder = new InfluxQueryBuilder({measurement: 'cpu', 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) ORDER BY asc');
});
});
describe('series with multiple tags only', function() {
......@@ -42,7 +47,7 @@ define([
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 ' +
expect(query).to.be('SELECT mean(value) FROM "cpu" WHERE hostname = \'server1\' AND app = \'email\' AND ' +
'$timeFilter GROUP BY time($interval) ORDER BY asc');
});
});
......@@ -78,7 +83,7 @@ define([
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'");
expect(query).to.be("SHOW TAG KEYS WHERE host = 'se1'");
});
it('should have no conditions in measurement query for query with no tags', function() {
......@@ -90,7 +95,7 @@ define([
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'");
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() {
......@@ -102,7 +107,13 @@ define([
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\'');
expect(query).to.be('SHOW TAG VALUES FROM "cpu" WITH KEY = "app" WHERE host = \'server1\'');
});
it('should switch to regex operator in tag condition', function() {
var builder = new InfluxQueryBuilder({measurement: 'cpu', tags: [{key: 'host', value: '/server.*/'}]});
var query = builder.buildExploreQuery('TAG_VALUES', 'app');
expect(query).to.be('SHOW TAG VALUES FROM "cpu" WITH KEY = "app" WHERE host =~ /server.*/');
});
});
......
......@@ -65,6 +65,18 @@ define([
});
});
describe('when last tag value segment is updated to regex', function() {
beforeEach(function() {
ctx.scope.init();
ctx.scope.tagSegmentUpdated({value: 'asd', type: 'plus-button'}, 0);
ctx.scope.tagSegmentUpdated({value: '/server.*/', type: 'value'}, 2);
});
it('should update operator', function() {
expect(ctx.scope.tagSegments[1].value).to.be('=~');
});
});
describe('when second tag key is added', function() {
beforeEach(function() {
ctx.scope.init();
......
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