Skip to content

Commit f9b0a3a

Browse files
committed
Merge branch 'main' into update/ai-context
2 parents ea43c9f + 8d401f6 commit f9b0a3a

33 files changed

+6593
-4406
lines changed

.github/workflows/webpack_ci.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ jobs:
5757
issue_number: context.issue.number,
5858
owner: context.repo.owner,
5959
repo: context.repo.repo,
60-
body: '👋 A new build is available for this PR based on ${{ github.event.pull_request.head.sha }}.\n * [Download here.](https://github.com/codefori/vscode-ibmi/actions/runs/${{ github.run_id }})\n* [Read more about how to test](https://github.com/codefori/vscode-ibmi/blob/master/.github/pr_testing_template.md)'
60+
body: '👋 A new build is available for this PR based on ${{ github.event.pull_request.head.sha }}.\n * [Download here.](https://github.com/codefori/vscode-db2i/actions/runs/${{ github.run_id }})\n* [Read more about how to test](https://github.com/codefori/vscode-db2i/blob/master/.github/pr_testing_template.md)'
6161
})
6262
6363
- name: Update comment
@@ -69,5 +69,5 @@ jobs:
6969
body: |
7070
👋 A new build is available for this PR based on ${{ github.event.pull_request.head.sha }}.
7171
72-
* [Download here.](https://github.com/codefori/vscode-ibmi/actions/runs/${{ github.run_id }})
73-
* [Read more about how to test](https://github.com/codefori/vscode-ibmi/blob/master/.github/pr_testing_template.md)
72+
* [Download here.](https://github.com/codefori/vscode-db2i/actions/runs/${{ github.run_id }})
73+
* [Read more about how to test](https://github.com/codefori/vscode-db2i/blob/master/.github/pr_testing_template.md)

global.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ interface SQLParm {
3535

3636
interface BasicSQLObject {
3737
type: string;
38+
tableType: string;
3839
schema: string;
3940
name: string;
4041
specificName: string;

package-lock.json

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

package.json

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "vscode-db2i",
33
"displayName": "Db2 for IBM i",
44
"description": "Db2 for IBM i tools in VS Code",
5-
"version": "1.7.0",
5+
"version": "1.8.0",
66
"engines": {
77
"vscode": "^1.95.0"
88
},
@@ -199,6 +199,32 @@
199199
"default": false
200200
}
201201
}
202+
},
203+
{
204+
"id": "vscode-db2i.syntax",
205+
"title": "SQL Syntax Checking",
206+
"properties": {
207+
"vscode-db2i.syntax.checkOnOpen": {
208+
"type": "boolean",
209+
"description": "If enabled, will check the syntax of the SQL file when it is opened",
210+
"default": false
211+
},
212+
"vscode-db2i.syntax.checkOnEdit": {
213+
"type": "boolean",
214+
"description": "Whether the syntax checker should run automatically when the document is edited",
215+
"default": true
216+
},
217+
"vscode-db2i.syntax.checkInterval": {
218+
"type": "number",
219+
"description": "Time between editing (ms) and sending a request to syntax check on the server",
220+
"default": 1500
221+
},
222+
"vscode-db2i.syntax.showWarnings": {
223+
"type": "boolean",
224+
"description": "Whether SQL syntax warnings should show in the editor",
225+
"default": false
226+
}
227+
}
202228
}
203229
],
204230
"viewsContainers": {
@@ -332,6 +358,11 @@
332358
"title": "Get Indexes",
333359
"category": "Db2 for i"
334360
},
361+
{
362+
"command": "vscode-db2i.getAuthorities",
363+
"title": "Get Authorities",
364+
"category": "Db2 for i"
365+
},
335366
{
336367
"command": "vscode-db2i.clearData",
337368
"title": "Clear...",
@@ -655,6 +686,13 @@
655686
"title": "Export",
656687
"category": "IBM i Notebooks",
657688
"icon": "$(save)"
689+
},
690+
{
691+
"command": "vscode-db2i.syntax.checkDocument",
692+
"title": "Check SQL syntax",
693+
"category": "Db2 for IBM i",
694+
"enablement": "code-for-ibmi:connected == true && vscode-db2i:jobManager.hasJob && vscode-db2i:statementCanCancel != true && vscode-db2i.syntax.checkerAvailable == true && vscode-db2i.syntax.checkerRunning != true",
695+
"icon": "$(check-all)"
658696
}
659697
],
660698
"menus": {
@@ -920,6 +958,11 @@
920958
"when": "viewItem == table || viewItem == schema",
921959
"group": "db2workWith@3"
922960
},
961+
{
962+
"command": "vscode-db2i.getAuthorities",
963+
"when": "viewItem == table || viewItem == view || viewItem == alias || viewItem == constraint || viewItem == function || viewItem == variable || viewItem == index || viewItem == procedure || viewItem == sequence || viewItem == package || viewItem == trigger || viewItem == type",
964+
"group": "db2workWith@4"
965+
},
923966
{
924967
"command": "vscode-db2i.clearData",
925968
"when": "viewItem == table",
@@ -1040,6 +1083,11 @@
10401083
"command": "vscode-db2i.statement.cancel",
10411084
"when": "editorLangId == sql && vscode-db2i:statementCanCancel == true",
10421085
"group": "navigation@1"
1086+
},
1087+
{
1088+
"command": "vscode-db2i.syntax.checkDocument",
1089+
"when": "editorLangId == sql && code-for-ibmi:connected == true",
1090+
"group": "navigation"
10431091
}
10441092
],
10451093
"sql/editor/context": [
@@ -1264,9 +1312,9 @@
12641312
},
12651313
"devDependencies": {
12661314
"@continuedev/core": "^1.0.13",
1267-
"@halcyontech/vscode-ibmi-types": "^2.0.0",
1315+
"@halcyontech/vscode-ibmi-types": "^2.14.0",
12681316
"@types/glob": "^7.1.3",
1269-
"@types/node": "14.x",
1317+
"@types/node": "18.x",
12701318
"@types/vscode": "^1.95.0",
12711319
"esbuild-loader": "^3.0.1",
12721320
"eslint": "^7.32.0",
@@ -1275,7 +1323,7 @@
12751323
"raw-loader": "^4.0.2",
12761324
"ts-loader": "^9.3.1",
12771325
"typescript": "^4.3.2",
1278-
"vitest": "^0.33.0",
1326+
"vitest": "^2.1.8",
12791327
"vscd": "^1.1.0",
12801328
"vscode-test": "^1.5.2",
12811329
"webpack": "^5.91.0",

snippets/create.code-snippets

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
"prefix": "create procedure",
44
"body": [
55
"create or replace procedure ${1:procedure_name}($2)",
6+
" program type sub modifies sql data",
67
" set option usrprf = *user, dynusrprf = *user, commit = *none",
7-
" program type sub",
8-
" modifies sql data",
98
"begin",
109
" $0",
1110
"end;"

src/base.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,29 @@
11
import { CodeForIBMi } from "@halcyontech/vscode-ibmi-types";
22
import Instance from "@halcyontech/vscode-ibmi-types/api/Instance";
33
import {CustomUI} from "@halcyontech/vscode-ibmi-types/api/CustomUI";
4-
import { Extension, extensions } from "vscode";
4+
import { Extension, ExtensionContext, extensions } from "vscode";
5+
import { SQLStatementChecker } from "./connection/syntaxChecker";
56

67
let baseExtension: Extension<CodeForIBMi>|undefined;
78

8-
export function loadBase(): CodeForIBMi|undefined {
9+
export function loadBase(context: ExtensionContext): CodeForIBMi|undefined {
910
if (!baseExtension) {
1011
baseExtension = (extensions ? extensions.getExtension(`halcyontechltd.code-for-ibmi`) : undefined);
12+
13+
if (baseExtension) {
14+
baseExtension.activate().then(() => {
15+
baseExtension.exports.componentRegistry.registerComponent(context, new SQLStatementChecker());
16+
});
17+
}
1118
}
1219

1320
return (baseExtension && baseExtension.isActive && baseExtension.exports ? baseExtension.exports : undefined);
1421
}
1522

23+
export function getBase(): CodeForIBMi|undefined {
24+
return (baseExtension && baseExtension.isActive && baseExtension.exports ? baseExtension.exports : undefined);
25+
}
26+
1627
export function getInstance(): Instance|undefined {
1728
return (baseExtension && baseExtension.isActive && baseExtension.exports ? baseExtension.exports.instance : undefined);
1829
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
export const VALIDATOR_NAME = `VALIDATE_STATEMENT`;
2+
export const WRAPPER_NAME = `CHECKSTMTWRAPPED`;
3+
export const VALID_STATEMENT_LENGTH = 32740;
4+
export const MAX_STATEMENT_COUNT = 200;
5+
6+
export function getValidatorSource(schema: string, version: number) {
7+
return /*sql*/`
8+
create or replace procedure ${schema}.${WRAPPER_NAME} (
9+
IN statementText char(${VALID_STATEMENT_LENGTH}) FOR SBCS DATA,
10+
IN statementLength int,
11+
IN recordsProvided int,
12+
IN statementLanguage char(10),
13+
IN options char(24),
14+
OUT statementInfo char(1000),
15+
IN statementInfoLength int,
16+
OUT recordsProcessed int,
17+
OUT errorCode char(1000)
18+
)
19+
LANGUAGE RPGLE
20+
NOT DETERMINISTIC
21+
MODIFIES SQL DATA
22+
EXTERNAL NAME QSYS/QSQCHKS
23+
PARAMETER STYLE GENERAL;
24+
25+
comment on procedure ${schema}/${WRAPPER_NAME} is '${version} - QSQCHKS Wrapper';
26+
27+
create or replace function ${schema}.${VALIDATOR_NAME}(statementText char(${VALID_STATEMENT_LENGTH}) FOR SBCS DATA) --todo: support 1208 parms
28+
returns table (
29+
messageFileName char(10),
30+
messageFileLibrary char(10),
31+
numberOfStatementsBack int,
32+
curStmtLength int,
33+
errorFirstRecordNumber int,
34+
errorFirstColumnNumber int,
35+
errorLastRecordNumber int,
36+
errorLastColumnNumber int,
37+
errorSyntaxRecordNumber int,
38+
errorSyntaxColumnNumber int,
39+
errorSQLMessageID char(7),
40+
errorSQLSTATE char(5),
41+
errorReplacementText char(1000),
42+
messageText char(132)
43+
)
44+
modifies sql data
45+
begin
46+
-- Variables required for parameters
47+
declare stmtLength int default 0;
48+
declare recordsProvided int default 1;
49+
declare statementLanguage char(10) default '*NONE';
50+
declare options char(24) default '000000000000000000000000';
51+
declare statementInfo char(1000) for bit data default '';
52+
declare statementInfoLength int default 1000;
53+
declare recordsProcessed int default 0;
54+
declare errorCode char(1000) default '';
55+
--
56+
57+
-- Variables required for parsing the error list
58+
declare messageFileName char(10);
59+
declare messageFileLibrary char(10);
60+
declare numberOfStatementsBack int default 0;
61+
declare currentStatementIndex int default 0;
62+
63+
-- Variables for each error
64+
declare errorOffset int default 25;
65+
declare curStmtLength int default 0;
66+
declare errorFirstRecordNumber int default 0;
67+
declare errorFirstColumnNumber int default 0;
68+
declare errorLastRecordNumber int default 0;
69+
declare errorLastColumnNumber int default 0;
70+
declare errorSyntaxRecordNumber int default 0;
71+
declare errorSyntaxColumnNumber int default 0;
72+
declare errorSQLMessageID char(7) default '';
73+
declare errorSQLSTATE char(5) default '';
74+
declare errorRepLen int default 0;
75+
declare errorReplacementText char(1000) default '';
76+
declare messageText char(132) default '';
77+
78+
set stmtLength = length(rtrim(statementText));
79+
set options = x'00000001' concat x'00000001' concat x'0000000A' concat '*NONE '; --No naming convention
80+
-- set options = x'00000001' concat x'00000008' concat x'00000004' concat x'000004B0'; -- ccsid
81+
82+
call ${schema}.${WRAPPER_NAME}( statementText, stmtLength, recordsProvided, statementLanguage, options, statementInfo, statementInfoLength, recordsProcessed, errorCode);
83+
84+
-- set ${schema}.outlog = statementInfo;
85+
-- set ${schema}.outlog = substr(statementInfo, 21, 4);
86+
87+
-- Parse the output
88+
set messageFileName = rtrim(substr(statementInfo, 1, 10));
89+
set messageFileLibrary = rtrim(substr(statementInfo, 11, 10));
90+
set numberOfStatementsBack = interpret(substr(statementInfo, 21, 4) as int);
91+
set errorOffset = 25;
92+
93+
while currentStatementIndex < numberOfStatementsBack do
94+
set curStmtLength = interpret(substr(statementInfo, errorOffset, 4) as int);
95+
set errorFirstRecordNumber = interpret(substr(statementInfo, errorOffset + 4, 4) as int);
96+
set errorFirstColumnNumber = interpret(substr(statementInfo, errorOffset + 8, 4) as int);
97+
set errorLastRecordNumber = interpret(substr(statementInfo, errorOffset + 12, 4) as int);
98+
set errorLastColumnNumber = interpret(substr(statementInfo, errorOffset + 16, 4) as int);
99+
set errorSyntaxRecordNumber = interpret(substr(statementInfo, errorOffset + 20, 4) as int);
100+
set errorSyntaxColumnNumber = interpret(substr(statementInfo, errorOffset + 24, 4) as int);
101+
set errorSQLMessageID = rtrim(substr(statementInfo, errorOffset + 28, 7));
102+
set errorSQLSTATE = rtrim(substr(statementInfo, errorOffset + 35, 5));
103+
set errorRepLen = interpret(substr(statementInfo, errorOffset + 40, 4) as int);
104+
set errorReplacementText = rtrim(substr(statementInfo, errorOffset + 44, errorRepLen));
105+
106+
set errorOffset = errorOffset + 44 + errorRepLen;
107+
108+
set currentStatementIndex = currentStatementIndex + 1;
109+
110+
select message_text
111+
into messageText
112+
from table(qsys2.message_file_data(messageFileLibrary, messageFileName))
113+
where message_id = errorSQLMessageID;
114+
115+
pipe (
116+
messageFileName,
117+
messageFileLibrary,
118+
numberOfStatementsBack,
119+
curStmtLength,
120+
errorFirstRecordNumber,
121+
errorFirstColumnNumber,
122+
errorLastRecordNumber,
123+
errorLastColumnNumber,
124+
errorSyntaxRecordNumber,
125+
errorSyntaxColumnNumber,
126+
errorSQLMessageID,
127+
errorSQLSTATE,
128+
errorReplacementText,
129+
messageText
130+
);
131+
end while;
132+
133+
return;
134+
end;
135+
136+
comment on function ${schema}/${VALIDATOR_NAME} is '${version} - SQL Syntax Checker';
137+
138+
--select *
139+
--from table(${schema}.validate_statement('select from sample.employee order by a')) x;
140+
--
141+
--select * from table(qsys2.message_file_data('QSYS', 'QSQLMSG'));
142+
--
143+
--values hex(substr(${schema}.outlog, 21, 4));
144+
--values interpret(hex(substr(${schema}.outlog, 21, 4)) as int);
145+
--values hex(1) concat hex(1) concat hex(10) concat '*NONE ';
146+
--values length(x'000004B8');
147+
--values hex(1200);
148+
`;
149+
}

0 commit comments

Comments
 (0)