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