aboutsummaryrefslogtreecommitdiff
path: root/app/components
diff options
context:
space:
mode:
authorAlex Tatiyants <atatiyan@gmail.com>2016-01-04 19:42:44 -0800
committerAlex Tatiyants <atatiyan@gmail.com>2016-01-04 19:42:44 -0800
commitd89ddcf3532937d395898f255c42f3d26303f1c4 (patch)
tree9efdf18c3fa965f1a1d140e5b2b06a9cfa0a4e19 /app/components
parent7955dbcc9272f258c9b36e67853471e59d851cac (diff)
add integrated query view with syntax highlighting
Diffstat (limited to 'app/components')
-rw-r--r--app/components/plan-node/plan-node.html20
-rw-r--r--app/components/plan-node/plan-node.ts26
-rw-r--r--app/components/plan-view/plan-view.html18
-rw-r--r--app/components/plan-view/plan-view.ts28
4 files changed, 57 insertions, 35 deletions
diff --git a/app/components/plan-node/plan-node.html b/app/components/plan-node/plan-node.html
index 49380a2..ddf6722 100644
--- a/app/components/plan-node/plan-node.html
+++ b/app/components/plan-node/plan-node.html
@@ -1,12 +1,18 @@
<div class="plan-node">
<header (click)="showDetails = !showDetails">
- <h4>{{node['Node Type'] | uppercase}}</h4>
+ <h4>{{node['Node Type'] | uppercase}}
+ </h4>
<span class="node-duration">{{duration}}<span class="text-muted">{{durationUnit}} | </span>
<strong>{{executionTimePercent}}</strong><span class="text-muted">%</span>
</span>
</header>
- <div class="relation-name" *ngIf="node['Relation Name']"><span class="text-muted">on </span>
+ <div class="relation-name" *ngIf="node['Relation Name']">
+ <button *ngIf="plan.formattedQuery" class="btn btn-sm btn-default btn-slim pull-right" (click)="showQuery = !showQuery">
+ <i class="fa fa-database"></i>
+ </button>
+
+ <span class="text-muted">on </span>
<span *ngIf="node['Schema']">{{node['Schema']}}.</span>{{node['Relation Name']}}
<span *ngIf="node['Alias']"> ({{node['Alias']}})</span>
</div>
@@ -41,10 +47,18 @@
<td>{{prop.value}}</td>
<tr>
</table>
+
+ <div *ngIf="showQuery" class="plan-query-container">
+ <button class="btn btn-close pull-right" (click)="showQuery = false">
+ <i class="fa fa-close"></i>
+ </button>
+ <h3>query</h3>
+ <pre class="plan-query-text"><code [innerHTML]="getFormattedQuery()"></code></pre>
+ </div>
</div>
<ul *ngIf="node.Plans">
<li *ngFor="#subNode of node.Plans">
- <plan-node [node]="subNode" [viewOptions]="viewOptions" [planStats]="planStats"></plan-node>
+ <plan-node [plan]="plan" [node]="subNode" [viewOptions]="viewOptions" [planStats]="planStats"></plan-node>
</li>
</ul>
diff --git a/app/components/plan-node/plan-node.ts b/app/components/plan-node/plan-node.ts
index 3562ea6..8aaab2c 100644
--- a/app/components/plan-node/plan-node.ts
+++ b/app/components/plan-node/plan-node.ts
@@ -1,14 +1,16 @@
+import {IPlan} from '../../interfaces/iplan';
import {Component, OnInit} from 'angular2/core';
import {HighlightType, EstimateDirection} from '../../enums';
import {PlanService} from '../../services/plan-service';
+import {SyntaxHighlightService} from '../../services/syntax-highlight-service';
/// <reference path="lodash.d.ts" />
@Component({
selector: 'plan-node',
- inputs: ['node', 'planStats', 'viewOptions'],
+ inputs: ['plan', 'node', 'viewOptions'],
templateUrl: './components/plan-node/plan-node.html',
directives: [PlanNode],
- providers: [PlanService]
+ providers: [PlanService, SyntaxHighlightService]
})
export class PlanNode {
@@ -21,8 +23,8 @@ export class PlanNode {
ESTIMATE_TAG: string = 'bad estimate';
// inputs
+ plan: IPlan;
node: any;
- planStats: any;
viewOptions: any;
// calculated properties
@@ -42,7 +44,7 @@ export class PlanNode {
estimateDirections = EstimateDirection;
highlightTypes = HighlightType;
- constructor(private _planService: PlanService) { }
+ constructor(private _planService: PlanService, private _syntaxHighlightService: SyntaxHighlightService) { }
ngOnInit() {
this.currentHighlightType = this.viewOptions.highlightType;
@@ -63,19 +65,27 @@ export class PlanNode {
}
}
+ getFormattedQuery() {
+ var keyItems: Array<string> = [];
+ keyItems.push(this.node['Schema'] + '.' + this.node['Relation Name']);
+ keyItems.push(' ' + this.node['Relation Name'] + ' ');
+ keyItems.push(' ' + this.node['Alias'] + ' ');
+ return this._syntaxHighlightService.highlightKeyItems(this.plan.formattedQuery, keyItems);
+ }
+
calculateBar() {
switch (this.currentHighlightType) {
case HighlightType.DURATION:
this.highlightValue = (this.node[this._planService.ACTUAL_DURATION_PROP]);
- this.width = Math.round((this.highlightValue / this.planStats.maxDuration) * this.MAX_WIDTH);
+ this.width = Math.round((this.highlightValue / this.plan.planStats.maxDuration) * this.MAX_WIDTH);
break;
case HighlightType.ROWS:
this.highlightValue = (this.node[this._planService.ACTUAL_ROWS_PROP]);
- this.width = Math.round((this.highlightValue / this.planStats.maxRows) * this.MAX_WIDTH);
+ this.width = Math.round((this.highlightValue / this.plan.planStats.maxRows) * this.MAX_WIDTH);
break;
case HighlightType.COST:
this.highlightValue = (this.node[this._planService.ACTUAL_COST_PROP]);
- this.width = Math.round((this.highlightValue / this.planStats.maxCost) * this.MAX_WIDTH);
+ this.width = Math.round((this.highlightValue / this.plan.planStats.maxCost) * this.MAX_WIDTH);
break;
}
@@ -96,7 +106,7 @@ export class PlanNode {
this.duration = _.round(dur / 1000, 2).toString();
this.durationUnit = 'mins';
}
- this.executionTimePercent = (_.round((dur / this.planStats.executionTime) * 100));
+ this.executionTimePercent = (_.round((dur / this.plan.planStats.executionTime) * 100));
}
// create an array of node propeties so that they can be displayed in the view
diff --git a/app/components/plan-view/plan-view.html b/app/components/plan-view/plan-view.html
index 8ebe525..c63c4d1 100644
--- a/app/components/plan-view/plan-view.html
+++ b/app/components/plan-view/plan-view.html
@@ -39,20 +39,20 @@
<span class="stat-value">{{executionTime}}</span>
<span class="stat-label">execution time ({{executionTimeUnit}})</span>
</div>
- <div *ngIf="planStats.planningTime">
- <span class="stat-value">{{planStats.planningTime | number:'.0-2'}}</span>
+ <div *ngIf="plan.planStats.planningTime">
+ <span class="stat-value">{{plan.planStats.planningTime | number:'.0-2'}}</span>
<span class="stat-label">planning time (ms)</span>
</div>
- <div *ngIf="planStats.maxDuration">
- <span class="stat-value">{{planStats.maxDuration | number:'.0-2'}}</span>
+ <div *ngIf="plan.planStats.maxDuration">
+ <span class="stat-value">{{plan.planStats.maxDuration | number:'.0-2'}}</span>
<span class="stat-label">slowest node (ms)</span>
</div>
- <div *ngIf="planStats.maxRows">
- <span class="stat-value">{{planStats.maxRows | number:'.0-2'}}</span>
+ <div *ngIf="plan.planStats.maxRows">
+ <span class="stat-value">{{plan.planStats.maxRows | number:'.0-2'}}</span>
<span class="stat-label">largest node (rows)</span>
</div>
- <div *ngIf="planStats.maxCost">
- <span class="stat-value">{{planStats.maxCost | number:'.0-2'}}</span>
+ <div *ngIf="plan.planStats.maxCost">
+ <span class="stat-value">{{plan.planStats.maxCost | number:'.0-2'}}</span>
<span class="stat-label">costliest node</span>
</div>
</div>
@@ -60,7 +60,7 @@
<div class="plan">
<ul>
<li>
- <plan-node [node]="rootContainer.Plan" [planStats]="planStats" [viewOptions]="viewOptions"></plan-node>
+ <plan-node [plan]="plan" [node]="rootContainer.Plan" [viewOptions]="viewOptions"></plan-node>
</li>
</ul>
</div>
diff --git a/app/components/plan-view/plan-view.ts b/app/components/plan-view/plan-view.ts
index 1ec3855..e1700ba 100644
--- a/app/components/plan-view/plan-view.ts
+++ b/app/components/plan-view/plan-view.ts
@@ -2,15 +2,16 @@ import {Component, OnInit} from 'angular2/core';
import {ROUTER_DIRECTIVES, RouteParams} from 'angular2/router';
import {IPlan} from '../../interfaces/iplan';
-import {PlanService} from '../../services/plan-service';
import {HighlightType} from '../../enums';
import {PlanNode} from '../plan-node/plan-node';
+import {PlanService} from '../../services/plan-service';
+import {SyntaxHighlightService} from '../../services/syntax-highlight-service';
@Component({
selector: 'plan-view',
templateUrl: './components/plan-view/plan-view.html',
directives: [ROUTER_DIRECTIVES, PlanNode],
- providers: [PlanService]
+ providers: [PlanService, SyntaxHighlightService]
})
export class PlanView {
id: string;
@@ -20,13 +21,6 @@ export class PlanView {
executionTimeUnit: string;
hideMenu: boolean = true;
- planStats: any = {
- executionTime: 0,
- maxRows: 0,
- maxCost: 0,
- maxDuration: 0
- };
-
viewOptions: any = {
showPlanStats: true,
showHighlightBar: true,
@@ -40,7 +34,7 @@ export class PlanView {
highlightTypes = HighlightType; // exposing the enum to the view
- constructor(private _planService: PlanService, routeParams: RouteParams) {
+ constructor(private _planService: PlanService, routeParams: RouteParams, private _syntaxHighlightService: SyntaxHighlightService) {
this.id = routeParams.get('id');
}
@@ -55,13 +49,17 @@ export class PlanView {
var executionTime: number = this.rootContainer['Execution Time'] || this.rootContainer['Total Runtime'];
[this.executionTime, this.executionTimeUnit] = this.calculateDuration(executionTime);
- this.planStats = {
+ this.plan.planStats = {
executionTime: executionTime,
- planningTime: this.rootContainer['Planning Time'],
- maxRows: this.rootContainer[this._planService.MAXIMUM_ROWS_PROP],
- maxCost: this.rootContainer[this._planService.MAXIMUM_COSTS_PROP],
- maxDuration: this.rootContainer[this._planService.MAXIMUM_DURATION_PROP]
+ planningTime: this.rootContainer['Planning Time'] || 0,
+ maxRows: this.rootContainer[this._planService.MAXIMUM_ROWS_PROP] || 0,
+ maxCost: this.rootContainer[this._planService.MAXIMUM_COSTS_PROP] || 0,
+ maxDuration: this.rootContainer[this._planService.MAXIMUM_DURATION_PROP] || 0
}
+
+ // get syntax highlighted query
+ this._syntaxHighlightService.init();
+ this.plan.formattedQuery = this._syntaxHighlightService.highlight(this.plan.query);
}
ngOnInit() {