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() {  | 
