mirror of
https://github.com/grafana/grafana.git
synced 2024-11-25 18:30:41 -06:00
More work on new influxdb query editor, #1525
This commit is contained in:
parent
d14b570d76
commit
6fd37779b8
@ -91,7 +91,7 @@
|
||||
time($interval)
|
||||
</li>
|
||||
<li ng-repeat="segment in groupBySegments">
|
||||
<metric-segment segment="segment" get-alt-segments="getTagsOrValues(segment, 0)" on-value-changed="groupByTagUpdated(segment, $index)"></metric-segment>
|
||||
<metric-segment segment="segment" get-alt-segments="getGroupByTagSegments(segment, 0)" on-value-changed="groupByTagUpdated(segment, $index)"></metric-segment>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a class="tight-form-item pointer" data-toggle="dropdown" bs-tooltip="'Insert missing values, important when stacking'" data-placement="right">
|
||||
|
@ -1,5 +1,5 @@
|
||||
define([
|
||||
'lodash'
|
||||
'lodash'
|
||||
],
|
||||
function (_) {
|
||||
'use strict';
|
||||
@ -32,12 +32,18 @@ function (_) {
|
||||
}
|
||||
|
||||
query += aggregationFunc + '(value)';
|
||||
query += ' FROM ' + measurement + ' WHERE $timeFilter';
|
||||
query += _.map(target.tags, function(tag) {
|
||||
return ' AND ' + tag.key + '=' + "'" + tag.value + "'";
|
||||
}).join('');
|
||||
query += ' FROM ' + measurement + ' WHERE ';
|
||||
var conditions = _.map(target.tags, function(tag) {
|
||||
return tag.key + '=' + "'" + tag.value + "' ";
|
||||
});
|
||||
conditions.push('$timeFilter');
|
||||
|
||||
query += conditions.join('AND ');
|
||||
|
||||
query += ' GROUP BY time($interval)';
|
||||
if (target.groupByTags && target.groupByTags.length > 0) {
|
||||
query += ', ' + target.groupByTags.join();
|
||||
}
|
||||
|
||||
if (target.fill) {
|
||||
query += ' fill(' + target.fill + ')';
|
||||
|
@ -35,14 +35,12 @@ function (angular, _) {
|
||||
if (tag.condition) {
|
||||
$scope.tagSegments.push(MetricSegment.newCondition(tag.condition));
|
||||
}
|
||||
$scope.tagSegments.push(new MetricSegment({value: tag.key, type: 'key' }));
|
||||
$scope.tagSegments.push(new MetricSegment({fake: true, value: "="}));
|
||||
$scope.tagSegments.push(new MetricSegment({value: tag.value, type: 'value'}));
|
||||
$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({value: tag.value, type: 'value', cssClass: 'query-segment-value'}));
|
||||
});
|
||||
|
||||
if ($scope.tagSegments.length % 3 === 0) {
|
||||
$scope.tagSegments.push(MetricSegment.newPlusButton());
|
||||
}
|
||||
$scope.fixTagSegments();
|
||||
|
||||
$scope.groupBySegments = [];
|
||||
_.each(target.groupByTags, function(tag) {
|
||||
@ -50,12 +48,37 @@ function (angular, _) {
|
||||
});
|
||||
|
||||
$scope.groupBySegments.push(MetricSegment.newPlusButton());
|
||||
|
||||
$scope.removeTagFilterSegment = new MetricSegment({fake: true, value: 'remove tag filter'});
|
||||
$scope.removeGroupBySegment = new MetricSegment({fake: true, value: 'remove group by'});
|
||||
};
|
||||
|
||||
$scope.fixTagSegments = function() {
|
||||
var count = $scope.tagSegments.length;
|
||||
var lastSegment = $scope.tagSegments[Math.max(count-1, 0)];
|
||||
|
||||
if (!lastSegment || lastSegment.type !== 'plus-button') {
|
||||
$scope.tagSegments.push(MetricSegment.newPlusButton());
|
||||
}
|
||||
};
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
if (index === $scope.groupBySegments.length-1) {
|
||||
$scope.groupBySegments.push(MetricSegment.newPlusButton());
|
||||
}
|
||||
|
||||
segment.type = 'group-by-key';
|
||||
segment.fake = false;
|
||||
|
||||
$scope.target.groupByTags[index] = segment.value;
|
||||
$scope.$parent.get_data();
|
||||
};
|
||||
|
||||
$scope.changeFunction = function(func) {
|
||||
@ -65,7 +88,6 @@ function (angular, _) {
|
||||
|
||||
$scope.measurementChanged = function() {
|
||||
$scope.target.measurement = $scope.measurementSegment.value;
|
||||
console.log('measurement updated', $scope.target.measurement);
|
||||
$scope.$parent.get_data();
|
||||
};
|
||||
|
||||
@ -126,8 +148,23 @@ function (angular, _) {
|
||||
.then($scope.transformToSegments)
|
||||
.then($scope.addTemplateVariableSegments)
|
||||
.then(function(results) {
|
||||
if (queryType === 'TAG_KEYS' && segment.type !== 'plus-button') {
|
||||
results.push(new MetricSegment({fake: true, value: 'remove tag filter'}));
|
||||
if (queryType === 'TAG_KEYS' && segment.type === 'key') {
|
||||
results.push(angular.copy($scope.removeTagFilterSegment));
|
||||
}
|
||||
return results;
|
||||
})
|
||||
.then(null, $scope.handleQueryError);
|
||||
};
|
||||
|
||||
$scope.getGroupByTagSegments = function(segment) {
|
||||
var query = 'SHOW TAG KEYS FROM "' + $scope.target.measurement + '"';
|
||||
|
||||
return $scope.datasource.metricFindQuery(query, 'TAG_KEYS')
|
||||
.then($scope.transformToSegments)
|
||||
.then($scope.addTemplateVariableSegments)
|
||||
.then(function(results) {
|
||||
if (segment.type !== 'plus-button') {
|
||||
results.push(angular.copy($scope.removeGroupBySegment));
|
||||
}
|
||||
return results;
|
||||
})
|
||||
@ -137,13 +174,15 @@ function (angular, _) {
|
||||
$scope.tagSegmentUpdated = function(segment, index) {
|
||||
$scope.tagSegments[index] = segment;
|
||||
|
||||
if (segment.value === 'remove tag filter') {
|
||||
if (segment.value === $scope.removeTagFilterSegment.value) {
|
||||
$scope.tagSegments.splice(index, 3);
|
||||
if ($scope.tagSegments.length === 0) {
|
||||
$scope.tagSegments.push(MetricSegment.newPlusButton());
|
||||
} else {
|
||||
$scope.tagSegments.splice(index-1, 1);
|
||||
$scope.tagSegments.push(MetricSegment.newPlusButton());
|
||||
} else if ($scope.tagSegments.length > 2) {
|
||||
$scope.tagSegments.splice(Math.max(index-1, 0), 1);
|
||||
if ($scope.tagSegments[$scope.tagSegments.length-1].type !== 'plus-button') {
|
||||
$scope.tagSegments.push(MetricSegment.newPlusButton());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -151,9 +190,10 @@ function (angular, _) {
|
||||
if (index > 2) {
|
||||
$scope.tagSegments.splice(index, 0, MetricSegment.newCondition('AND'));
|
||||
}
|
||||
$scope.tagSegments.push(new MetricSegment({fake: true, value: '=', type: 'operator'}));
|
||||
$scope.tagSegments.push(new MetricSegment({fake: true, value: 'select tag value', type: 'value' }));
|
||||
$scope.tagSegments.push(MetricSegment.newFake('=', 'operator', 'query-segment-operator'));
|
||||
$scope.tagSegments.push(MetricSegment.newFake('select tag value', 'value', 'query-segment-value'));
|
||||
segment.type = 'key';
|
||||
segment.cssClass = 'query-segment-key';
|
||||
}
|
||||
|
||||
if ((index+1) === $scope.tagSegments.length) {
|
||||
@ -165,10 +205,13 @@ function (angular, _) {
|
||||
};
|
||||
|
||||
$scope.rebuildTargetTagConditions = function() {
|
||||
var tags = [{}];
|
||||
var tags = [];
|
||||
var tagIndex = 0;
|
||||
_.each($scope.tagSegments, function(segment2) {
|
||||
if (segment2.type === 'key') {
|
||||
if (tags.length === 0) {
|
||||
tags.push({});
|
||||
}
|
||||
tags[tagIndex].key = segment2.value;
|
||||
}
|
||||
else if (segment2.type === 'value') {
|
||||
@ -211,6 +254,10 @@ function (angular, _) {
|
||||
return new MetricSegment({value: 'select measurement', fake: true});
|
||||
};
|
||||
|
||||
MetricSegment.newFake = function(text, type, cssClass) {
|
||||
return new MetricSegment({value: text, fake: true, type: type, cssClass: cssClass});
|
||||
};
|
||||
|
||||
MetricSegment.newCondition = function(condition) {
|
||||
return new MetricSegment({value: condition, type: 'condition', cssClass: 'query-keyword' });
|
||||
};
|
||||
|
@ -343,4 +343,16 @@
|
||||
color: @blue;
|
||||
}
|
||||
|
||||
.query-segment-key {
|
||||
border-right: none;
|
||||
padding-right: 1px;
|
||||
}
|
||||
|
||||
.query-segment-operator {
|
||||
padding-right: 1px;
|
||||
border-right: none;
|
||||
color: @orange;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@ define([
|
||||
|
||||
});
|
||||
|
||||
describe('series with tags only', function() {
|
||||
describe('series with single tag only', function() {
|
||||
var builder = new InfluxQueryBuilder({
|
||||
measurement: 'cpu',
|
||||
tags: [{key: 'hostname', value: 'server1'}]
|
||||
@ -27,12 +27,41 @@ define([
|
||||
var query = builder.build();
|
||||
|
||||
it('should generate correct query', function() {
|
||||
expect(query).to.be('SELECT mean(value) FROM "cpu" WHERE $timeFilter ' +
|
||||
'AND hostname=\'server1\' GROUP BY time($interval) ORDER BY asc');
|
||||
expect(query).to.be('SELECT mean(value) FROM "cpu" WHERE hostname=\'server1\' AND $timeFilter'
|
||||
+ ' GROUP BY time($interval) ORDER BY asc');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
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 ' +
|
||||
'$timeFilter GROUP BY time($interval) ORDER BY asc');
|
||||
});
|
||||
});
|
||||
|
||||
describe('series with groupByTag', function() {
|
||||
var builder = new InfluxQueryBuilder({
|
||||
measurement: 'cpu',
|
||||
tags: [],
|
||||
groupByTags: ["host"]
|
||||
});
|
||||
|
||||
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), host ORDER BY asc');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -101,13 +101,31 @@ define([
|
||||
});
|
||||
});
|
||||
|
||||
describe('when deleting is changed', function() {
|
||||
describe('when deleting first tag filter after value is selected', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.init();
|
||||
ctx.scope.tagSegmentUpdated({value: 'asd', type: 'plus-button' }, 0);
|
||||
ctx.scope.tagSegmentUpdated({value: 'server1', type: 'value'}, 2);
|
||||
ctx.scope.tagSegmentUpdated(ctx.scope.removeTagFilterSegment, 0);
|
||||
});
|
||||
|
||||
it('should remove tags', function() {
|
||||
expect(ctx.scope.target.tags.length).to.be(0);
|
||||
});
|
||||
|
||||
it('should remove all segment after 2 and replace with plus button', function() {
|
||||
expect(ctx.scope.tagSegments.length).to.be(1);
|
||||
expect(ctx.scope.tagSegments[0].type).to.be('plus-button');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when deleting second tag value before second tag value is complete', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.init();
|
||||
ctx.scope.tagSegmentUpdated({value: 'asd', type: 'plus-button' }, 0);
|
||||
ctx.scope.tagSegmentUpdated({value: 'server1', type: 'value'}, 2);
|
||||
ctx.scope.tagSegmentUpdated({value: 'key2', type: 'plus-button'}, 3);
|
||||
ctx.scope.tagSegmentUpdated({value: 'remove tag filter', type: 'key'}, 4);
|
||||
ctx.scope.tagSegmentUpdated(ctx.scope.removeTagFilterSegment, 4);
|
||||
});
|
||||
|
||||
it('should remove all segment after 2 and replace with plus button', function() {
|
||||
@ -116,5 +134,69 @@ define([
|
||||
});
|
||||
});
|
||||
|
||||
describe('when deleting second tag value before second tag value is complete', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.init();
|
||||
ctx.scope.tagSegmentUpdated({value: 'asd', type: 'plus-button' }, 0);
|
||||
ctx.scope.tagSegmentUpdated({value: 'server1', type: 'value'}, 2);
|
||||
ctx.scope.tagSegmentUpdated({value: 'key2', type: 'plus-button'}, 3);
|
||||
ctx.scope.tagSegmentUpdated(ctx.scope.removeTagFilterSegment, 4);
|
||||
});
|
||||
|
||||
it('should remove all segment after 2 and replace with plus button', function() {
|
||||
expect(ctx.scope.tagSegments.length).to.be(4);
|
||||
expect(ctx.scope.tagSegments[3].type).to.be('plus-button');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when deleting second tag value after second tag filter is complete', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.init();
|
||||
ctx.scope.tagSegmentUpdated({value: 'asd', type: 'plus-button' }, 0);
|
||||
ctx.scope.tagSegmentUpdated({value: 'server1', type: 'value'}, 2);
|
||||
ctx.scope.tagSegmentUpdated({value: 'key2', type: 'plus-button'}, 3);
|
||||
ctx.scope.tagSegmentUpdated({value: 'value', type: 'value'}, 6);
|
||||
ctx.scope.tagSegmentUpdated(ctx.scope.removeTagFilterSegment, 4);
|
||||
});
|
||||
|
||||
it('should remove all segment after 2 and replace with plus button', function() {
|
||||
expect(ctx.scope.tagSegments.length).to.be(4);
|
||||
expect(ctx.scope.tagSegments[3].type).to.be('plus-button');
|
||||
});
|
||||
});
|
||||
|
||||
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');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user