From 9a9902cea9f212983cf87002b4177422e260fda1 Mon Sep 17 00:00:00 2001 From: Denis Doria Date: Sat, 8 Aug 2015 13:31:37 +0200 Subject: [PATCH 1/6] Includes more comparators/operators for influxdb This patch includes some missing comparators/operators for influxdb: > - greater than < - less than <> - not equal !~ - doesn't match against It includes the tag.operator fields to facilitate identification of the operators on the segments. It keeps the logic for the regex syntax; although it changes the way to validate it, to handle the new operators use case. --- .../datasource/influxdb/queryBuilder.js | 9 ++++-- .../plugins/datasource/influxdb/queryCtrl.js | 28 ++++++++++++++----- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/public/app/plugins/datasource/influxdb/queryBuilder.js b/public/app/plugins/datasource/influxdb/queryBuilder.js index 9e9cd01ffc8..4c1ffeb2357 100644 --- a/public/app/plugins/datasource/influxdb/queryBuilder.js +++ b/public/app/plugins/datasource/influxdb/queryBuilder.js @@ -10,14 +10,16 @@ function (_) { function renderTagCondition (tag, index) { var str = ""; + var operator = (tag.operator || '='); if (index > 0) { str = (tag.condition || 'AND') + ' '; } - if (tag.value && tag.value[0] === '/' && tag.value[tag.value.length - 1] === '/') { - return str + '"' +tag.key + '"' + ' =~ ' + tag.value; + if (tag.value && (operator === '=~' || operator === '!~') && /^\/.*\/$/.test(tag.value)) { + return str + '"' + tag.key + '"' + ' ' + operator + ' ' + tag.value; } - return str + '"' + tag.key + '"' + " = '" + tag.value + "'"; + + return str + '"' + tag.key + '" ' + operator + " '" + tag.value + "'"; } var p = InfluxQueryBuilder.prototype; @@ -127,3 +129,4 @@ function (_) { return InfluxQueryBuilder; }); + diff --git a/public/app/plugins/datasource/influxdb/queryCtrl.js b/public/app/plugins/datasource/influxdb/queryCtrl.js index 973bffea02e..5275b8003ba 100644 --- a/public/app/plugins/datasource/influxdb/queryCtrl.js +++ b/public/app/plugins/datasource/influxdb/queryCtrl.js @@ -35,7 +35,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.newOperator("=")); + $scope.tagSegments.push(MetricSegment.newOperator(tag.operator)); $scope.tagSegments.push(new MetricSegment({value: tag.value, type: 'value', cssClass: 'query-segment-value'})); }); @@ -150,6 +150,10 @@ function (angular, _, InfluxQueryBuilder) { 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')]); + } else if (segment.type === 'operator') { + return $q.when([MetricSegment.newOperator('='), MetricSegment.newOperator('<>'), + MetricSegment.newOperator('<'), MetricSegment.newOperator('>'), + MetricSegment.newOperator('=~'), MetricSegment.newOperator('!~')]); } else { return $q.when([]); @@ -238,6 +242,7 @@ function (angular, _, InfluxQueryBuilder) { $scope.rebuildTargetTagConditions = function() { var tags = []; var tagIndex = 0; + var tagOperator = ""; _.each($scope.tagSegments, function(segment2, index) { if (segment2.type === 'key') { if (tags.length === 0) { @@ -246,25 +251,33 @@ function (angular, _, InfluxQueryBuilder) { tags[tagIndex].key = segment2.value; } else if (segment2.type === 'value') { + tagOperator = $scope.getTagValueOperator(segment2.value, tags[tagIndex].operator) + if (tagOperator) { + $scope.tagSegments[index-1] = MetricSegment.newOperator(tagOperator); + tags[tagIndex].operator = tagOperator; + } tags[tagIndex].value = segment2.value; - $scope.tagSegments[index-1] = $scope.getTagValueOperator(segment2.value); } else if (segment2.type === 'condition') { tags.push({ condition: segment2.value }); tagIndex += 1; } + else if (segment2.type === 'operator') { + tags[tagIndex].operator = segment2.value; + } }); $scope.target.tags = tags; $scope.$parent.get_data(); }; - $scope.getTagValueOperator = function(tagValue) { - if (tagValue[0] === '/' && tagValue[tagValue.length - 1] === '/') { - return MetricSegment.newOperator('=~'); + $scope.getTagValueOperator = function(tagValue, tagOperator) { + if (tagOperator !== '=~' && tagOperator !== '!~' && /^\/.*\/$/.test(tagValue)) { + return '=~'; + } + else if ((tagOperator === '=~' || tagOperator === '!~') && /^(?!\/.*\/$)/.test(tagValue)) { + return '='; } - - return MetricSegment.newOperator('='); }; function MetricSegment(options) { @@ -317,3 +330,4 @@ function (angular, _, InfluxQueryBuilder) { }); }); + From a51d900da023386f55b2dbe320386b7152cf216a Mon Sep 17 00:00:00 2001 From: Denis Doria Date: Sat, 8 Aug 2015 13:54:01 +0200 Subject: [PATCH 2/6] Fix code style and included missed semicolon --- public/app/plugins/datasource/influxdb/queryBuilder.js | 3 +-- public/app/plugins/datasource/influxdb/queryCtrl.js | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/public/app/plugins/datasource/influxdb/queryBuilder.js b/public/app/plugins/datasource/influxdb/queryBuilder.js index 4c1ffeb2357..e32fce9caf0 100644 --- a/public/app/plugins/datasource/influxdb/queryBuilder.js +++ b/public/app/plugins/datasource/influxdb/queryBuilder.js @@ -16,7 +16,7 @@ function (_) { } if (tag.value && (operator === '=~' || operator === '!~') && /^\/.*\/$/.test(tag.value)) { - return str + '"' + tag.key + '"' + ' ' + operator + ' ' + tag.value; + return str + '"' + tag.key + '"' + ' ' + operator + ' ' + tag.value; } return str + '"' + tag.key + '" ' + operator + " '" + tag.value + "'"; @@ -129,4 +129,3 @@ function (_) { return InfluxQueryBuilder; }); - diff --git a/public/app/plugins/datasource/influxdb/queryCtrl.js b/public/app/plugins/datasource/influxdb/queryCtrl.js index 5275b8003ba..a536a8eee35 100644 --- a/public/app/plugins/datasource/influxdb/queryCtrl.js +++ b/public/app/plugins/datasource/influxdb/queryCtrl.js @@ -251,7 +251,7 @@ function (angular, _, InfluxQueryBuilder) { tags[tagIndex].key = segment2.value; } else if (segment2.type === 'value') { - tagOperator = $scope.getTagValueOperator(segment2.value, tags[tagIndex].operator) + tagOperator = $scope.getTagValueOperator(segment2.value, tags[tagIndex].operator); if (tagOperator) { $scope.tagSegments[index-1] = MetricSegment.newOperator(tagOperator); tags[tagIndex].operator = tagOperator; @@ -330,4 +330,3 @@ function (angular, _, InfluxQueryBuilder) { }); }); - From 5a906e0f3efcd9da80c316ecf2469b63007864e0 Mon Sep 17 00:00:00 2001 From: Denis Doria Date: Sat, 8 Aug 2015 14:40:55 +0200 Subject: [PATCH 3/6] Fix small corner case --- public/app/plugins/datasource/influxdb/queryBuilder.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/public/app/plugins/datasource/influxdb/queryBuilder.js b/public/app/plugins/datasource/influxdb/queryBuilder.js index e32fce9caf0..95c8bd1b4dd 100644 --- a/public/app/plugins/datasource/influxdb/queryBuilder.js +++ b/public/app/plugins/datasource/influxdb/queryBuilder.js @@ -17,6 +17,8 @@ function (_) { if (tag.value && (operator === '=~' || operator === '!~') && /^\/.*\/$/.test(tag.value)) { return str + '"' + tag.key + '"' + ' ' + operator + ' ' + tag.value; + } else if (tag.value && /^\/.*\/$/.test(tag.value)) { + return str + '"' + tag.key + '"' + ' =~ ' + tag.value; } return str + '"' + tag.key + '" ' + operator + " '" + tag.value + "'"; From 4bd83443f879c3ce145b9c2720e339b20134be54 Mon Sep 17 00:00:00 2001 From: Denis Doria Date: Sat, 8 Aug 2015 17:00:10 +0200 Subject: [PATCH 4/6] Fixing issue for missing tag.operator This should fix the case from when we migrate from a version that doesn't contain tag.operator. --- public/app/plugins/datasource/influxdb/queryCtrl.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/public/app/plugins/datasource/influxdb/queryCtrl.js b/public/app/plugins/datasource/influxdb/queryCtrl.js index a536a8eee35..c5697268297 100644 --- a/public/app/plugins/datasource/influxdb/queryCtrl.js +++ b/public/app/plugins/datasource/influxdb/queryCtrl.js @@ -35,7 +35,13 @@ 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(MetricSegment.newOperator(tag.operator)); + if (tag.operator) { + $scope.tagSegments.push(MetricSegment.newOperator(tag.operator)); + } else if (/^\/.*\/$/.test(tag.value)) { + $scope.tagSegments.push(MetricSegment.newOperator('=~')); + } else { + $scope.tagSegments.push(MetricSegment.newOperator('=')); + } $scope.tagSegments.push(new MetricSegment({value: tag.value, type: 'value', cssClass: 'query-segment-value'})); }); From 42caf02fb03d703e7135f810b7534436e0a2344f Mon Sep 17 00:00:00 2001 From: Denis Doria Date: Sun, 9 Aug 2015 11:58:08 +0200 Subject: [PATCH 5/6] Include context for operators Depending of the value a different set of operators will show up. If regex only =~ and !~ will show up. Any other value will show =, <>, <, >. --- public/app/plugins/datasource/influxdb/queryCtrl.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/public/app/plugins/datasource/influxdb/queryCtrl.js b/public/app/plugins/datasource/influxdb/queryCtrl.js index c5697268297..0278a2c3097 100644 --- a/public/app/plugins/datasource/influxdb/queryCtrl.js +++ b/public/app/plugins/datasource/influxdb/queryCtrl.js @@ -156,10 +156,12 @@ function (angular, _, InfluxQueryBuilder) { 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')]); - } else if (segment.type === 'operator') { + } else if (segment.type === 'operator' && /^(?!\/.*\/$)/.test($scope.tagSegments[index+1].value)) { return $q.when([MetricSegment.newOperator('='), MetricSegment.newOperator('<>'), - MetricSegment.newOperator('<'), MetricSegment.newOperator('>'), - MetricSegment.newOperator('=~'), MetricSegment.newOperator('!~')]); + MetricSegment.newOperator('<'), MetricSegment.newOperator('>')]); + + } else if (segment.type === 'operator' && /^\/.*\/$/.test($scope.tagSegments[index+1].value)) { + return $q.when([ MetricSegment.newOperator('=~'), MetricSegment.newOperator('!~')]); } else { return $q.when([]); From 950d4bb24e0f5165bb361211315eb8eaa6363cf3 Mon Sep 17 00:00:00 2001 From: Denis Doria Date: Sun, 9 Aug 2015 12:03:51 +0200 Subject: [PATCH 6/6] Code style correction --- public/app/plugins/datasource/influxdb/queryCtrl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/plugins/datasource/influxdb/queryCtrl.js b/public/app/plugins/datasource/influxdb/queryCtrl.js index 0278a2c3097..52e9e8277d8 100644 --- a/public/app/plugins/datasource/influxdb/queryCtrl.js +++ b/public/app/plugins/datasource/influxdb/queryCtrl.js @@ -161,7 +161,7 @@ function (angular, _, InfluxQueryBuilder) { MetricSegment.newOperator('<'), MetricSegment.newOperator('>')]); } else if (segment.type === 'operator' && /^\/.*\/$/.test($scope.tagSegments[index+1].value)) { - return $q.when([ MetricSegment.newOperator('=~'), MetricSegment.newOperator('!~')]); + return $q.when([MetricSegment.newOperator('=~'), MetricSegment.newOperator('!~')]); } else { return $q.when([]);