make sure graphite queries containing references are properly updated

This commit is contained in:
Dan Cech 2017-04-14 17:41:22 -04:00
parent aa47b9bf5c
commit 715453204e
2 changed files with 43 additions and 17 deletions

View File

@ -1,7 +1,7 @@
<query-editor-row query-ctrl="ctrl" has-text-edit-mode="true"> <query-editor-row query-ctrl="ctrl" has-text-edit-mode="true">
<div class="gf-form" ng-show="ctrl.target.textEditor"> <div class="gf-form" ng-show="ctrl.target.textEditor">
<input type="text" class="gf-form-input" ng-model="ctrl.target.target" spellcheck="false" ng-blur="ctrl.refresh()"></input> <input type="text" class="gf-form-input" ng-model="ctrl.target.target" spellcheck="false" ng-blur="ctrl.targetTextChanged()"></input>
</div> </div>
<div ng-hide="ctrl.target.textEditor"> <div ng-hide="ctrl.target.textEditor">

View File

@ -55,7 +55,7 @@ export class GraphiteQueryCtrl extends QueryCtrl {
} }
try { try {
this.parseTargeRecursive(astNode, null, 0); this.parseTargetRecursive(astNode, null, 0);
} catch (err) { } catch (err) {
console.log('error parsing target:', err.message); console.log('error parsing target:', err.message);
this.error = err.message; this.error = err.message;
@ -72,7 +72,7 @@ export class GraphiteQueryCtrl extends QueryCtrl {
func.params[index] = value; func.params[index] = value;
} }
parseTargeRecursive(astNode, func, index) { parseTargetRecursive(astNode, func, index) {
if (astNode === null) { if (astNode === null) {
return null; return null;
} }
@ -81,7 +81,7 @@ export class GraphiteQueryCtrl extends QueryCtrl {
case 'function': case 'function':
var innerFunc = gfunc.createFuncInstance(astNode.name, { withDefaultParams: false }); var innerFunc = gfunc.createFuncInstance(astNode.name, { withDefaultParams: false });
_.each(astNode.params, (param, index) => { _.each(astNode.params, (param, index) => {
this.parseTargeRecursive(param, innerFunc, index); this.parseTargetRecursive(param, innerFunc, index);
}); });
innerFunc.updateText(); innerFunc.updateText();
@ -209,30 +209,56 @@ export class GraphiteQueryCtrl extends QueryCtrl {
} }
targetTextChanged() { targetTextChanged() {
this.parseTarget(); this.updateModelTarget();
this.panelCtrl.refresh(); this.refresh();
} }
updateModelTarget() { updateModelTarget() {
// render query // render query
var metricPath = this.getSegmentPathUpTo(this.segments.length); if (!this.target.textEditor) {
this.target.target = _.reduce(this.functions, this.wrapFunction, metricPath); var metricPath = this.getSegmentPathUpTo(this.segments.length);
this.target.target = _.reduce(this.functions, this.wrapFunction, metricPath);
}
// loop through queries and update targetFull as needed
for (const target of this.panelCtrl.panel.targets) {
this.resolveTarget(target);
}
}
resolveTarget(target) {
// render nested query // render nested query
var targetsByRefId = _.keyBy(this.panelCtrl.panel.targets, 'refId'); var targetsByRefId = _.keyBy(this.panelCtrl.panel.targets, 'refId');
// no references to self
delete targetsByRefId[target.refId];
var nestedSeriesRefRegex = /\#([A-Z])/g; var nestedSeriesRefRegex = /\#([A-Z])/g;
var targetWithNestedQueries = this.target.target.replace(nestedSeriesRefRegex, (match, g1) => { var targetWithNestedQueries = target.target;
var target = targetsByRefId[g1];
if (!target) { while (targetWithNestedQueries.match(nestedSeriesRefRegex)) {
return match; var updated = targetWithNestedQueries.replace(nestedSeriesRefRegex, (match, g1) => {
var t = targetsByRefId[g1];
if (!t) {
return match;
}
// no circular references
delete targetsByRefId[g1];
return t.target;
});
if (updated === targetWithNestedQueries) {
break;
} }
return target.targetFull || target.target; targetWithNestedQueries = updated;
}); }
delete this.target.targetFull; delete target.targetFull;
if (this.target.target !== targetWithNestedQueries) { if (target.target !== targetWithNestedQueries) {
this.target.targetFull = targetWithNestedQueries; target.targetFull = targetWithNestedQueries;
} }
} }