Skip to content

Commit de78996

Browse files
authored
Merge branch 'codefori:main' into feature/rpg-codegen
2 parents 3d3976b + 4d5705b commit de78996

File tree

19 files changed

+367
-85
lines changed

19 files changed

+367
-85
lines changed

package.json

Lines changed: 27 additions & 2 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.10.1",
5+
"version": "1.11.0",
66
"engines": {
77
"vscode": "^1.95.0"
88
},
@@ -211,7 +211,7 @@
211211
},
212212
{
213213
"id": "vscode-db2i.syntax",
214-
"title": "SQL Syntax Checking",
214+
"title": "SQL Syntax Options",
215215
"properties": {
216216
"vscode-db2i.syntax.checkOnOpen": {
217217
"type": "boolean",
@@ -232,6 +232,11 @@
232232
"type": "boolean",
233233
"description": "Whether SQL syntax warnings should show in the editor",
234234
"default": false
235+
},
236+
"vscode-db2i.syntax.useSystemNames": {
237+
"type": "boolean",
238+
"description": "Whether to use system names for columns in the content assist",
239+
"default": false
235240
}
236241
}
237242
}
@@ -377,6 +382,11 @@
377382
"title": "Get Object Locks",
378383
"category": "Db2 for i"
379384
},
385+
{
386+
"command": "vscode-db2i.getRecordLocks",
387+
"title": "Get Record Locks",
388+
"category": "Db2 for i"
389+
},
380390
{
381391
"command": "vscode-db2i.clearData",
382392
"title": "Clear...",
@@ -424,6 +434,11 @@
424434
"category": "Db2 for i",
425435
"icon": "$(search)"
426436
},
437+
{
438+
"command": "vscode-db2i.viewPermissions",
439+
"title": "View permissions",
440+
"category": "Db2 for i"
441+
},
427442
{
428443
"command": "vscode-db2i.runEditorStatement",
429444
"title": "Run statement",
@@ -997,6 +1012,11 @@
9971012
"when": "viewItem == table || viewItem == view || viewItem == alias || viewItem == function || viewItem == variable || viewItem == index || viewItem == procedure || viewItem == sequence || viewItem == package || viewItem == trigger || viewItem == type",
9981013
"group": "db2workWith@5"
9991014
},
1015+
{
1016+
"command": "vscode-db2i.getRecordLocks",
1017+
"when": "viewItem == table",
1018+
"group": "db2workWith@6"
1019+
},
10001020
{
10011021
"command": "vscode-db2i.clearData",
10021022
"when": "viewItem == table",
@@ -1017,6 +1037,11 @@
10171037
"when": "viewItem == table || viewItem == view || viewItem == index",
10181038
"group": "db2data@4"
10191039
},
1040+
{
1041+
"command": "vscode-db2i.viewPermissions",
1042+
"when": "viewItem == table || viewItem == view || viewItem == alias || viewItem == function || viewItem == variable || viewItem == index || viewItem == procedure || viewItem == sequence || viewItem == package || viewItem == trigger || viewItem == type",
1043+
"group": "db2data@5"
1044+
},
10201045
{
10211046
"command": "vscode-db2i.advisedIndexes",
10221047
"when": "viewItem == table || viewItem == schema",

src/connection/sqlJob.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export class OldSQLJob extends SQLJob {
106106
getStatus(): JobStatus {
107107
const currentListenerCount = this.responseEmitter.eventNames().length;
108108

109-
return this.channel && currentListenerCount > 0 ? JobStatus.BUSY : this.status;
109+
return this.channel && currentListenerCount > 0 ? JobStatus.BUSY : this.status as JobStatus;
110110
}
111111

112112
async connect(): Promise<ConnectionResult> {

src/database/schemas.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -356,18 +356,12 @@ export default class Schemas {
356356

357357
let query: string;
358358

359-
if (selects.length > 1) {
360-
if (details.sort) {
361-
query = `with results as (${selects.join(
362-
" UNION ALL "
363-
)}) select * from results Order by QSYS2.DELIMIT_NAME(NAME) asc`;
364-
} else {
365-
query = selects.join(` UNION ALL `);
366-
}
367-
359+
if (details.sort) {
360+
query = `with results as (${selects.join(
361+
" UNION ALL "
362+
)}) select * from results Order by QSYS2.DELIMIT_NAME(NAME) asc`;
368363
} else {
369-
// TODO: sort single
370-
query = selects[0];
364+
query = selects.join(` UNION ALL `);
371365
}
372366

373367
const objects: any[] = await JobManager.runSQL(

src/database/table.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export default class Table {
1515
`SELECT `,
1616
` column.TABLE_SCHEMA,`,
1717
` column.TABLE_NAME,`,
18+
` column.SYSTEM_COLUMN_NAME,`,
1819
` column.COLUMN_NAME,`,
1920
` key.CONSTRAINT_NAME,`,
2021
` column.DATA_TYPE, `,
@@ -70,8 +71,8 @@ export default class Table {
7071
}
7172

7273
static async isPartitioned(schema: string, name: string): Promise<boolean> {
73-
const sql = `select table_name, partitioned_table from qsys2.sysfiles where table_schema = ? and table_name = ? and partitioned_table is not null and partitioned_table = 'YES'`;
74-
const parameters = [schema, name];
74+
const sql = `select table_name, partitioned_table from qsys2.sysfiles where ((table_schema = ? and table_name = ?) or (system_table_schema = ? and system_table_name = ?)) and partitioned_table is not null and partitioned_table = 'YES'`;
75+
const parameters = [schema, name, schema, name];
7576

7677
const result = await JobManager.runSQL(sql, {parameters});
7778
return result.length > 0;

src/language/providers/completionProvider.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { CTEReference, ClauseType, ObjectRef, StatementType } from "../sql/types
1010
import { CallableType } from "../../database/callable";
1111
import { prepareParamType, createCompletionItem, getParmAttributes } from "./logic/completion";
1212
import { isCallableType, getCallableParameters } from "./logic/callable";
13-
import { localAssistIsEnabled, remoteAssistIsEnabled } from "./logic/available";
13+
import { localAssistIsEnabled, remoteAssistIsEnabled, useSystemNames } from "./logic/available";
1414
import { DbCache } from "./logic/cache";
1515
import { getSqlDocument } from "./logic/parse";
1616
import { TableColumn, BasicSQLObject } from "../../types";
@@ -57,9 +57,9 @@ const completionTypes: { [index: string]: CompletionType } = {
5757

5858

5959

60-
function getColumnAttributes(column: TableColumn): string {
60+
function getColumnAttributes(column: TableColumn, useSystemName: boolean): string {
6161
const lines: string[] = [
62-
`Column: ${column.COLUMN_NAME}`,
62+
`Column: ${useSystemName ? column.SYSTEM_COLUMN_NAME : column.COLUMN_NAME}`,
6363
`Type: ${prepareParamType(column)}`,
6464
`HAS_DEFAULT: ${column.HAS_DEFAULT}`,
6565
`IS_IDENTITY: ${column.IS_IDENTITY}`,
@@ -85,7 +85,8 @@ function getAllColumns(name: string, schema: string, items: CompletionItem[]) {
8585
async function getObjectColumns(
8686
schema: string,
8787
name: string,
88-
isUDTF = false
88+
isUDTF: boolean,
89+
useSystemNamesInColumn: boolean,
8990
): Promise<CompletionItem[]> {
9091

9192
let completionItems: CompletionItem[];
@@ -121,9 +122,9 @@ async function getObjectColumns(
121122

122123
completionItems = columns.map((i) =>
123124
createCompletionItem(
124-
Statement.prettyName(i.COLUMN_NAME),
125+
Statement.prettyName(useSystemNamesInColumn ? i.SYSTEM_COLUMN_NAME : i.COLUMN_NAME),
125126
CompletionItemKind.Field,
126-
getColumnAttributes(i),
127+
getColumnAttributes(i, useSystemNamesInColumn),
127128
`Schema: ${schema}\nTable: ${name}\n`,
128129
`a@objectcolumn`
129130
)
@@ -268,7 +269,8 @@ async function getCompletionItemsForTriggerDot(
268269
const completionItems = await getObjectColumns(
269270
curRefIdentifier.object.schema,
270271
curRefIdentifier.object.name,
271-
curRefIdentifier.isUDTF
272+
curRefIdentifier.isUDTF,
273+
useSystemNames()
272274
);
273275

274276
list.push(...completionItems);
@@ -346,7 +348,7 @@ async function getCompletionItemsForRefs(currentStatement: LanguageStatement.def
346348
// Fetch all the columns for tables that have references in the statement
347349
const tableItemPromises = objectRefs.map((ref) =>
348350
ref.object.name && ref.object.schema
349-
? getObjectColumns(ref.object.schema, ref.object.name, ref.isUDTF)
351+
? getObjectColumns(ref.object.schema, ref.object.name, ref.isUDTF, useSystemNames())
350352
: Promise.resolve([])
351353
);
352354
const results = await Promise.allSettled(tableItemPromises);

src/language/providers/contributes.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"configuration": [
44
{
55
"id": "vscode-db2i.syntax",
6-
"title": "SQL Syntax Checking",
6+
"title": "SQL Syntax Options",
77
"properties": {
88
"vscode-db2i.syntax.checkOnOpen": {
99
"type": "boolean",
@@ -24,6 +24,11 @@
2424
"type": "boolean",
2525
"description": "Whether SQL syntax warnings should show in the editor",
2626
"default": false
27+
},
28+
"vscode-db2i.syntax.useSystemNames": {
29+
"type": "boolean",
30+
"description": "Whether to use system names for columns in the content assist",
31+
"default": false
2732
}
2833
}
2934
}

src/language/providers/hoverProvider.ts

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import Statement from "../../database/statement";
66
import { getParmAttributes, prepareParamType } from "./logic/completion";
77
import { StatementType } from "../sql/types";
88
import { remoteAssistIsEnabled } from "./logic/available";
9-
import { getPositionData } from "./logic/callable";
109
import { CallableSignature } from "../../database/callable";
10+
import { getPositionData } from "../sql/document";
1111

1212
// =================================
1313
// We need to open provider to exist so symbols can be cached for hover support when opening files
@@ -87,16 +87,29 @@ export const hoverProvider = languages.registerHoverProvider({ language: `sql` }
8787

8888
if (result) {
8989
if ('routine' in result) {
90-
const routineOffset = ref.tokens[ref.tokens.length-1].range.end+1;
91-
const callableRef = statementAt.getCallableDetail(routineOffset, false);
92-
if (callableRef) {
93-
const { currentCount } = getPositionData(callableRef, routineOffset);
94-
const signatures = await DbCache.getCachedSignatures(callableRef.parentRef.object.schema, callableRef.parentRef.object.name);
95-
const possibleSignatures = signatures.filter((s) => s.parms.length >= currentCount).sort((a, b) => a.parms.length - b.parms.length);
96-
const signature = possibleSignatures.find((signature) => currentCount <= signature.parms.length);
97-
if (signature) {
98-
addRoutineMd(md, signature, result);
99-
}
90+
let signatures: CallableSignature[];
91+
let signature: CallableSignature | undefined;
92+
93+
const lastToken = ref.tokens[ref.tokens.length-1];
94+
95+
if (lastToken.type === `closebracket`) {
96+
let routineOffset: number = lastToken.range.start-1;
97+
const callableRef = statementAt.getCallableDetail(routineOffset, false);
98+
if (callableRef) {
99+
const { currentCount } = getPositionData(callableRef, routineOffset);
100+
signatures = await DbCache.getCachedSignatures(callableRef.parentRef.object.schema, callableRef.parentRef.object.name);
101+
const possibleSignatures = signatures.filter((s) => s.parms.length >= currentCount).sort((a, b) => a.parms.length - b.parms.length);
102+
signature = possibleSignatures.find((signature) => currentCount <= signature.parms.length);
103+
}
104+
}
105+
106+
if (!signature) {
107+
signatures = await DbCache.getCachedSignatures(result.routine.schema, result.routine.name);
108+
signature = signatures[0];
109+
}
110+
111+
if (signature) {
112+
addRoutineMd(md, signature, result);
100113
}
101114
} else {
102115
addSymbol(md, result);

src/language/providers/logic/available.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ import { env } from "process";
33
import { ServerComponent } from "../../../connection/serverComponent";
44
import { JobManager } from "../../../config";
55
import { JobInfo } from "../../../connection/manager";
6+
import Configuration from "../../../configuration";
7+
8+
export function useSystemNames() {
9+
return Configuration.get<boolean>(`syntax.useSystemNames`) || false;
10+
}
611

712
export function localAssistIsEnabled() {
813
return (env.DB2I_DISABLE_CA !== `true`);

src/language/providers/logic/callable.ts

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Statement from "../../../database/statement";
55
import { createCompletionItem, getParmAttributes } from "./completion";
66
import { DbCache } from "./cache";
77
import { SQLParm } from "../../../types";
8+
import { getPositionData } from "../../sql/document";
89

910
/**
1011
* Checks if the ref exists as a procedure or function. Then,
@@ -117,27 +118,4 @@ export function getCallableParameters(ref: CallableReference, offset: number): C
117118
});
118119
}
119120
return [];
120-
}
121-
122-
export function getPositionData(ref: CallableReference, offset: number) {
123-
const paramCommas = ref.tokens.filter(token => token.type === `comma`);
124-
125-
let currentParm = paramCommas.findIndex(t => offset < t.range.end);
126-
127-
if (currentParm === -1) {
128-
currentParm = paramCommas.length;
129-
}
130-
131-
const firstNamedPipe = ref.tokens.find((token, i) => token.type === `rightpipe`);
132-
let firstNamedParameter = firstNamedPipe ? paramCommas.findIndex((token, i) => token.range.start > firstNamedPipe.range.start) : undefined;
133-
134-
if (firstNamedParameter === -1) {
135-
firstNamedParameter = undefined;
136-
}
137-
138-
return {
139-
currentParm,
140-
currentCount: paramCommas.length + 1,
141-
firstNamedParameter
142-
};
143121
}

src/language/providers/parameterProvider.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { MarkdownString, ParameterInformation, Position, Range, SignatureHelp, SignatureInformation, TextEdit, languages } from "vscode";
22
import Statement from "../../database/statement";
3-
import Document from "../sql/document";
4-
import { getCallableParameters, getPositionData, isCallableType } from "./logic/callable";
5-
import { getParmAttributes, prepareParamType } from "./logic/completion";
3+
import Document, { getPositionData } from "../sql/document";
4+
import { isCallableType } from "./logic/callable";
5+
import { prepareParamType } from "./logic/completion";
66
import { CallableType } from "../../database/callable";
77
import { StatementType } from "../sql/types";
88
import { remoteAssistIsEnabled } from "./logic/available";
@@ -22,7 +22,7 @@ export const signatureProvider = languages.registerSignatureHelpProvider({ langu
2222
const currentStatement = sqlDoc.getStatementByOffset(offset);
2323

2424
if (currentStatement) {
25-
const routineType: CallableType = currentStatement.type === StatementType.Call ? `PROCEDURE` : `FUNCTION`;
25+
const routineType: CallableType = currentStatement. type === StatementType.Call ? `PROCEDURE` : `FUNCTION`;
2626
const callableRef = currentStatement.getCallableDetail(offset, true);
2727
// TODO: check the function actually exists before returning
2828
if (callableRef) {

0 commit comments

Comments
 (0)