Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@
"type": "boolean",
"description": "Make larger cells collapsed by default",
"default": false
},
"vscode-db2i.resultsets.outputDecorations": {
"type": "boolean",
"description": "Show INOUT and OUT parameters inside the editor",
"default": true
}
}
},
Expand Down
5 changes: 5 additions & 0 deletions src/views/results/contributes.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
"type": "boolean",
"description": "Make larger cells collapsed by default",
"default": false
},
"vscode-db2i.resultsets.outputDecorations": {
"type": "boolean",
"description": "Show INOUT and OUT parameters inside the editor",
"default": true
}
}
},
Expand Down
75 changes: 75 additions & 0 deletions src/views/results/editorUi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { ParsedStatementInfo } from ".";
import crypto from "crypto";
import { ParameterResult } from "@ibm/mapepire-js";
import { DecorationOptions, ThemeColor, window, Range, MarkdownString, DecorationRangeBehavior } from "vscode";
import Configuration from "../../configuration";

let priorStatements: { [uniqueHash: string]: ParsedStatementInfo } = {};

const outputParameters = window.createTextEditorDecorationType({
after: {
color: new ThemeColor(`editorGhostText.foreground`),
fontStyle: `italic`,
margin: `0 0 0 1em`
},
rangeBehavior: DecorationRangeBehavior.ClosedClosed
});

export function registerRunStatement(stmt: ParsedStatementInfo) {
const uniqueUiId = crypto.randomBytes(16).toString("hex");
priorStatements[uniqueUiId] = stmt;
return uniqueUiId;
}

export function statementDone(uniqueId: string, options: { paramsOut?: ParameterResult[] } = {}) {
const existingStatement = priorStatements[uniqueId];
const activeEditor = window.activeTextEditor;

const shortValue = (v: any, short = true) => {
if (typeof v === "string") {
return short && v.length > 10 ? `${v.substring(0, 10)}...` : v;
}
return v || `-`;
};

if (existingStatement) {
// Huge assumption here the statement is in the active editor

// TODO: feature flag
if (Configuration.get(`resultsets.outputDecorations`)) {
if (activeEditor) {
const document = activeEditor.document;
const startPosition = document.positionAt(existingStatement.group.range.start);
const endPosition = document.positionAt(existingStatement.group.range.end + 1);

if (options.paramsOut && options.paramsOut.length > 0) {
const markdownString = new MarkdownString();
options.paramsOut.forEach((p, i) => {
markdownString.appendMarkdown(`**Parameter ${i + 1}${p.name ? ` - ${p.name}` : ``}**:\n\n\`\`\`\n${p.value !== undefined ? p.value : `-`}\n\`\`\``);

if (i !== options.paramsOut.length - 1) {
markdownString.appendMarkdown(`\n\n---\n\n`);
}
});

const shouldBeShort = options.paramsOut.length > 1;
const values = `=> ` + options.paramsOut.map((p) => shortValue(p.value, shouldBeShort)).join(", ");

const decoration: DecorationOptions = {
range: new Range(startPosition, endPosition),
hoverMessage: markdownString,
renderOptions: {
after: {
contentText: values,
}
}
};

activeEditor.setDecorations(outputParameters, [decoration]);
}
}
}

delete priorStatements[uniqueId];
}
}
3 changes: 2 additions & 1 deletion src/views/results/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ document.getElementById('resultset').onclick = function(e){
};
`;

export function generateScroller(basicSelect: string, parameters: SqlParameter[] = [], isCL: boolean = false, withCancel: boolean = false, updatable?: UpdatableInfo): string {
export function generateScroller(uiId: string, basicSelect: string, parameters: SqlParameter[] = [], isCL: boolean = false, withCancel: boolean = false, updatable?: UpdatableInfo): string {
const withCollapsed = Configuration.get<boolean>('collapsedResultSet');

return /*html*/`
Expand Down Expand Up @@ -417,6 +417,7 @@ export function generateScroller(basicSelect: string, parameters: SqlParameter[]
function fetchNextPage() {
isFetching = true;
vscode.postMessage({
uiId: ${JSON.stringify(uiId)},
query: basicSelect,
parameters: ${JSON.stringify(parameters)},
isCL: ${isCL},
Expand Down
7 changes: 5 additions & 2 deletions src/views/results/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import * as vscode from "vscode";
import crypto from "crypto";
import { SnippetString, ViewColumn, TreeView, window } from "vscode"

import * as csv from "csv/sync";


import { JobManager } from "../../config";
import Document from "../../language/sql/document";
import { ObjectRef, ParsedEmbeddedStatement, StatementGroup, StatementType } from "../../language/sql/types";
Expand All @@ -21,6 +21,7 @@ import { queryResultToRpgDs } from "./codegen";
import Configuration from "../../configuration";
import { getSqlDocument } from "../../language/providers/logic/parse";
import { getLiteralsFromStatement, getPriorBindableStatement } from "./binding";
import { registerRunStatement } from "./editorUi";

export type StatementQualifier = "statement" | "bind" | "update" | "explain" | "onlyexplain" | "json" | "csv" | "cl" | "sql" | "rpg";

Expand Down Expand Up @@ -57,7 +58,7 @@ let doveResultsView = new DoveResultsView();
let doveResultsTreeView: TreeView<ExplainTreeItem> = doveResultsView.getTreeView();
let doveNodeView = new DoveNodeView();
let doveNodeTreeView: TreeView<PropertyNode> = doveNodeView.getTreeView();
let doveTreeDecorationProvider = new DoveTreeDecorationProvider(); // Self-registers as a tree decoration providor
let doveTreeDecorationProvider = new DoveTreeDecorationProvider(); // Self-registers as a tree decoration provider

export function initialise(context: vscode.ExtensionContext) {
setCancelButtonVisibility(false);
Expand Down Expand Up @@ -378,13 +379,15 @@ async function runHandler(options?: StatementInfo) {
updatableTable = refs[0];
}

const uiId = registerRunStatement(statementDetail);
const basicSelect = statementDetail.content.split(eol).filter(line => !line.trimStart().startsWith(`--`)).join(eol);

chosenView.setScrolling({ // Never errors
basicSelect: basicSelect,
withCancel: inWindow,
ref: updatableTable,
parameters,
uiId
})
}

Expand Down
13 changes: 10 additions & 3 deletions src/views/results/resultSetPanelProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ import { ObjectRef } from "../../language/sql/types";
import Table from "../../database/table";
import Statement from "../../database/statement";
import { TableColumn } from "../../types";
import { statementDone } from "./editorUi";
import { QueryResult } from "@ibm/mapepire-js";

export type SqlParameter = string|number;

export interface ScrollerOptions {
uiId?: string;
basicSelect: string;
parameters?: SqlParameter[];
isCL?: boolean;
Expand Down Expand Up @@ -106,7 +109,7 @@ export class ResultSetPanelProvider implements WebviewViewProvider {

if (this.currentQuery.getState() !== "RUN_DONE") {
setCancelButtonVisibility(true);
let queryResults = undefined;
let queryResults: QueryResult<any> = undefined;
let startTime = 0;
let endTime = 0;
let executionTime: number|undefined;
Expand All @@ -118,7 +121,11 @@ export class ResultSetPanelProvider implements WebviewViewProvider {
startTime = performance.now();
queryResults = await this.currentQuery.execute();
endTime = performance.now();
executionTime = (endTime - startTime)
executionTime = (endTime - startTime);

if (message.uiId) {
statementDone(message.uiId, {paramsOut: queryResults.output_parms});
}
}
const jobId = this.currentQuery.getHostJob().id;

Expand Down Expand Up @@ -285,7 +292,7 @@ export class ResultSetPanelProvider implements WebviewViewProvider {
}
}

this._view.webview.html = html.generateScroller(options.basicSelect, options.parameters, options.isCL, options.withCancel, updatable);
this._view.webview.html = html.generateScroller(options.uiId, options.basicSelect, options.parameters, options.isCL, options.withCancel, updatable);

this._view.webview.postMessage({
command: `fetch`,
Expand Down
Loading