Skip to content

Commit dc300c7

Browse files
authored
Merge branch 'codefori:main' into fix/token_tests
2 parents 8e0d587 + 8494008 commit dc300c7

File tree

14 files changed

+192
-75
lines changed

14 files changed

+192
-75
lines changed

.github/workflows/webpack_ci.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
cat $GITHUB_ENV
3636
3737
- name: Upload dist artifacts
38-
uses: actions/upload-artifact@v3
38+
uses: actions/upload-artifact@v4
3939
with:
4040
name: test_vsix
4141
path: ${{env.vsix_name}}
@@ -70,4 +70,4 @@ jobs:
7070
👋 A new build is available for this PR based on ${{ github.event.pull_request.head.sha }}.
7171
7272
* [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)
73+
* [Read more about how to test](https://github.com/codefori/vscode-db2i/blob/master/.github/pr_testing_template.md)

package-lock.json

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

package.json

Lines changed: 3 additions & 3 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.8.0",
5+
"version": "1.8.3",
66
"engines": {
77
"vscode": "^1.95.0"
88
},
@@ -970,7 +970,7 @@
970970
},
971971
{
972972
"command": "vscode-db2i.getObjectLocks",
973-
"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",
973+
"when": "viewItem == table || viewItem == view || viewItem == alias || viewItem == function || viewItem == variable || viewItem == index || viewItem == procedure || viewItem == sequence || viewItem == package || viewItem == trigger || viewItem == type",
974974
"group": "db2workWith@5"
975975
},
976976
{
@@ -1322,7 +1322,7 @@
13221322
},
13231323
"devDependencies": {
13241324
"@continuedev/core": "^1.0.13",
1325-
"@halcyontech/vscode-ibmi-types": "^2.14.0",
1325+
"@halcyontech/vscode-ibmi-types": "^2.14.5",
13261326
"@types/glob": "^7.1.3",
13271327
"@types/node": "18.x",
13281328
"@types/vscode": "^1.95.0",

src/aiProviders/continue/continueContextProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export class db2ContextProvider implements IContextProvider {
8787
const result = await selected.job
8888
.query<SelfCodeNode>(content)
8989
.execute(10000);
90-
if (result.success) {
90+
if (result.success && result.data) {
9191
const data: SelfCodeNode[] = result.data.map((row) => ({
9292
...row,
9393
INITIAL_STACK: this.tryParseJson(row),

src/connection/syntaxChecker/index.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,18 @@ export class SQLStatementChecker implements IBMiComponent {
4242
private readonly functionName = VALIDATOR_NAME;
4343
private readonly currentVersion = 5;
4444

45-
private installedVersion = 1;
4645
private library = "";
4746

4847
static get(): SQLStatementChecker|undefined {
4948
return getInstance()?.getConnection()?.getComponent<SQLStatementChecker>(SQLStatementChecker.ID);
5049
}
5150

5251
reset() {
53-
this.installedVersion = 0;
5452
this.library = "";
5553
}
5654

5755
getIdentification(): ComponentIdentification {
58-
return { name: SQLStatementChecker.ID, version: this.installedVersion };
56+
return { name: SQLStatementChecker.ID, version: this.currentVersion };
5957
}
6058

6159
static async getVersionOf(connection: IBMi, schema: string, name: string) {
@@ -79,8 +77,8 @@ export class SQLStatementChecker implements IBMiComponent {
7977
return `NeedsUpdate`;
8078
}
8179

82-
this.installedVersion = await SQLStatementChecker.getVersionOf(connection, this.library, this.functionName);
83-
if (this.installedVersion < this.currentVersion) {
80+
const installedVersion = await SQLStatementChecker.getVersionOf(connection, this.library, this.functionName);
81+
if (installedVersion < this.currentVersion) {
8482
return `NeedsUpdate`;
8583
}
8684

src/database/schemas.ts

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

2+
import path from "path";
23
import { getInstance } from "../base";
3-
44
import { JobManager } from "../config";
55

66
export type SQLType = "schemas" | "tables" | "views" | "aliases" | "constraints" | "functions" | "variables" | "indexes" | "procedures" | "sequences" | "packages" | "triggers" | "types" | "logicals";
@@ -220,13 +220,27 @@ export default class Schemas {
220220
* @param object Not user input
221221
*/
222222
static async generateSQL(schema: string, object: string, internalType: string): Promise<string> {
223-
const lines = await JobManager.runSQL<{ SRCDTA: string }>([
224-
`CALL QSYS2.GENERATE_SQL(?, ?, ?, CREATE_OR_REPLACE_OPTION => '1', PRIVILEGES_OPTION => '0')`
225-
].join(` `), { parameters: [object, schema, internalType] });
226-
227-
const generatedStatement = lines.map(line => line.SRCDTA).join(`\n`);
228-
229-
return generatedStatement;
223+
const instance = getInstance();
224+
const connection = instance.getConnection();
225+
226+
const result = await connection.withTempDirectory<string>(async (tempDir) => {
227+
const tempFilePath = path.posix.join(tempDir, `generatedSql.sql`);
228+
await JobManager.runSQL<{ SRCDTA: string }>([
229+
`CALL QSYS2.GENERATE_SQL( DATABASE_OBJECT_NAME => ?, DATABASE_OBJECT_LIBRARY_NAME => ?, DATABASE_OBJECT_TYPE => ?
230+
, CREATE_OR_REPLACE_OPTION => '1', PRIVILEGES_OPTION => '0'
231+
, DATABASE_SOURCE_FILE_NAME => '*STMF'
232+
, STATEMENT_FORMATTING_OPTION => '0'
233+
, SOURCE_STREAM_FILE => '${tempFilePath}'
234+
, SOURCE_STREAM_FILE_END_OF_LINE => 'LF'
235+
, SOURCE_STREAM_FILE_CCSID => 1208 )`
236+
].join(` `), { parameters: [object, schema, internalType] });
237+
238+
// TODO: eventually .content -> .getContent(), it's not available yet
239+
const contents = (await connection.content.downloadStreamfileRaw(tempFilePath)).toString();
240+
return contents;
241+
})
242+
243+
return result;
230244
}
231245

232246
static async deleteObject(schema: string, name: string, type: string): Promise<void> {

src/language/providers/hoverProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ function addSymbol(base: MarkdownString, symbol: LookupResult) {
181181
else if ('COLUMN_NAME' in symbol) {
182182
base.appendCodeblock(prepareParamType(symbol) + `\n`, `sql`);
183183
}
184-
else if ('name' in symbol) {
184+
else if ('name' in symbol && symbol.text) {
185185
addList(base, [
186186
`**Description:** ${symbol.text}`,
187187
]);

src/language/sql/statement.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,8 @@ export default class Statement {
302302

303303
for (const parameter of parameters) {
304304
// If the first token is the parm type, then the name follows
305+
if (tokenIs(parameter[0], `keyword`)) continue;
306+
305307
let nameIndex = tokenIs(parameter[0], `parmType`) ? 1 : 0;
306308
const name = parameter[nameIndex].value!;
307309
// Include parmType if it is provided

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

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,96 @@ parserScenarios(`Object references`, ({newDoc}) => {
945945
expect(refs[1].object.schema).toBe(`LIB`);
946946
});
947947

948+
test('CREATE TABLE: routine parametes with primary key', () => {
949+
const content = [
950+
`-- Employee Master`,
951+
`-- Generated on: 11/03/21 14:32:20`,
952+
`CREATE OR REPLACE TABLE super_long_dept_name FOR SYSTEM NAME DEPT (`,
953+
`-- SQL150B 10 REUSEDLT(*NO) in table EMPMST in PAYROLL1 ignored.`,
954+
` COL_B CHAR(1) CCSID 37 NOT NULL DEFAULT '' ,`,
955+
` PRIMARY KEY( COL_B ) );`,
956+
].join(`\n`);
957+
958+
const document = newDoc(content);
959+
const groups = document.getStatementGroups();
960+
961+
expect(groups.length).toBe(1);
962+
const createStatement = groups[0].statements[0];
963+
964+
expect(createStatement.type).toBe(StatementType.Create);
965+
966+
const parms = createStatement.getRoutineParameters();
967+
expect(parms.length).toBe(1);
968+
expect(parms[0].alias).toBe(`COL_B`);
969+
});
970+
971+
test('CREATE TABLE: simple routine parametes test', () => {
972+
const content = [
973+
`CREATE TABLE ROSSITER.INVENTORY`,
974+
`(PARTNO SMALLINT NOT NULL,`,
975+
` DESCR VARCHAR(24),`,
976+
` QONHAND INT)`,
977+
].join(`\n`);
978+
979+
const document = newDoc(content);
980+
const groups = document.getStatementGroups();
981+
982+
expect(groups.length).toBe(1);
983+
const createStatement = groups[0].statements[0];
984+
985+
expect(createStatement.type).toBe(StatementType.Create);
986+
987+
const parms = createStatement.getRoutineParameters();
988+
expect(parms.length).toBe(3);
989+
990+
expect(parms[0].alias).toBe(`PARTNO`);
991+
expect(parms[0].createType).toBe(`SMALLINT NOT NULL`);
992+
993+
expect(parms[1].alias).toBe(`DESCR`);
994+
expect(parms[1].createType).toBe(`VARCHAR(24)`);
995+
996+
expect(parms[2].alias).toBe(`QONHAND`);
997+
expect(parms[2].createType).toBe(`INT`);
998+
});
999+
1000+
test('CREATE TABLE: generated types', () => {
1001+
const content = [
1002+
`CREATE TABLE policy_info`,
1003+
` (policy_id CHAR(10) NOT NULL,`,
1004+
` coverage INT NOT NULL,`,
1005+
` sys_start TIMESTAMP(12) NOT NULL GENERATED ALWAYS AS ROW BEGIN,`,
1006+
` sys_end TIMESTAMP(12) NOT NULL GENERATED ALWAYS AS ROW END,`,
1007+
` create_id TIMESTAMP(12) GENERATED ALWAYS AS TRANSACTION START ID,`,
1008+
` PERIOD SYSTEM_TIME(sys_start,sys_end));`,
1009+
].join(`\n`);
1010+
1011+
const document = newDoc(content);
1012+
const groups = document.getStatementGroups();
1013+
1014+
expect(groups.length).toBe(1);
1015+
const createStatement = groups[0].statements[0];
1016+
1017+
expect(createStatement.type).toBe(StatementType.Create);
1018+
1019+
const parms = createStatement.getRoutineParameters();
1020+
expect(parms.length).toBe(5);
1021+
1022+
expect(parms[0].alias).toBe(`policy_id`);
1023+
expect(parms[0].createType).toBe(`CHAR(10) NOT NULL`);
1024+
1025+
expect(parms[1].alias).toBe(`coverage`);
1026+
expect(parms[1].createType).toBe(`INT NOT NULL`);
1027+
1028+
expect(parms[2].alias).toBe(`sys_start`);
1029+
expect(parms[2].createType).toBe(`TIMESTAMP(12) NOT NULL GENERATED ALWAYS AS ROW BEGIN`);
1030+
1031+
expect(parms[3].alias).toBe(`sys_end`);
1032+
expect(parms[3].createType).toBe(`TIMESTAMP(12) NOT NULL GENERATED ALWAYS AS ROW END`);
1033+
1034+
expect(parms[4].alias).toBe(`create_id`);
1035+
expect(parms[4].createType).toBe(`TIMESTAMP(12) GENERATED ALWAYS AS TRANSACTION START ID`);
1036+
})
1037+
9481038
test(`DECLARE VARIABLE`, () => {
9491039
const document = newDoc(`declare watsonx_response Varchar(10000) CCSID 1208;`);
9501040
const groups = document.getStatementGroups();

src/language/sql/tokens.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export default class SQLTokeniser {
8282
{
8383
name: `KEYWORD`,
8484
match: [{ type: `word`, match: (value: string) => {
85-
return [`AS`, `FOR`, `OR`, `REPLACE`, `BEGIN`, `DO`, `THEN`, `LOOP`, `END`, `CURSOR`, `DEFAULT`, `HANDLER`, `REFERENCES`, `ON`, `UNIQUE`, `SPECIFIC`, `EXTERNAL`, `ELSE`].includes(value.toUpperCase());
85+
return [`AS`, `FOR`, `OR`, `REPLACE`, `BEGIN`, `DO`, `THEN`, `LOOP`, `END`, `CURSOR`, `DEFAULT`, `HANDLER`, `REFERENCES`, `ON`, `UNIQUE`, `PRIMARY`, `CONSTRAINT`, `SPECIFIC`, `PERIOD`, `RCDFMT`, `EXTERNAL`, `ELSE`].includes(value.toUpperCase());
8686
} }],
8787
becomes: `keyword`,
8888
},

0 commit comments

Comments
 (0)