Просмотр исходного кода

feat(influxdb): more work on influxdb editor

Torkel Ödegaard 10 лет назад
Родитель
Сommit
c9ba856c52

+ 17 - 19
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];

+ 4 - 4
public/app/plugins/datasource/influxdb/partials/query.editor.html

@@ -65,15 +65,15 @@
 
 	<div ng-hide="target.rawQuery">
 
-		<div class="tight-form" ng-repeat="selectModel in queryModel.selectModels">
+		<div class="tight-form" ng-repeat="selectParts in queryModel.selectModels">
 			<ul class="tight-form-list">
 				<li class="tight-form-item query-keyword tight-form-align" style="width: 75px;">
 					<span ng-show="$index === 0">SELECT</span>
 				</li>
-				<li ng-repeat="part in selectModel.modelParts">
-					<influx-query-part-editor part="part" class="tight-form-item tight-form-func" remove-action="removeSelectPart(selectModel, part)" part-updated="selectPartUpdated(selectModel, part)"></influx-query-part-editor>
+				<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 class="dropdown" dropdown-typeahead="selectMenu" dropdown-typeahead-on-select="selectMenuAction(selectModel, $item, $subItem)">
+				<li class="dropdown" dropdown-typeahead="selectMenu" dropdown-typeahead-on-select="addSelectPart(selectParts, $item, $subItem)">
 				</li>
 			</ul>
 			<div class="clearfix"></div>

+ 1 - 2
public/app/plugins/datasource/influxdb/partials/query_part.html

@@ -1,6 +1,5 @@
 <div class="tight-form-func-controls">
-	<span class="pointer fa fa-question-circle"></span>
-	<span class="pointer fa fa-remove" ng-click="removeAction()" ></span>
+	<span class="pointer fa fa-remove" ng-click="removeActionInternal()" ></span>
 </div>
 
 <a ng-click="toggleControls()">{{part.def.name}}</a><span>(</span><span class="query-part-parameters"></span><span>)</span>

+ 4 - 4
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();
     };
 

+ 73 - 1
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'],

+ 5 - 0
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) {

+ 59 - 0
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');
+    });
+
+  });
+
 });