Skip to content

Commit 21b3100

Browse files
authored
Merge pull request #165 from codefori/feature/notebooks
Initial work on Notebooks
2 parents c077816 + 5046148 commit 21b3100

File tree

18 files changed

+2026
-403
lines changed

18 files changed

+2026
-403
lines changed

package-lock.json

Lines changed: 511 additions & 371 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 94 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,12 @@
8080
"order": 0,
8181
"description": "Default SELF setting for new jobs",
8282
"default": "*NONE",
83-
"enum": ["*NONE", "*ALL", "*ERROR", "*WARNING"]
83+
"enum": [
84+
"*NONE",
85+
"*ALL",
86+
"*ERROR",
87+
"*WARNING"
88+
]
8489
},
8590
"vscode-db2i.jobSelfViewAutoRefresh": {
8691
"type": "boolean",
@@ -98,7 +103,11 @@
98103
"type": "string",
99104
"description": "SQL identifiers",
100105
"default": "preserve",
101-
"enum": ["lower", "upper", "preserve"],
106+
"enum": [
107+
"lower",
108+
"upper",
109+
"preserve"
110+
],
102111
"enumDescriptions": [
103112
"Format SQL identifiers in lowercase",
104113
"Format SQL identifiers in uppercase",
@@ -109,7 +118,10 @@
109118
"type": "string",
110119
"description": "SQL keywords",
111120
"default": "lower",
112-
"enum": ["lower", "upper"],
121+
"enum": [
122+
"lower",
123+
"upper"
124+
],
113125
"enumDescriptions": [
114126
"Format reserved SQL keywords in lowercase",
115127
"Format reserved SQL keywords in uppercase"
@@ -126,12 +138,15 @@
126138
"order": 0,
127139
"description": "Descriptor to use for column headings when viewing data",
128140
"default": "Name",
129-
"enum": ["Name", "Label"],
141+
"enum": [
142+
"Name",
143+
"Label"
144+
],
130145
"enumDescriptions": [
131146
"Show the column name",
132147
"Show the column label\n'Extended metadata' must be set to true in the JDBC configuration"
133148
]
134-
},
149+
},
135150
"vscode-db2i.collapsedResultSet": {
136151
"type": "boolean",
137152
"description": "Make larger cells collapsed by default",
@@ -190,6 +205,18 @@
190205
}
191206
}
192207
],
208+
"notebooks": [
209+
{
210+
"id": "db2i-notebook",
211+
"type": "db2i-notebook",
212+
"displayName": "IBM i Notebook",
213+
"selector": [
214+
{
215+
"filenamePattern": "*.inb"
216+
}
217+
]
218+
}
219+
],
193220
"viewsContainers": {
194221
"activitybar": [
195222
{
@@ -286,22 +313,47 @@
286313
"command": "vscode-db2i.runEditorStatement",
287314
"key": "ctrl+r",
288315
"mac": "cmd+r",
289-
"when": "editorLangId == sql"
316+
"when": "editorLangId == sql && resourceExtname != .inb"
290317
},
291318
{
292319
"command": "vscode-db2i.editorExplain.withRun",
293320
"key": "ctrl+shift+r",
294321
"mac": "cmd+shift+r",
295-
"when": "editorLangId == sql"
322+
"when": "editorLangId == sql && resourceExtname != .inb"
296323
},
297324
{
298325
"command": "vscode-db2i.editorExplain.withoutRun",
299326
"key": "ctrl+alt+r",
300327
"mac": "cmd+alt+r",
301-
"when": "editorLangId == sql"
328+
"when": "editorLangId == sql && resourceExtname != .inb"
329+
},
330+
{
331+
"command": "notebook.cell.execute",
332+
"key": "ctrl+r",
333+
"mac": "cmd+r",
334+
"when": "editorLangId == sql && resourceExtname == .inb"
302335
}
303336
],
304337
"commands": [
338+
{
339+
"command": "vscode-db2i.notebook.open",
340+
"title": "New Notebook",
341+
"category": "IBM i Notebooks",
342+
"enablement": "code-for-ibmi:connected == true",
343+
"icon": "$(notebook)"
344+
},
345+
{
346+
"command": "vscode-db2i.notebook.fromSqlUri",
347+
"title": "Open as Notebook",
348+
"category": "IBM i Notebooks",
349+
"icon": "$(notebook)"
350+
},
351+
{
352+
"command": "vscode-db2i.notebook.exportAsHtml",
353+
"title": "Export",
354+
"category": "IBM i Notebooks",
355+
"icon": "$(save)"
356+
},
305357
{
306358
"command": "vscode-db2i.openSqlDocument",
307359
"title": "Open SQL Document",
@@ -439,7 +491,7 @@
439491
"command": "vscode-db2i.editorExplain.withoutRun",
440492
"title": "Explain without running",
441493
"category": "Db2 for i",
442-
"icon": "$(debug-alt)"
494+
"icon": "$(debug-alt)"
443495
},
444496
{
445497
"command": "vscode-db2i.queryHistory.remove",
@@ -622,6 +674,13 @@
622674
}
623675
],
624676
"menus": {
677+
"notebook/toolbar": [
678+
{
679+
"command": "vscode-db2i.notebook.exportAsHtml",
680+
"when": "code-for-ibmi:connected == true && resourceExtname == .inb",
681+
"group": "navigation"
682+
}
683+
],
625684
"commandPalette": [
626685
{
627686
"command": "vscode-db2i.queryHistory.remove",
@@ -671,6 +730,10 @@
671730
"command": "vscode-db2i.jobManager.deleteConfig",
672731
"when": "never"
673732
},
733+
{
734+
"command": "vscode-db2i.notebook.fromSqlUri",
735+
"when": "never"
736+
},
674737
{
675738
"command": "vscode-db2i.dove.displayDetails",
676739
"when": "never"
@@ -730,6 +793,11 @@
730793
"command": "vscode-db2i.editorExplain.withoutRun",
731794
"when": "editorLangId == sql",
732795
"group": "2_explain@2"
796+
},
797+
{
798+
"command": "vscode-db2i.notebook.fromSqlUri",
799+
"when": "editorLangId == sql",
800+
"group": "3_notebook@1"
733801
}
734802
],
735803
"view/title": [
@@ -783,14 +851,9 @@
783851
"group": "navigation",
784852
"when": "view == exampleBrowser"
785853
},
786-
{
787-
"command": "vscode-db2i.openSqlDocument",
788-
"group": "navigation",
789-
"when": "view == jobManager"
790-
},
791854
{
792855
"command": "vscode-db2i.jobManager.newJob",
793-
"group": "navigation",
856+
"group": "navigation@1",
794857
"when": "view == jobManager"
795858
},
796859
{
@@ -800,7 +863,17 @@
800863
},
801864
{
802865
"command": "vscode-db2i.jobManager.endAll",
803-
"group": "navigation",
866+
"group": "navigation@2",
867+
"when": "view == jobManager"
868+
},
869+
{
870+
"command": "vscode-db2i.openSqlDocument",
871+
"group": "navigation@3",
872+
"when": "view == jobManager"
873+
},
874+
{
875+
"command": "vscode-db2i.notebook.open",
876+
"group": "navigation@4",
804877
"when": "view == jobManager"
805878
},
806879
{
@@ -930,7 +1003,7 @@
9301003
"when": "view == jobManager && viewItem == sqlJob",
9311004
"group": "inline"
9321005
},
933-
{
1006+
{
9341007
"command": "vscode-db2i.jobManager.editSelfCodes",
9351008
"when": "view == jobManager && viewItem == sqlJob",
9361009
"group": "self@2"
@@ -1081,13 +1154,16 @@
10811154
"typescript": "^4.3.2",
10821155
"vitest": "^0.33.0",
10831156
"vscode-test": "^1.5.2",
1084-
"webpack": "^5.24.3",
1157+
"webpack": "^5.91.0",
10851158
"webpack-cli": "^4.5.0"
10861159
},
10871160
"dependencies": {
1161+
"chart.js": "^4.4.2",
10881162
"csv": "^6.1.3",
1163+
"json-to-markdown-table": "^1.0.0",
10891164
"lru-cache": "^6.0.0",
10901165
"node-fetch": "^3.3.1",
1166+
"showdown": "^2.1.0",
10911167
"sql-formatter": "^14.0.0"
10921168
}
10931169
}

src/connection/sqlJob.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,14 @@ export class SQLJob {
346346

347347
this.send(JSON.stringify(exitObject));
348348

349+
this.responseEmitter.eventNames().forEach(event => {
350+
this.responseEmitter.emit(event, JSON.stringify({
351+
id: event,
352+
success: false,
353+
error: `Job ended before response returned.`
354+
}));
355+
});
356+
349357
this.dispose();
350358
}
351359

src/extension.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { ServerComponent } from "./connection/serverComponent";
1717
import { SQLJobManager } from "./connection/manager";
1818
import { JDBCOptions } from "./connection/types";
1919
import { SQLJob } from "./connection/sqlJob";
20+
import { notebookInit } from "./notebooks/IBMiSerializer";
2021
import { SelfTreeDecorationProvider, selfCodesResultsView } from "./views/jobManager/selfCodes/selfCodesResultsView";
2122
import Configuration from "./configuration";
2223

@@ -41,6 +42,7 @@ export function activate(context: vscode.ExtensionContext): Db2i {
4142

4243
context.subscriptions.push(
4344
...languageInit(),
45+
...notebookInit(),
4446
ServerComponent.initOutputChannel(),
4547
vscode.window.registerTreeDataProvider(
4648
`jobManager`,

src/language/providers/completionProvider.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -408,11 +408,13 @@ async function getCompletionItemsForRefs(currentStatement: LanguageStatement.def
408408
// content assist invoked during incomplete reference
409409
// example: select * from sample.emp
410410
// -- |
411-
const curSchema: string = objectRefs[objectRefs.length - 1].object.schema;
412-
if (curClause !== ClauseType.Unknown && tokenAtOffset && curSchema) {
413-
completionItems.push(
414-
...(await getObjectCompletions(curSchema, completionTypes))
415-
);
411+
if (objectRefs[objectRefs.length - 1]) {
412+
const curSchema: string = objectRefs[objectRefs.length - 1].object.schema;
413+
if (curClause !== ClauseType.Unknown && tokenAtOffset && curSchema) {
414+
completionItems.push(
415+
...(await getObjectCompletions(curSchema, completionTypes))
416+
);
417+
}
416418
}
417419
}
418420

src/language/sql/statement.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ export default class Statement {
1313

1414
let first = this.tokens[0];
1515

16-
if (tokenIs(first, `word`, `EXEC`) && tokenIs(this.tokens[1], `word`, `SQL`) && this) {
17-
first = this.tokens[3];
16+
if (tokenIs(first, `word`, `EXEC`) && tokenIs(this.tokens[1], `word`, `SQL`)) {
17+
first = this.tokens[2];
18+
} else if (tokenIs(first, `word`) && tokenIs(this.tokens[1], `colon`)) {
19+
first = this.tokens[2];
1820
}
1921

2022
if (tokenIs(first, `statementType`) || tokenIs(first, `keyword`, `END`) || tokenIs(first, `keyword`, `BEGIN`)) {

src/language/sql/tests/statements.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,27 @@ describe(`Parameter statement tests`, () => {
14371437
});
14381438
});
14391439

1440+
describe(`Prefix tests`, () => {
1441+
test('CL prefix', () => {
1442+
const content = [
1443+
`-- example`,
1444+
`bar: SELECT A.AUTHORIZATION_NAME as label, SUM(A.STORAGE_USED) AS TOTAL_STORAGE_USED`,
1445+
` FROM QSYS2.USER_STORAGE A `,
1446+
` INNER JOIN QSYS2.USER_INFO B ON B.USER_NAME = A.AUTHORIZATION_NAME WHERE B.USER_NAME NOT LIKE 'Q%' `,
1447+
` GROUP BY A.AUTHORIZATION_NAME, B.TEXT_DESCRIPTION, B.ACCOUNTING_CODE, B.MAXIMUM_ALLOWED_STORAGE`,
1448+
` ORDER BY TOTAL_STORAGE_USED DESC FETCH FIRST 10 ROWS ONLY`,
1449+
].join(`\n`);
1450+
1451+
const document = new Document(content);
1452+
const statements = document.statements;
1453+
expect(statements.length).toBe(1);
1454+
1455+
const statement = statements[0];
1456+
1457+
expect(statement.type).toBe(StatementType.Select);
1458+
});
1459+
});
1460+
14401461
test(`Callable blocks`, () => {
14411462
const lines = [
14421463
`call qsys2.create_abcd();`,

0 commit comments

Comments
 (0)