diff options
author | Alex Tatiyants <atatiyan@gmail.com> | 2016-01-04 19:42:44 -0800 |
---|---|---|
committer | Alex Tatiyants <atatiyan@gmail.com> | 2016-01-04 19:42:44 -0800 |
commit | d89ddcf3532937d395898f255c42f3d26303f1c4 (patch) | |
tree | 9efdf18c3fa965f1a1d140e5b2b06a9cfa0a4e19 /app/components | |
parent | 7955dbcc9272f258c9b36e67853471e59d851cac (diff) |
add integrated query view with syntax highlighting
Diffstat (limited to 'app/components')
-rw-r--r-- | app/components/plan-node/plan-node.html | 20 | ||||
-rw-r--r-- | app/components/plan-node/plan-node.ts | 26 | ||||
-rw-r--r-- | app/components/plan-view/plan-view.html | 18 | ||||
-rw-r--r-- | app/components/plan-view/plan-view.ts | 28 |
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() { |