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

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

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

+ 34 - 14
public/app/plugins/datasource/influxdb/influx_query.ts

@@ -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.groupByParts = [
-      queryPart.create({type: 'time', params: ['$interval']})
-    ];
+    this.updateProjection();
   }
   }
 
 
-  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 {
     });
     });
   }
   }
 
 
+  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 {
     query += conditions.join(' ');
     query += conditions.join(' ');
     query += (conditions.length > 0 ? ' AND ' : '') + '$timeFilter';
     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) {
     if (target.fill) {

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

@@ -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>
-					<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>
-				<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>

+ 32 - 13
public/app/plugins/datasource/influxdb/query_ctrl.js

@@ -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) {
         memo.push(menu);
         memo.push(menu);
         return memo;
         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) {
     $scope.addSelectPart = function(selectParts, cat, subitem) {
@@ -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;

+ 8 - 0
public/app/plugins/datasource/influxdb/query_part.ts

@@ -184,6 +184,14 @@ QueryPartDef.register({
   renderer: functionRenderer,
   renderer: functionRenderer,
 });
 });
 
 
+QueryPartDef.register({
+  type: 'tag',
+  category: groupByTimeFunctions,
+  params: [{name: 'tag', type: 'string'}],
+  defaultParams: ['tag'],
+  renderer: quotedIdentityRenderer,
+});
+
 QueryPartDef.register({
 QueryPartDef.register({
   type: 'math',
   type: 'math',
   addStrategy: addMathStrategy,
   addStrategy: addMathStrategy,

+ 14 - 14
public/app/plugins/datasource/influxdb/specs/influx_query_specs.ts

@@ -21,10 +21,10 @@ describe.only('InfluxQuery', function() {
         measurement: 'cpu',
         measurement: 'cpu',
         select: [
         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() {
     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');
     });
     });
 
 
   });
   });

+ 4 - 4
public/app/plugins/datasource/influxdb/specs/query_part_specs.ts

@@ -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', () => {
 
 
     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', () => {
 
 
     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'],
       });
       });