Commit f00320c8 by Torkel Ödegaard

feat(influxdb): query editor is starting to work, can now add group by parts

parent 5ba19144
......@@ -16,22 +16,20 @@ class InfluxQuery {
this.target = target;
target.tags = target.tags || [];
target.groupBy = target.groupBy || [{type: 'time', interval: 'auto'}];
target.groupBy = target.groupBy || [{type: 'time', params: ['$interval']}];
target.select = target.select || [[
{type: 'field', params: ['value']},
{type: 'mean', params: []},
]];
this.updateSelectParts();
this.groupByParts = [
queryPart.create({type: 'time', params: ['$interval']})
];
this.updateProjection();
}
updateSelectParts() {
updateProjection() {
this.selectModels = _.map(this.target.select, function(parts: any) {
return _.map(parts, queryPart.create);
});
this.groupByParts = _.map(this.target.groupBy, queryPart.create);
}
updatePersistedParts() {
......@@ -42,9 +40,32 @@ class InfluxQuery {
});
}
hasGroupByTime() {
return false;
}
hasFill() {
return false;
}
addGroupBy(value) {
var stringParts = value.match(/^(\w+)\((.*)\)$/);
var typePart = stringParts[1];
var arg = stringParts[2];
console.log(value, stringParts);
var partModel = queryPart.create({type: typePart, params: [arg]});
this.target.groupBy.push(partModel.part);
this.updateProjection();
}
removeGroupByPart(part, index) {
this.target.groupBy.splice(index, 1);
this.updateProjection();
}
removeSelect(index: number) {
this.target.select.splice(index, 1);
this.updateSelectParts();
this.updateProjection();
}
removeSelectPart(selectParts, part) {
......@@ -139,14 +160,13 @@ class InfluxQuery {
query += conditions.join(' ');
query += (conditions.length > 0 ? ' AND ' : '') + '$timeFilter';
query += ' GROUP BY';
for (i = 0; i < target.groupBy.length; i++) {
var group = target.groupBy[i];
if (group.type === 'time') {
query += ' time(' + this.getGroupByTimeInterval(group.interval) + ')';
} else {
query += ', "' + group.key + '"';
query += ' GROUP BY ';
for (i = 0; i < this.groupByParts.length; i++) {
var part = this.groupByParts[i];
if (i > 0) {
query += ', ';
}
query += part.render('');
}
if (target.fill) {
......
......@@ -73,24 +73,22 @@
<li ng-repeat="part in selectParts">
<influx-query-part-editor part="part" class="tight-form-item tight-form-func" remove-action="removeSelectPart(selectParts, part)" part-updated="selectPartUpdated(selectParts, part)"></influx-query-part-editor>
</li>
<li>
<metric-segment segment="selectPlusButton" get-options="getSelectOptions(selectParts)" on-change="selectAction(selectParts, $index)"></metric-segment>
</li>
<li class="dropdown" dropdown-typeahead="selectMenu" dropdown-typeahead-on-select="addSelectPart(selectParts, $item, $subItem)">
</li>
</ul>
<div class="clearfix"></div>
</div>
<div class="tight-form" ng-repeat="part in queryModel.groupByParts">
<div class="tight-form">
<ul class="tight-form-list">
<li class="tight-form-item query-keyword tight-form-align" style="width: 75px;">
<span ng-show="$index === 0">GROUP BY</span>
</li>
<li>
<influx-query-part-editor part="part" class="tight-form-item tight-form-func"></influx-query-part-editor>
<li ng-repeat="part in queryModel.groupByParts">
<influx-query-part-editor part="part" class="tight-form-item tight-form-func" remove-action="removeGroupByPart(part, $index)" part-updated="get_data();"></influx-query-part-editor>
</li>
<li class="dropdown" dropdown-typeahead="groupByMenu" dropdown-typeahead-on-select="groupByMenuAction(parts, $item, $subItem)">
<li>
<metric-segment segment="groupBySegment" get-options="getGroupByOptions()" on-change="groupByAction(part, $index)"></metric-segment>
</li>
</ul>
<div class="clearfix"></div>
......
......@@ -19,6 +19,7 @@ function (angular, _, InfluxQueryBuilder, InfluxQuery, queryPart) {
$scope.target = $scope.target;
$scope.queryModel = new InfluxQuery($scope.target);
$scope.queryBuilder = new InfluxQueryBuilder($scope.target);
$scope.groupBySegment = uiSegmentSrv.newPlusButton();
if (!$scope.target.measurement) {
$scope.measurementSegment = uiSegmentSrv.newSelectMeasurement();
......@@ -60,16 +61,39 @@ function (angular, _, InfluxQueryBuilder, InfluxQuery, queryPart) {
memo.push(menu);
return memo;
}, []);
};
$scope.groupByMenu = _.reduce(categories, function(memo, cat, key) {
var menu = {text: key};
menu.submenu = _.map(cat, function(item) {
return {text: item.type, value: item.type};
$scope.getGroupByOptions = function() {
var query = $scope.queryBuilder.buildExploreQuery('TAG_KEYS');
return $scope.datasource.metricFindQuery(query)
.then(function(tags) {
var options = [];
if (!$scope.queryModel.hasFill()) {
options.push(uiSegmentSrv.newSegment({value: 'fill(option)'}));
}
if (!$scope.queryModel.hasGroupByTime()) {
options.push(uiSegmentSrv.newSegment({value: 'time($interval)'}));
}
_.each(tags, function(tag) {
options.push(uiSegmentSrv.newSegment({value: 'tag(' + tag.text + ')'}));
});
memo.push(menu);
return memo;
}, []);
return options;
})
.then(null, $scope.handleQueryError);
};
$scope.groupByAction = function() {
$scope.queryModel.addGroupBy($scope.groupBySegment.value);
var plusButton = uiSegmentSrv.newPlusButton();
$scope.groupBySegment.value = plusButton.value;
$scope.groupBySegment.html = plusButton.html;
$scope.get_data();
};
$scope.removeGroupByPart = function(part, index) {
$scope.queryModel.removeGroupByPart(part, index);
$scope.get_data();
};
$scope.addSelectPart = function(selectParts, cat, subitem) {
......@@ -178,12 +202,7 @@ function (angular, _, InfluxQueryBuilder, InfluxQuery, queryPart) {
};
$scope.getTagOptions = function() {
var query = $scope.queryBuilder.buildExploreQuery('TAG_KEYS');
return $scope.datasource.metricFindQuery(query)
.then($scope.transformToSegments(false))
.then(null, $scope.handleQueryError);
};
};
$scope.setFill = function(fill) {
$scope.target.fill = fill;
......
......@@ -185,6 +185,14 @@ QueryPartDef.register({
});
QueryPartDef.register({
type: 'tag',
category: groupByTimeFunctions,
params: [{name: 'tag', type: 'string'}],
defaultParams: ['tag'],
renderer: quotedIdentityRenderer,
});
QueryPartDef.register({
type: 'math',
addStrategy: addMathStrategy,
category: categories.Math,
......
......@@ -21,10 +21,10 @@ describe.only('InfluxQuery', function() {
measurement: 'cpu',
select: [
[
{name: 'field', params: ['value']},
{name: 'mean', params: []},
{name: 'math', params: ['/100']},
{name: 'alias', params: ['text']},
{type: 'field', params: ['value']},
{type: 'mean', params: []},
{type: 'math', params: ['/100']},
{type: 'alias', params: ['text']},
]
]
});
......@@ -39,56 +39,56 @@ describe.only('InfluxQuery', function() {
it('should add mean after after field', function() {
var query = new InfluxQuery({
measurement: 'cpu',
select: [[{name: 'field', params: ['value']}]]
select: [[{type: 'field', params: ['value']}]]
});
query.addSelectPart(query.selectModels[0], 'mean');
expect(query.target.select[0].length).to.be(2);
expect(query.target.select[0][1].name).to.be('mean');
expect(query.target.select[0][1].type).to.be('mean');
});
it('should replace sum by mean', function() {
var query = new InfluxQuery({
measurement: 'cpu',
select: [[{name: 'field', params: ['value']}, {name: 'mean'}]]
select: [[{type: 'field', params: ['value']}, {type: 'mean'}]]
});
query.addSelectPart(query.selectModels[0], 'sum');
expect(query.target.select[0].length).to.be(2);
expect(query.target.select[0][1].name).to.be('sum');
expect(query.target.select[0][1].type).to.be('sum');
});
it('should add math before alias', function() {
var query = new InfluxQuery({
measurement: 'cpu',
select: [[{name: 'field', params: ['value']}, {name: 'mean'}, {name: 'alias'}]]
select: [[{type: 'field', params: ['value']}, {type: 'mean'}, {type: 'alias'}]]
});
query.addSelectPart(query.selectModels[0], 'math');
expect(query.target.select[0].length).to.be(4);
expect(query.target.select[0][2].name).to.be('math');
expect(query.target.select[0][2].type).to.be('math');
});
it('should add math last', function() {
var query = new InfluxQuery({
measurement: 'cpu',
select: [[{name: 'field', params: ['value']}, {name: 'mean'}]]
select: [[{type: 'field', params: ['value']}, {type: 'mean'}]]
});
query.addSelectPart(query.selectModels[0], 'math');
expect(query.target.select[0].length).to.be(3);
expect(query.target.select[0][2].name).to.be('math');
expect(query.target.select[0][2].type).to.be('math');
});
it('should replace math', function() {
var query = new InfluxQuery({
measurement: 'cpu',
select: [[{name: 'field', params: ['value']}, {name: 'mean'}, {name: 'math'}]]
select: [[{type: 'field', params: ['value']}, {type: 'mean'}, {type: 'math'}]]
});
query.addSelectPart(query.selectModels[0], 'math');
expect(query.target.select[0].length).to.be(3);
expect(query.target.select[0][2].name).to.be('math');
expect(query.target.select[0][2].type).to.be('math');
});
});
......
......@@ -3,12 +3,12 @@ import {describe, beforeEach, it, sinon, expect} from 'test/lib/common';
import queryPart = require('../query_part');
describe('InfluxQueryBuilder', () => {
describe('InfluxQueryPart', () => {
describe('series with mesurement only', () => {
it('should handle nested function parts', () => {
var part = queryPart.create({
name: 'derivative',
type: 'derivative',
params: ['10s'],
});
......@@ -18,7 +18,7 @@ describe('InfluxQueryBuilder', () => {
it('should handle suffirx parts', () => {
var part = queryPart.create({
name: 'math',
type: 'math',
params: ['/ 100'],
});
......@@ -28,7 +28,7 @@ describe('InfluxQueryBuilder', () => {
it('should handle alias parts', () => {
var part = queryPart.create({
name: 'alias',
type: 'alias',
params: ['test'],
});
......
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