From c9ba856c527c316d8a5ecdd1d177dfe861df1ba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 25 Nov 2015 10:22:20 +0100 Subject: [PATCH] feat(influxdb): more work on influxdb editor --- .../datasource/influxdb/influx_query.ts | 36 +++++---- .../influxdb/partials/query.editor.html | 8 +- .../influxdb/partials/query_part.html | 3 +- .../plugins/datasource/influxdb/query_ctrl.js | 8 +- .../plugins/datasource/influxdb/query_part.ts | 74 ++++++++++++++++++- .../datasource/influxdb/query_part_editor.js | 5 ++ .../influxdb/specs/influx_query_specs.ts | 59 +++++++++++++++ 7 files changed, 163 insertions(+), 30 deletions(-) diff --git a/public/app/plugins/datasource/influxdb/influx_query.ts b/public/app/plugins/datasource/influxdb/influx_query.ts index ec75bc8d75b..0ba2df1833f 100644 --- a/public/app/plugins/datasource/influxdb/influx_query.ts +++ b/public/app/plugins/datasource/influxdb/influx_query.ts @@ -6,16 +6,6 @@ import queryPart = require('./query_part'); declare var InfluxQueryBuilder: any; -class InfluxSelectModel { - modelParts: any[]; - persistedParts: any[]; - - constructor(persistedParts: any[]) { - this.persistedParts = persistedParts; - this.modelParts = _.map(persistedParts, queryPart.create); - } -} - class InfluxQuery { target: any; selectModels: any[]; @@ -40,7 +30,15 @@ class InfluxQuery { updateSelectParts() { this.selectModels = _.map(this.target.select, function(parts: any) { - return new InfluxSelectModel(parts); + return _.map(parts, queryPart.create); + }); + } + + updatePersistedParts() { + this.target.select = _.map(this.selectModels, function(selectParts) { + return _.map(selectParts, function(part: any) { + return {name: part.def.name, params: part.params}; + }); }); } @@ -49,16 +47,16 @@ class InfluxQuery { this.updateSelectParts(); } - removeSelectPart(selectModel, part) { - var partIndex = _.indexOf(selectModel.modelParts, part); - selectModel.persistedParts.splice(partIndex, 1); - this.updateSelectParts(); + removeSelectPart(selectParts, part) { + var partIndex = _.indexOf(selectParts, part); + selectParts.splice(partIndex, 1); + this.updatePersistedParts(); } - addSelectPart(selectModel, name) { + addSelectPart(selectParts, name) { var partModel = queryPart.create({name: name}); - selectModel.persistedParts.push(partModel.part); - selectModel.modelParts.push(partModel); + partModel.def.addStrategy(selectParts, partModel); + this.updatePersistedParts(); } addSelect() { @@ -113,7 +111,7 @@ class InfluxQuery { var query = 'SELECT '; var i, y; for (i = 0; i < this.selectModels.length; i++) { - let parts = this.selectModels[i].modelParts; + let parts = this.selectModels[i]; var selectText = ""; for (y = 0; y < parts.length; y++) { let part = parts[y]; diff --git a/public/app/plugins/datasource/influxdb/partials/query.editor.html b/public/app/plugins/datasource/influxdb/partials/query.editor.html index 0af29a39981..86ab92dbcaa 100644 --- a/public/app/plugins/datasource/influxdb/partials/query.editor.html +++ b/public/app/plugins/datasource/influxdb/partials/query.editor.html @@ -65,15 +65,15 @@
-
+
  • SELECT
  • -
  • - +
  • +
  • -
diff --git a/public/app/plugins/datasource/influxdb/partials/query_part.html b/public/app/plugins/datasource/influxdb/partials/query_part.html index ea66c010efa..27bd44dec92 100644 --- a/public/app/plugins/datasource/influxdb/partials/query_part.html +++ b/public/app/plugins/datasource/influxdb/partials/query_part.html @@ -1,6 +1,5 @@
- - +
{{part.def.name}}() diff --git a/public/app/plugins/datasource/influxdb/query_ctrl.js b/public/app/plugins/datasource/influxdb/query_ctrl.js index 9bfb5b036e4..bbc12bfc432 100644 --- a/public/app/plugins/datasource/influxdb/query_ctrl.js +++ b/public/app/plugins/datasource/influxdb/query_ctrl.js @@ -62,13 +62,13 @@ function (angular, _, InfluxQueryBuilder, InfluxQuery, queryPart) { }, []); }; - $scope.selectMenuAction = function(selectModel, cat, subitem) { - $scope.queryModel.addSelectPart(selectModel, subitem.value); + $scope.addSelectPart = function(selectParts, cat, subitem) { + $scope.queryModel.addSelectPart(selectParts, subitem.value); $scope.get_data(); }; - $scope.removeSelectPart = function(selectModel, part) { - $scope.queryModel.removeSelectPart(selectModel, part); + $scope.removeSelectPart = function(selectParts, part) { + $scope.queryModel.removeSelectPart(selectParts, part); $scope.get_data(); }; diff --git a/public/app/plugins/datasource/influxdb/query_part.ts b/public/app/plugins/datasource/influxdb/query_part.ts index 1e750a361bc..9df0fddee3e 100644 --- a/public/app/plugins/datasource/influxdb/query_part.ts +++ b/public/app/plugins/datasource/influxdb/query_part.ts @@ -11,17 +11,23 @@ var categories = { Fields: [], }; +var groupByTimeFunctions = []; + class QueryPartDef { name: string; params: any[]; defaultParams: any[]; renderer: any; + category: any; + addStrategy: any; constructor(options: any) { this.name = options.name; this.params = options.params; this.defaultParams = options.defaultParams; this.renderer = options.renderer; + this.category = options.category; + this.addStrategy = options.addStrategy; } static register(options: any) { @@ -65,6 +71,67 @@ function quotedIdentityRenderer(part, innerExpr) { return '"' + part.params[0] + '"'; } +function replaceAggregationAddStrategy(selectParts, partModel) { + // look for existing aggregation + for (var i = 0; i < selectParts.length; i++) { + var part = selectParts[i]; + if (part.def.category === categories.Aggregations) { + selectParts[i] = partModel; + return; + } + } + + selectParts.splice(1, 0, partModel); +} + +function addTransformationStrategy(selectParts, partModel) { + var i; + // look for index to add transformation + for (i = 0; i < selectParts.length; i++) { + var part = selectParts[i]; + if (part.def.category === categories.Math || part.def.category === categories.Aliasing) { + break; + } + } + + selectParts.splice(i, 0, partModel); +} + +function addMathStrategy(selectParts, partModel) { + var partCount = selectParts.length; + if (partCount > 0) { + // if last is math, replace it + if (selectParts[partCount-1].def.name === 'math') { + selectParts[partCount-1] = partModel; + return; + } + // if next to last is math, replace it + if (selectParts[partCount-2].def.name === 'math') { + selectParts[partCount-2] = partModel; + return; + } + // if last is alias add it before + else if (selectParts[partCount-1].def.name === 'alias') { + selectParts.splice(partCount-1, 0, partModel); + return; + } + } + selectParts.push(partModel); +} + +function addAliasStrategy(selectParts, partModel) { + var partCount = selectParts.length; + if (partCount > 0) { + // if last is alias, replace it + if (selectParts[partCount-1].def.name === 'alias') { + selectParts[partCount-1] = partModel; + return; + } + } + selectParts.push(partModel); +} + + QueryPartDef.register({ name: 'field', category: categories.Fields, @@ -75,6 +142,7 @@ QueryPartDef.register({ QueryPartDef.register({ name: 'mean', + addStrategy: replaceAggregationAddStrategy, category: categories.Aggregations, params: [], defaultParams: [], @@ -83,6 +151,7 @@ QueryPartDef.register({ QueryPartDef.register({ name: 'sum', + addStrategy: replaceAggregationAddStrategy, category: categories.Aggregations, params: [], defaultParams: [], @@ -91,6 +160,7 @@ QueryPartDef.register({ QueryPartDef.register({ name: 'derivative', + addStrategy: addTransformationStrategy, category: categories.Transformations, params: [{ name: "duration", type: "interval", options: ['1s', '10s', '1m', '5min', '10m', '15m', '1h']}], defaultParams: ['10s'], @@ -99,7 +169,7 @@ QueryPartDef.register({ QueryPartDef.register({ name: 'time', - category: categories.Transformations, + category: groupByTimeFunctions, params: [{ name: "rate", type: "interval", options: ['$interval', '1s', '10s', '1m', '5min', '10m', '15m', '1h'] }], defaultParams: ['$interval'], renderer: functionRenderer, @@ -107,6 +177,7 @@ QueryPartDef.register({ QueryPartDef.register({ name: 'math', + addStrategy: addMathStrategy, category: categories.Math, params: [{ name: "expr", type: "string"}], defaultParams: [' / 100'], @@ -115,6 +186,7 @@ QueryPartDef.register({ QueryPartDef.register({ name: 'alias', + addStrategy: addAliasStrategy, category: categories.Aliasing, params: [{ name: "name", type: "string", quote: 'double'}], defaultParams: ['alias'], diff --git a/public/app/plugins/datasource/influxdb/query_part_editor.js b/public/app/plugins/datasource/influxdb/query_part_editor.js index c7e16d86ec6..9fbe02acf21 100644 --- a/public/app/plugins/datasource/influxdb/query_part_editor.js +++ b/public/app/plugins/datasource/influxdb/query_part_editor.js @@ -117,6 +117,11 @@ function (angular, _, $) { $controlsContainer.show(); }; + $scope.removeActionInternal = function() { + $scope.toggleControls(); + $scope.removeAction(); + }; + function addElementsAndCompile() { _.each(partDef.params, function(param, index) { if (param.optional && part.params.length <= index) { diff --git a/public/app/plugins/datasource/influxdb/specs/influx_query_specs.ts b/public/app/plugins/datasource/influxdb/specs/influx_query_specs.ts index a6f70249a68..038ad5140c1 100644 --- a/public/app/plugins/datasource/influxdb/specs/influx_query_specs.ts +++ b/public/app/plugins/datasource/influxdb/specs/influx_query_specs.ts @@ -34,4 +34,63 @@ describe.only('InfluxQuery', function() { }); }); + describe('when adding select part', function() { + + it('should add mean after after field', function() { + var query = new InfluxQuery({ + measurement: 'cpu', + select: [[{name: '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'); + }); + + it('should replace sum by mean', function() { + var query = new InfluxQuery({ + measurement: 'cpu', + select: [[{name: 'field', params: ['value']}, {name: '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'); + }); + + it('should add math before alias', function() { + var query = new InfluxQuery({ + measurement: 'cpu', + select: [[{name: 'field', params: ['value']}, {name: 'mean'}, {name: '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'); + }); + + it('should add math last', function() { + var query = new InfluxQuery({ + measurement: 'cpu', + select: [[{name: 'field', params: ['value']}, {name: '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'); + }); + + it('should replace math', function() { + var query = new InfluxQuery({ + measurement: 'cpu', + select: [[{name: 'field', params: ['value']}, {name: 'mean'}, {name: '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'); + }); + + }); + });