Commit 5ba19144 by Torkel Ödegaard

feat(influxdb): more work on query editor

parent c9ba856c
...@@ -18,13 +18,13 @@ class InfluxQuery { ...@@ -18,13 +18,13 @@ class InfluxQuery {
target.tags = target.tags || []; target.tags = target.tags || [];
target.groupBy = target.groupBy || [{type: 'time', interval: 'auto'}]; target.groupBy = target.groupBy || [{type: 'time', interval: 'auto'}];
target.select = target.select || [[ target.select = target.select || [[
{name: 'field', params: ['value']}, {type: 'field', params: ['value']},
{name: 'mean', params: []}, {type: 'mean', params: []},
]]; ]];
this.updateSelectParts(); this.updateSelectParts();
this.groupByParts = [ this.groupByParts = [
queryPart.create({name: 'time', params: ['$interval']}) queryPart.create({type: 'time', params: ['$interval']})
]; ];
} }
...@@ -37,7 +37,7 @@ class InfluxQuery { ...@@ -37,7 +37,7 @@ class InfluxQuery {
updatePersistedParts() { updatePersistedParts() {
this.target.select = _.map(this.selectModels, function(selectParts) { this.target.select = _.map(this.selectModels, function(selectParts) {
return _.map(selectParts, function(part: any) { return _.map(selectParts, function(part: any) {
return {name: part.def.name, params: part.params}; return {type: part.def.type, params: part.params};
}); });
}); });
} }
...@@ -48,22 +48,24 @@ class InfluxQuery { ...@@ -48,22 +48,24 @@ class InfluxQuery {
} }
removeSelectPart(selectParts, part) { removeSelectPart(selectParts, part) {
var partIndex = _.indexOf(selectParts, part); // if we remove the field remove the whole statement
selectParts.splice(partIndex, 1); if (part.def.type === 'field') {
this.updatePersistedParts(); if (this.selectModels.length > 1) {
} var modelsIndex = _.indexOf(this.selectModels, selectParts);
this.selectModels.splice(modelsIndex, 1);
}
} else {
var partIndex = _.indexOf(selectParts, part);
selectParts.splice(partIndex, 1);
}
addSelectPart(selectParts, name) {
var partModel = queryPart.create({name: name});
partModel.def.addStrategy(selectParts, partModel);
this.updatePersistedParts(); this.updatePersistedParts();
} }
addSelect() { addSelectPart(selectParts, type) {
this.target.select.push([ var partModel = queryPart.create({type: type});
{name: 'mean', params: ['value']}, partModel.def.addStrategy(selectParts, partModel, this);
]); this.updatePersistedParts();
this.updateSelectParts();
} }
private renderTagCondition(tag, index) { private renderTagCondition(tag, index) {
...@@ -100,12 +102,12 @@ class InfluxQuery { ...@@ -100,12 +102,12 @@ class InfluxQuery {
render() { render() {
var target = this.target; var target = this.target;
if (!target.measurement) { if (target.rawQuery) {
throw "Metric measurement is missing"; return target.query;
} }
if (!target.fields) { if (!target.measurement) {
target.fields = [{name: 'value', func: target.function || 'mean'}]; throw "Metric measurement is missing";
} }
var query = 'SELECT '; var query = 'SELECT ';
......
...@@ -73,6 +73,9 @@ ...@@ -73,6 +73,9 @@
<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>
......
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
<span class="pointer fa fa-remove" ng-click="removeActionInternal()" ></span> <span class="pointer fa fa-remove" ng-click="removeActionInternal()" ></span>
</div> </div>
<a ng-click="toggleControls()">{{part.def.name}}</a><span>(</span><span class="query-part-parameters"></span><span>)</span> <a ng-click="toggleControls()">{{part.def.type}}</a><span>(</span><span class="query-part-parameters"></span><span>)</span>
...@@ -55,11 +55,21 @@ function (angular, _, InfluxQueryBuilder, InfluxQuery, queryPart) { ...@@ -55,11 +55,21 @@ function (angular, _, InfluxQueryBuilder, InfluxQuery, queryPart) {
$scope.selectMenu = _.reduce(categories, function(memo, cat, key) { $scope.selectMenu = _.reduce(categories, function(memo, cat, key) {
var menu = {text: key}; var menu = {text: key};
menu.submenu = _.map(cat, function(item) { menu.submenu = _.map(cat, function(item) {
return {text: item.name, value: item.name}; return {text: item.type, value: item.type};
}); });
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};
});
memo.push(menu);
return memo;
}, []);
}; };
$scope.addSelectPart = function(selectParts, cat, subitem) { $scope.addSelectPart = function(selectParts, cat, subitem) {
......
...@@ -14,7 +14,7 @@ var categories = { ...@@ -14,7 +14,7 @@ var categories = {
var groupByTimeFunctions = []; var groupByTimeFunctions = [];
class QueryPartDef { class QueryPartDef {
name: string; type: string;
params: any[]; params: any[];
defaultParams: any[]; defaultParams: any[];
renderer: any; renderer: any;
...@@ -22,7 +22,7 @@ class QueryPartDef { ...@@ -22,7 +22,7 @@ class QueryPartDef {
addStrategy: any; addStrategy: any;
constructor(options: any) { constructor(options: any) {
this.name = options.name; this.type = options.type;
this.params = options.params; this.params = options.params;
this.defaultParams = options.defaultParams; this.defaultParams = options.defaultParams;
this.renderer = options.renderer; this.renderer = options.renderer;
...@@ -31,13 +31,13 @@ class QueryPartDef { ...@@ -31,13 +31,13 @@ class QueryPartDef {
} }
static register(options: any) { static register(options: any) {
index[options.name] = new QueryPartDef(options); index[options.type] = new QueryPartDef(options);
options.category.push(index[options.name]); options.category.push(index[options.type]);
} }
} }
function functionRenderer(part, innerExpr) { function functionRenderer(part, innerExpr) {
var str = part.def.name + '('; var str = part.def.type + '(';
var parameters = _.map(part.params, (value, index) => { var parameters = _.map(part.params, (value, index) => {
var paramType = part.def.params[index]; var paramType = part.def.params[index];
if (paramType.quote === 'single') { if (paramType.quote === 'single') {
...@@ -101,17 +101,17 @@ function addMathStrategy(selectParts, partModel) { ...@@ -101,17 +101,17 @@ function addMathStrategy(selectParts, partModel) {
var partCount = selectParts.length; var partCount = selectParts.length;
if (partCount > 0) { if (partCount > 0) {
// if last is math, replace it // if last is math, replace it
if (selectParts[partCount-1].def.name === 'math') { if (selectParts[partCount-1].def.type === 'math') {
selectParts[partCount-1] = partModel; selectParts[partCount-1] = partModel;
return; return;
} }
// if next to last is math, replace it // if next to last is math, replace it
if (selectParts[partCount-2].def.name === 'math') { if (selectParts[partCount-2].def.type === 'math') {
selectParts[partCount-2] = partModel; selectParts[partCount-2] = partModel;
return; return;
} }
// if last is alias add it before // if last is alias add it before
else if (selectParts[partCount-1].def.name === 'alias') { else if (selectParts[partCount-1].def.type === 'alias') {
selectParts.splice(partCount-1, 0, partModel); selectParts.splice(partCount-1, 0, partModel);
return; return;
} }
...@@ -123,7 +123,7 @@ function addAliasStrategy(selectParts, partModel) { ...@@ -123,7 +123,7 @@ function addAliasStrategy(selectParts, partModel) {
var partCount = selectParts.length; var partCount = selectParts.length;
if (partCount > 0) { if (partCount > 0) {
// if last is alias, replace it // if last is alias, replace it
if (selectParts[partCount-1].def.name === 'alias') { if (selectParts[partCount-1].def.type === 'alias') {
selectParts[partCount-1] = partModel; selectParts[partCount-1] = partModel;
return; return;
} }
...@@ -131,9 +131,18 @@ function addAliasStrategy(selectParts, partModel) { ...@@ -131,9 +131,18 @@ function addAliasStrategy(selectParts, partModel) {
selectParts.push(partModel); selectParts.push(partModel);
} }
function addFieldStrategy(selectParts, partModel, query) {
// copy all parts
var parts = _.map(selectParts, function(part: any) {
return new QueryPart({type: part.def.type, params: _.clone(part.params)});
});
query.selectModels.push(parts);
}
QueryPartDef.register({ QueryPartDef.register({
name: 'field', type: 'field',
addStrategy: addFieldStrategy,
category: categories.Fields, category: categories.Fields,
params: [{type: 'field'}], params: [{type: 'field'}],
defaultParams: ['value'], defaultParams: ['value'],
...@@ -141,7 +150,7 @@ QueryPartDef.register({ ...@@ -141,7 +150,7 @@ QueryPartDef.register({
}); });
QueryPartDef.register({ QueryPartDef.register({
name: 'mean', type: 'mean',
addStrategy: replaceAggregationAddStrategy, addStrategy: replaceAggregationAddStrategy,
category: categories.Aggregations, category: categories.Aggregations,
params: [], params: [],
...@@ -150,7 +159,7 @@ QueryPartDef.register({ ...@@ -150,7 +159,7 @@ QueryPartDef.register({
}); });
QueryPartDef.register({ QueryPartDef.register({
name: 'sum', type: 'sum',
addStrategy: replaceAggregationAddStrategy, addStrategy: replaceAggregationAddStrategy,
category: categories.Aggregations, category: categories.Aggregations,
params: [], params: [],
...@@ -159,7 +168,7 @@ QueryPartDef.register({ ...@@ -159,7 +168,7 @@ QueryPartDef.register({
}); });
QueryPartDef.register({ QueryPartDef.register({
name: 'derivative', type: 'derivative',
addStrategy: addTransformationStrategy, addStrategy: addTransformationStrategy,
category: categories.Transformations, category: categories.Transformations,
params: [{ name: "duration", type: "interval", options: ['1s', '10s', '1m', '5min', '10m', '15m', '1h']}], params: [{ name: "duration", type: "interval", options: ['1s', '10s', '1m', '5min', '10m', '15m', '1h']}],
...@@ -168,7 +177,7 @@ QueryPartDef.register({ ...@@ -168,7 +177,7 @@ QueryPartDef.register({
}); });
QueryPartDef.register({ QueryPartDef.register({
name: 'time', type: 'time',
category: groupByTimeFunctions, category: groupByTimeFunctions,
params: [{ name: "rate", type: "interval", options: ['$interval', '1s', '10s', '1m', '5min', '10m', '15m', '1h'] }], params: [{ name: "rate", type: "interval", options: ['$interval', '1s', '10s', '1m', '5min', '10m', '15m', '1h'] }],
defaultParams: ['$interval'], defaultParams: ['$interval'],
...@@ -176,7 +185,7 @@ QueryPartDef.register({ ...@@ -176,7 +185,7 @@ QueryPartDef.register({
}); });
QueryPartDef.register({ QueryPartDef.register({
name: 'math', type: 'math',
addStrategy: addMathStrategy, addStrategy: addMathStrategy,
category: categories.Math, category: categories.Math,
params: [{ name: "expr", type: "string"}], params: [{ name: "expr", type: "string"}],
...@@ -185,7 +194,7 @@ QueryPartDef.register({ ...@@ -185,7 +194,7 @@ QueryPartDef.register({
}); });
QueryPartDef.register({ QueryPartDef.register({
name: 'alias', type: 'alias',
addStrategy: addAliasStrategy, addStrategy: addAliasStrategy,
category: categories.Aliasing, category: categories.Aliasing,
params: [{ name: "name", type: "string", quote: 'double'}], params: [{ name: "name", type: "string", quote: 'double'}],
...@@ -202,9 +211,9 @@ class QueryPart { ...@@ -202,9 +211,9 @@ class QueryPart {
constructor(part: any) { constructor(part: any) {
this.part = part; this.part = part;
this.def = index[part.name]; this.def = index[part.type];
if (!this.def) { if (!this.def) {
throw {message: 'Could not find query part ' + part.name}; throw {message: 'Could not find query part ' + part.type};
} }
part.params = part.params || _.clone(this.def.defaultParams); part.params = part.params || _.clone(this.def.defaultParams);
...@@ -247,11 +256,11 @@ class QueryPart { ...@@ -247,11 +256,11 @@ class QueryPart {
updateText() { updateText() {
if (this.params.length === 0) { if (this.params.length === 0) {
this.text = this.def.name + '()'; this.text = this.def.type + '()';
return; return;
} }
var text = this.def.name + '('; var text = this.def.type + '(';
text += this.params.join(', '); text += this.params.join(', ');
text += ')'; text += ')';
this.text = text; this.text = text;
...@@ -263,10 +272,6 @@ export = { ...@@ -263,10 +272,6 @@ export = {
return new QueryPart(part); return new QueryPart(part);
}, },
getFuncDef: function(name) {
return index[name];
},
getCategories: function() { getCategories: function() {
return categories; return categories;
} }
......
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