Skip to content

Commit 3ba8f65

Browse files
committed
Revert "Remove legacy view"
This reverts commit d81df59.
1 parent 2953120 commit 3ba8f65

File tree

4 files changed

+199
-0
lines changed

4 files changed

+199
-0
lines changed

package.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,12 @@
568568
"category": "Db2 for i",
569569
"icon": "$(gear)"
570570
},
571+
{
572+
"command": "vscode-db2i.dove.export",
573+
"title": "Export current VE data",
574+
"category": "Db2 for i",
575+
"icon": "$(file)"
576+
},
571577
{
572578
"command": "vscode-db2i.dove.node.copy",
573579
"title": "Copy value",
@@ -865,6 +871,10 @@
865871
"command": "vscode-db2i.dove.editSettings",
866872
"when": "vscode-db2i:explaining == true"
867873
},
874+
{
875+
"command": "vscode-db2i.dove.export",
876+
"when": "vscode-db2i:explaining == true"
877+
},
868878
{
869879
"command": "vscode-db2i.dove.node.copy",
870880
"when": "never"
@@ -969,6 +979,11 @@
969979
"group": "navigation@1",
970980
"when": "view == vscode-db2i.dove.nodes"
971981
},
982+
{
983+
"command": "vscode-db2i.dove.export",
984+
"group": "navigation@2",
985+
"when": "view == vscode-db2i.dove.nodes"
986+
},
972987
{
973988
"command": "vscode-db2i.dove.close",
974989
"group": "navigation@3",

src/views/results/explain/contributes.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@
106106
"category": "Db2 for i",
107107
"icon": "$(gear)"
108108
},
109+
{
110+
"command": "vscode-db2i.dove.export",
111+
"title": "Export current VE data",
112+
"category": "Db2 for i",
113+
"icon": "$(file)"
114+
},
109115
{
110116
"command": "vscode-db2i.dove.node.copy",
111117
"title": "Copy value",
@@ -127,6 +133,10 @@
127133
"command": "vscode-db2i.dove.editSettings",
128134
"when": "vscode-db2i:explaining == true"
129135
},
136+
{
137+
"command": "vscode-db2i.dove.export",
138+
"when": "vscode-db2i:explaining == true"
139+
},
130140
{
131141
"command": "vscode-db2i.dove.node.copy",
132142
"when": "never"
@@ -143,6 +153,11 @@
143153
"group": "navigation@1",
144154
"when": "view == vscode-db2i.dove.nodes"
145155
},
156+
{
157+
"command": "vscode-db2i.dove.export",
158+
"group": "navigation@2",
159+
"when": "view == vscode-db2i.dove.nodes"
160+
},
146161
{
147162
"command": "vscode-db2i.dove.close",
148163
"group": "navigation@3",
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import * as vscode from "vscode";
2+
import { CancellationToken, Event, EventEmitter, ProviderResult, TreeView, TreeDataProvider, TreeItem, TreeItemCollapsibleState, commands, ThemeIcon } from "vscode";
3+
import { ExplainNode } from "./nodes";
4+
import { toDoveTreeDecorationProviderUri } from "./doveTreeDecorationProvider";
5+
6+
/**
7+
* Icon labels as defined by the API, along with the name of the icon to display.
8+
* Not surprisingly, the reference link does not provide a complete list of icons.
9+
* TODO: Add missing icons
10+
* @see https://www.ibm.com/docs/en/i/7.5?topic=ssw_ibm_i_75/apis/qqqvexpl.html#icon_labels
11+
* @see https://code.visualstudio.com/api/references/icons-in-labels
12+
*/
13+
const icons = {
14+
"Bitmap Merge": `merge`,
15+
"Cache": ``,
16+
"Cache Probe": ``,
17+
"Delete": `trash`,
18+
"Distinct": `list-flat`,
19+
"Dynamic Bitmap": `symbol-misc`,
20+
"Encoded Vector Index": `symbol-reference`,
21+
"Encoded Vector Index, Parallel": `symbol-reference`,
22+
"Final Select": `selection`,
23+
"Hash Grouping": `group-by-ref-type`,
24+
"Hash Join": `add`,
25+
"Hash Scan": `search`,
26+
"Index Grouping": `group-by-ref-type`,
27+
"Index Scan - Key Positioning": `key`,
28+
"Index Scan - Key Positioning, Parallel": `key`,
29+
"Index Scan - Key Selection": `key`,
30+
"Index Scan - Key Selection, Parallel": `key`,
31+
"Insert": `insert`,
32+
"Nested Loop Join": `add`,
33+
"Select": `selection`,
34+
"Skip Sequential Table Scan": `list-unordered`,
35+
"Skip Sequential Table Scan, Parallel": `list-unordered`,
36+
"Sort": `sort-precedence`,
37+
"Sorted List Scan": `list-ordered`,
38+
"Subquery Merge": `merge`,
39+
"Table Probe": `list-selection`,
40+
"Table Scan": `search`,
41+
"Table Scan, Parallel": `search`,
42+
"Temporary Distinct Hash Table": `new-file`,
43+
"Temporary Hash Table": `new-file`,
44+
"Temporary Index": `new-file`,
45+
"Temporary Sorted List": `list-ordered`,
46+
"Temporary Table": `new-file`,
47+
"Union Merge": `merge`,
48+
"User Defined Table Function": `symbol-function`,
49+
"Unknown": `question`,
50+
"Update": `replace`,
51+
"VALUES LIST": `list-flat`,
52+
}
53+
54+
type ChangeTreeDataEventType = ExplainTreeItem | undefined | null | void;
55+
56+
export class DoveResultsView implements TreeDataProvider<any> {
57+
private _onDidChangeTreeData: EventEmitter<ChangeTreeDataEventType> = new EventEmitter<ChangeTreeDataEventType>();
58+
readonly onDidChangeTreeData: Event<ChangeTreeDataEventType> = this._onDidChangeTreeData.event;
59+
60+
private topNode: ExplainTreeItem;
61+
62+
private treeView: TreeView<ExplainTreeItem>;
63+
64+
constructor() {
65+
this.treeView = vscode.window.createTreeView(`vscode-db2i.dove.nodes`, { treeDataProvider: this, showCollapseAll: true });
66+
}
67+
68+
public getTreeView(): TreeView<ExplainTreeItem> {
69+
return this.treeView;
70+
}
71+
72+
setRootNode(topNode: ExplainNode): ExplainTreeItem {
73+
this.topNode = new ExplainTreeItem(topNode);
74+
this._onDidChangeTreeData.fire();
75+
76+
// Show tree in the view
77+
commands.executeCommand(`setContext`, `vscode-db2i:explaining`, true);
78+
// Ensure that the tree is positioned such that the first element is visible
79+
this.treeView.reveal(this.topNode, { select: false });
80+
return this.topNode;
81+
}
82+
getRootNode(): ExplainTreeItem {
83+
return this.topNode;
84+
}
85+
86+
getRootExplainNode(): ExplainNode {
87+
return this.topNode.explainNode;
88+
}
89+
90+
close(): void {
91+
commands.executeCommand(`setContext`, `vscode-db2i:explaining`, false);
92+
}
93+
94+
getTreeItem(element: ExplainTreeItem): ExplainTreeItem | Thenable<ExplainTreeItem> {
95+
return element;
96+
}
97+
98+
getChildren(element?: ExplainTreeItem): ProviderResult<ExplainTreeItem[]> {
99+
if (element) {
100+
return element.getChildren();
101+
} else if (this.topNode) {
102+
return [this.topNode];
103+
} else {
104+
return [];
105+
}
106+
}
107+
108+
getParent?(element: any) {
109+
throw new Error("Method not implemented.");
110+
}
111+
112+
resolveTreeItem?(item: TreeItem, element: any, token: CancellationToken): ProviderResult<ExplainTreeItem> {
113+
throw new Error("Method not implemented.");
114+
}
115+
}
116+
117+
export class ExplainTreeItem extends TreeItem {
118+
explainNode: ExplainNode;
119+
private children: ExplainTreeItem[];
120+
121+
constructor(node: ExplainNode) {
122+
super(node.title, node.childrenNodes > 0 ? TreeItemCollapsibleState.Expanded : TreeItemCollapsibleState.None);
123+
this.explainNode = node;
124+
this.contextValue = `explainTreeItem`;
125+
126+
// If the node is associated with a DB object, display the qualified object name in the description
127+
if (node.objectSchema && node.objectName) {
128+
this.description = node.objectSchema + `.` + node.objectName;
129+
}
130+
131+
// TODO: ideally the tooltip would be built using a MarkdownString, but regardless of everything tried, 'Loading...' is always displayed
132+
this.tooltip = [node.title, node.tooltipProps.map<string>(prop => prop.title + `: ` + prop.value).join(`\n`), ``].join(`\n`);
133+
this.resourceUri = toDoveTreeDecorationProviderUri(node.highlights);
134+
this.iconPath = new ThemeIcon(icons[node.title] || `server-process`, node.highlights.getPriorityColor()); // `circle-outline`
135+
}
136+
137+
getChildren(): ExplainTreeItem[] {
138+
if (!this.children) {
139+
this.children = this.explainNode.children.map(c => new ExplainTreeItem(c));
140+
}
141+
return this.children;
142+
}
143+
}

src/views/results/index.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Document from "../../language/sql/document";
99
import { ObjectRef, ParsedEmbeddedStatement, StatementGroup, StatementType } from "../../language/sql/types";
1010
import Statement from "../../language/sql/statement";
1111
import { ExplainNode, ExplainTree } from "./explain/nodes";
12+
import { DoveResultsView, ExplainTreeItem } from "./explain/doveResultsView";
1213
import { DoveNodeView, PropertyNode } from "./explain/doveNodeView";
1314
import { ResultSetPanelProvider, SqlParameter } from "./resultSetPanelProvider";
1415
import { generateSqlForAdvisedIndexes } from "./explain/advice";
@@ -52,13 +53,16 @@ export function setCancelButtonVisibility(visible: boolean) {
5253

5354
let resultSetProvider = new ResultSetPanelProvider();
5455
let explainTree: ExplainTree;
56+
let doveResultsView = new DoveResultsView();
57+
let doveResultsTreeView: TreeView<ExplainTreeItem> = doveResultsView.getTreeView();
5558
let doveNodeView = new DoveNodeView();
5659
let doveNodeTreeView: TreeView<PropertyNode> = doveNodeView.getTreeView();
5760

5861
export function initialise(context: vscode.ExtensionContext) {
5962
setCancelButtonVisibility(false);
6063

6164
context.subscriptions.push(
65+
doveResultsTreeView,
6266
doveNodeTreeView,
6367

6468
vscode.window.registerWebviewViewProvider(`vscode-db2i.resultset`, resultSetProvider, {
@@ -97,6 +101,17 @@ export function initialise(context: vscode.ExtensionContext) {
97101
}
98102
}),
99103

104+
vscode.commands.registerCommand(`vscode-db2i.dove.close`, () => {
105+
doveResultsView.close();
106+
doveNodeView.close();
107+
}),
108+
109+
vscode.commands.registerCommand(`vscode-db2i.dove.displayDetails`, (explainTreeItem: ExplainTreeItem) => {
110+
// When the user clicks for details of a node in the tree, set the focus to that node as a visual indicator tying it to the details tree
111+
doveResultsTreeView.reveal(explainTreeItem, { select: false, focus: true, expand: true });
112+
doveNodeView.setNode(explainTreeItem.explainNode);
113+
}),
114+
100115
vscode.commands.registerCommand(`vscode-db2i.dove.node.copy`, (propertyNode: PropertyNode) => {
101116
if (propertyNode.description && typeof propertyNode.description === `string`) {
102117
vscode.env.clipboard.writeText(propertyNode.description);
@@ -112,6 +127,15 @@ export function initialise(context: vscode.ExtensionContext) {
112127
vscode.commands.executeCommand('workbench.action.openSettings', 'vscode-db2i.visualExplain');
113128
}),
114129

130+
vscode.commands.registerCommand(`vscode-db2i.dove.export`, () => {
131+
vscode.workspace.openTextDocument({
132+
language: `json`,
133+
content: JSON.stringify(doveResultsView.getRootExplainNode(), null, 2)
134+
}).then(doc => {
135+
vscode.window.showTextDocument(doc);
136+
});
137+
}),
138+
115139
vscode.commands.registerCommand(`vscode-db2i.dove.generateSqlForAdvisedIndexes`, () => {
116140
const scriptContent = generateSqlForAdvisedIndexes(explainTree);
117141

@@ -236,6 +260,8 @@ async function runHandler(options?: StatementInfo) {
236260
const optionsIsValid = (options?.content !== undefined);
237261
let editor = vscode.window.activeTextEditor;
238262

263+
vscode.commands.executeCommand('vscode-db2i.dove.close');
264+
239265
if (optionsIsValid || (editor && editor.document.languageId === `sql`)) {
240266
let chosenView = resultSetProvider;
241267

0 commit comments

Comments
 (0)