Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing Branch: VE with 0.6.0 #180

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
12717b5
Initial work for explain data
worksofliam Sep 25, 2023
d4a1a15
API for converting flat data to nodes
worksofliam Sep 25, 2023
e1d5f02
Merge branch 'main' into feature/dove
worksofliam Oct 19, 2023
72d97cd
Working visual explain UX
worksofliam Oct 19, 2023
f08ca7c
Cleanup large result set panel
worksofliam Oct 19, 2023
4220424
File reorg
worksofliam Oct 19, 2023
54f2587
Start of icon mapping
worksofliam Oct 19, 2023
e8f41cf
Export VE data as JSON
worksofliam Oct 19, 2023
86fa6d8
Explain button
worksofliam Oct 19, 2023
14a66a8
Scrolling result set with explain
worksofliam Oct 20, 2023
9693970
Comment out full open requirement
worksofliam Oct 20, 2023
b1e0164
1.4.3 SC
worksofliam Oct 20, 2023
2f76467
CLI and additional logging
worksofliam Oct 20, 2023
74f2780
Node view headings, icons, constants
davecharron Nov 10, 2023
3b7c9b1
Process string data returned via multiple records
davecharron Nov 10, 2023
1d2fad6
Don't display invisible attributes
davecharron Nov 16, 2023
bd259a2
Handle double-byte properties and Delta attributes
davecharron Nov 17, 2023
fc35d7a
Add node descriptions and tooltips
davecharron Nov 17, 2023
1ebae70
Format object name in node description
davecharron Nov 22, 2023
465e7da
Tree node colors, framework and attribute headings
davecharron Nov 22, 2023
f9894ee
TreeDecorationProvider fixes
davecharron Nov 27, 2023
881ae81
Fix typos
davecharron Nov 27, 2023
2889782
Important node indicators (color, badge, tooltip)
davecharron Nov 30, 2023
ac29bb9
Merge branch 'feature/dove' into test/0.6.0_with_ve
worksofliam Dec 5, 2023
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
162 changes: 157 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,19 @@
"name": "Results",
"when": "code-for-ibmi:connected == true",
"contextualTitle": "IBM i"
},
{
"type": "tree",
"id": "vscode-db2i.dove.nodes",
"name": "Visual Explain",
"when": "vscode-db2i:explaining == true",
"contextualTitle": "IBM i"
},
{
"type": "tree",
"id": "vscode-db2i.dove.node",
"name": "Node Detail",
"when": "vscode-db2i:explainingNode == true"
}
],
"db2-explorer": [
Expand Down Expand Up @@ -263,10 +276,16 @@
},
{
"command": "vscode-db2i.runEditorStatement",
"title": "Run selected statement",
"title": "Run statement",
"category": "Db2 for i",
"icon": "$(notebook-execute)"
},
{
"command": "vscode-db2i.explainEditorStatement",
"title": "Explain statement",
"category": "Db2 for i",
"icon": "$(debug-alt)"
},
{
"command": "vscode-db2i.queryHistory.remove",
"title": "Remove query from history",
Expand Down Expand Up @@ -365,6 +384,24 @@
"title": "Delete configuration",
"category": "Db2 for i",
"icon": "$(trash)"
},
{
"command": "vscode-db2i.dove.close",
"title": "Close detail",
"category": "Db2 for i",
"icon": "$(close-all)"
},
{
"command": "vscode-db2i.dove.nodeDetail",
"title": "See detail",
"category": "Db2 for i",
"icon": "$(info)"
},
{
"command": "vscode-db2i.dove.export",
"title": "Export current VE data",
"category": "Db2 for i",
"icon": "$(file)"
}
],
"menus": {
Expand Down Expand Up @@ -420,6 +457,14 @@
{
"command": "vscode-db2i.jobManager.deleteConfig",
"when": "never"
},
{
"command": "vscode-db2i.dove.nodeDetail",
"when": "never"
},
{
"command": "vscode-db2i.dove.export",
"when": "vscode-db2i:explaining == true"
}
],
"editor/context": [
Expand All @@ -433,12 +478,12 @@
{
"command": "vscode-db2i.runEditorStatement",
"when": "editorLangId == sql",
"group": "navigation@2"
"group": "navigation@sql"
},
{
"command": "code-for-ibmi.changeCurrentLibrary",
"command": "vscode-db2i.explainEditorStatement",
"when": "editorLangId == sql",
"group": "navigation@3"
"group": "navigation@sql"
}
],
"view/title": [
Expand Down Expand Up @@ -481,6 +526,16 @@
"command": "vscode-db2i.jobManager.endAll",
"group": "navigation",
"when": "view == jobManager"
},
{
"command": "vscode-db2i.dove.export",
"group": "navigation",
"when": "view == vscode-db2i.dove.nodes"
},
{
"command": "vscode-db2i.dove.close",
"group": "navigation",
"when": "view == vscode-db2i.dove.nodes"
}
],
"view/item/context": [
Expand Down Expand Up @@ -608,9 +663,106 @@
"command": "vscode-db2i.jobManager.deleteConfig",
"when": "view == jobManager && viewItem == savedConfig",
"group": "inline"
},
{
"command": "vscode-db2i.dove.nodeDetail",
"when": "view == vscode-db2i.dove.nodes && viewItem == explainTreeItem",
"group": "inline"
}
]
}
},
"colors": [
{
"id": "db2i.dove.resultsView.HighlightIndexAdvised",
"description": "Highlight color for index advised",
"defaults": {
"dark": "#acace0",
"light": "#8c8cbd",
"highContrast": "#acace0",
"highContrastLight": "#8c8cbd"
}
},
{
"id": "db2i.dove.resultsView.HighlightActualExpensiveRows",
"description": "Highlight color for actual expensive rows",
"defaults": {
"dark": "#cc9933",
"light": "#cc9933",
"highContrast": "#cc9933",
"highContrastLight": "#cc9933"
}
},
{
"id": "db2i.dove.resultsView.HighlightEstimatedExpensiveRows",
"description": "Highlight color for estimated expensive rows",
"defaults": {
"dark": "#ffffbf",
"light": "#ffffbf",
"highContrast": "#ffffbf",
"highContrastLight": "#ffffbf"
}
},
{
"id": "db2i.dove.resultsView.HighlightActualExpensiveTime",
"description": "Highlight color for actual expensive time",
"defaults": {
"dark": "#bc0f0f",
"light": "#bc0f0f",
"highContrast": "#bc0f0f",
"highContrastLight": "#bc0f0f"
}
},
{
"id": "db2i.dove.resultsView.HighlightEstimatedExpensiveTime",
"description": "Highlight color for estimated expensive time",
"defaults": {
"dark": "#f2bdbd",
"light": "#f2bdbd",
"highContrast": "#f2bdbd",
"highContrastLight": "#f2bdbd"
}
},
{
"id": "db2i.dove.resultsView.HighlightLookaheadPredicateGeneration",
"description": "Highlight color for Lookahead Predicate Generation",
"defaults": {
"dark": "#00ff00",
"light": "#00ff00",
"highContrast": "#00ff00",
"highContrastLight": "#00ff00"
}
},
{
"id": "db2i.dove.resultsView.HighlightMaterializedQueryTable",
"description": "Highlight color for Materialized Query Table",
"defaults": {
"dark": "#ff8400",
"light": "#ff8400",
"highContrast": "#ff8400",
"highContrastLight": "#ff8400"
}
},
{
"id": "db2i.dove.resultsView.HighlightRefreshedNode",
"description": "Highlight color for refreshed node",
"defaults": {
"dark": "#00ffff",
"light": "#00ffff",
"highContrast": "#00ffff",
"highContrastLight": "#00ffff"
}
},
{
"id": "db2i.dove.nodeView.AttributeSectionHeading",
"description": "Color for attributes section heading",
"defaults": {
"dark": "#bd8c8c",
"light": "#5976df",
"highContrast": "#bd8c8c",
"highContrastLight": "#5976df"
}
}
]
},
"scripts": {
"lint": "eslint .",
Expand Down
45 changes: 43 additions & 2 deletions src/connection/sqlJob.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CommandResult } from "@halcyontech/vscode-ibmi-types";
import { getInstance } from "../base";
import { ServerComponent } from "./serverComponent";
import { JDBCOptions, ConnectionResult, Rows, QueryResult, JobLogEntry, CLCommandResult, VersionCheckResult, GetTraceDataResult, ServerTraceDest, ServerTraceLevel, SetConfigResult, QueryOptions } from "./types";
import { JDBCOptions, ConnectionResult, Rows, QueryResult, JobLogEntry, CLCommandResult, VersionCheckResult, GetTraceDataResult, ServerTraceDest, ServerTraceLevel, SetConfigResult, QueryOptions, ExplainResults } from "./types";
import { Query } from "./query";
import { EventEmitter } from "stream";

Expand All @@ -12,6 +12,11 @@ export enum JobStatus {
Ended = "ended"
}

export enum ExplainType {
Run,
DoNotRun
}

export enum TransactionEndType {
COMMIT,
ROLLBACK
Expand Down Expand Up @@ -122,6 +127,7 @@ export class SQLJob {

async send(content: string): Promise<string> {
if (this.isTracingChannelData) ServerComponent.writeOutput(content);

let req: ReqRespFmt = JSON.parse(content);
this.channel.stdin.write(content + `\n`);
this.status = JobStatus.Active;
Expand All @@ -138,6 +144,8 @@ export class SQLJob {
}

async connect(): Promise<ConnectionResult> {
this.isTracingChannelData = true;

this.channel = await this.getChannel();

this.channel.on(`error`, (err) => {
Expand All @@ -164,7 +172,8 @@ export class SQLJob {
const connectionObject = {
id: SQLJob.getNewUniqueId(),
type: `connect`,
technique: (getInstance().getConnection().qccsid === 65535 || this.options["database name"]) ? `tcp` : `cli`, //TODO: investigate why QCCSID 65535 breaks CLI and if there is any workaround
//technique: (getInstance().getConnection().qccsid === 65535 || this.options["database name"]) ? `tcp` : `cli`, //TODO: investigate why QCCSID 65535 breaks CLI and if there is any workaround
technique: `tcp`, // TODO: DOVE does not work in cli mode
application: `vscode-db2i ${DB2I_VERSION}`,
props: props.length > 0 ? props : undefined
}
Expand All @@ -186,8 +195,11 @@ export class SQLJob {
this.id = connectResult.job;
this.status = JobStatus.Ready;

this.isTracingChannelData = false;

return connectResult;
}

query<T>(sql: string, opts?: QueryOptions): Query<T> {
return new Query(this, sql, opts);
}
Expand All @@ -209,6 +221,35 @@ export class SQLJob {
return version;
}

async explain(statement: string, type: ExplainType = ExplainType.Run): Promise<ExplainResults<any>> {
if (type !== ExplainType.Run) {
throw new Error("TODO: support more types of explains");
}

// if (this.options["full open"] !== true) {
// throw new Error("Job option 'full open' must be true.");
// }

const explainRequest = {
id: SQLJob.getNewUniqueId(),
type: `dove`,
sql: statement,
run: type === ExplainType.Run
}

const result = await this.send(JSON.stringify(explainRequest));

const explainResult: ExplainResults<any> = JSON.parse(result);

if (explainResult.success !== true) {
this.dispose();
this.status = JobStatus.NotStarted;
throw new Error(explainResult.error || `Failed to explain.`);
}

return explainResult;
}

getTraceFilePath(): string|undefined {
return this.traceFile;
}
Expand Down
5 changes: 5 additions & 0 deletions src/connection/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ export interface VersionCheckResult extends ServerResponse {
version: string;
}

export interface ExplainResults<T> extends QueryResult<T> {
vemetadata: QueryMetaData,
vedata: any;
}

export interface GetTraceDataResult extends ServerResponse {
tracedata: string
}
Expand Down
16 changes: 16 additions & 0 deletions src/testing/jobs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Query } from "../connection/query";
import { ServerComponent } from "../connection/serverComponent";
import { JobStatus, SQLJob } from "../connection/sqlJob";
import { ServerTraceDest, ServerTraceLevel } from "../connection/types";
import { ExplainTree } from "../views/results/explain/nodes";

export const JobsSuite: TestSuite = {
name: `Connection tests`,
Expand Down Expand Up @@ -418,5 +419,20 @@ export const JobsSuite: TestSuite = {
console.log(`Old query method took ${oe - os} milliseconds.`);
assert.equal((ne - ns) < (oe - os), true);
}},

{name: `Explain API`, test: async () => {
const newJob = new SQLJob({"full open": true});
await newJob.connect();

const query = `select * from qiws.qcustcdt`;

const result = await newJob.explain(query);

const tree = new ExplainTree(result.data);

const topLevel = tree.get();

assert.notStrictEqual(topLevel, undefined);
}}
]
}
Loading
Loading