Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/self codes #156

Merged
merged 12 commits into from
Dec 1, 2023
29 changes: 29 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,12 @@
"category": "Db2 for i",
"icon": "$(edit)"
},
{
"command": "vscode-db2i.jobManager.editSelfCodes",
"title": "Edit SELF codes",
"category": "Db2 for i",
"icon": "$(bracket-error)"
},
{
"command": "vscode-db2i.jobManager.copyJobId",
"title": "Copy Job Name",
Expand All @@ -311,6 +317,11 @@
"title": "Get Trace Data",
"category": "Db2 for i"
},
{
"command": "vscode-db2i.jobManager.getSelfErrors",
"title": "Get SELF codes Errors",
"category": "Db2 for i"
},
{
"command": "vscode-db2i.jobManager.newConfig",
"title": "Save settings to config",
Expand Down Expand Up @@ -348,6 +359,10 @@
"command": "vscode-db2i.jobManager.editJobProps",
"when": "never"
},
{
"command": "vscode-db2i.jobManager.editSelfCodes",
"when": "never"
},
{
"command": "vscode-db2i.jobManager.copyJobId",
"when": "never"
Expand All @@ -360,6 +375,10 @@
"command": "vscode-db2i.jobManager.enableTracing",
"when": "never"
},
{
"command": "vscode-db2i.jobManager.getSelfErrors",
"when": "never"
},
{
"command": "vscode-db2i.jobManager.getTrace",
"when": "never"
Expand Down Expand Up @@ -519,6 +538,11 @@
"when": "view == jobManager && viewItem == sqlJob",
"group": "inline"
},
{
"command": "vscode-db2i.jobManager.editSelfCodes",
"when": "view == jobManager && viewItem == sqlJob",
"group": "self@2"
},
{
"command": "vscode-db2i.jobManager.copyJobId",
"when": "view == jobManager && viewItem == sqlJob",
Expand All @@ -539,6 +563,11 @@
"when": "view == jobManager && viewItem == sqlJob",
"group": "trace@2"
},
{
"command": "vscode-db2i.jobManager.getSelfErrors",
"when": "view == jobManager && viewItem == sqlJob",
"group": "self@1"
},
{
"command": "vscode-db2i.jobManager.newConfig",
"when": "view == jobManager && viewItem == sqlJob",
Expand Down
11 changes: 11 additions & 0 deletions src/connection/sqlJob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,17 @@ export class SQLJob {
return rpy;
}

async setSelfCodes(codes: string[]) {
const signedCodes: String[] = codes.map(code => [code, `-${code}`]).flat();
try {
const query: string = `SET SYSIBMADM.SELFCODES = SYSIBMADM.VALIDATE_SELF('${signedCodes.join(', ')}')`
await this.query<any>(query).run();
this.options.selfcodes = codes;
} catch (e) {
throw e;
}
}

async setTraceConfig(dest: ServerTraceDest, level: ServerTraceLevel): Promise<SetConfigResult> {
const reqObj = {
id: SQLJob.getNewUniqueId(),
Expand Down
2 changes: 2 additions & 0 deletions src/connection/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ export interface ColumnMetaData {
export type Rows = {[column: string]: string|number|boolean}[];

export interface JDBCOptions {
// selfcodes
selfcodes?: string[];
// Format properties
"naming"?: "sql" | "system";
"date format"?:
Expand Down
2 changes: 2 additions & 0 deletions src/testing/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import { ManagerSuite } from "./manager";
import { JobsSuite } from "./jobs";
import { DatabaseSuite } from "./database";
import { DatabasePerformanceSuite } from "./databasePerformance";
import { SelfCodesTestSuite } from "./selfCodes";

const suites : TestSuite[] = [
JobsSuite,
SelfCodesTestSuite,
ManagerSuite,
DatabaseSuite,
DatabasePerformanceSuite
Expand Down
4 changes: 2 additions & 2 deletions src/testing/jobs.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import assert from "assert";
import { TestSuite } from ".";
import { JobStatus, SQLJob } from "../connection/sqlJob";
import { getInstance } from "../base";
import { Query } from "../connection/query";
import { ServerComponent } from "../connection/serverComponent";
import { JobStatus, SQLJob } from "../connection/sqlJob";
import { ServerTraceDest, ServerTraceLevel } from "../connection/types";
import { Query } from "../connection/query";

export const JobsSuite: TestSuite = {
name: `Connection tests`,
Expand Down
2 changes: 1 addition & 1 deletion src/testing/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,6 @@ export const ManagerSuite: TestSuite = {
assert.strictEqual(JobManager.getSelection().name, runningJobs[0].name);

await JobManager.endAll();
}},
}}
]
}
44 changes: 44 additions & 0 deletions src/testing/selfCodes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import assert from "assert";
import { TestSuite } from ".";
import { ServerComponent } from "../connection/serverComponent";
import { testSelfCodes } from "../views/jobManager/selfCodes/selfCodesTest";
import { getInstance } from "../base";

export const SelfCodesTestSuite: TestSuite = {
name: `Self Codes Tests`,
tests: [
{name: `Backend check`, test: async () => {
const backendInstalled = await ServerComponent.initialise();

// To run these tests, we need the backend server. If this test fails. Don't bother
assert.strictEqual(backendInstalled, true);
try {
const selfTestSchema = [
`CREATE SCHEMA SELFTEST;`,
``,
`CREATE OR REPLACE TABLE SELFTEST.MYTBL (C1 INT, C2 VARCHAR(100), C3 TIMESTAMP, C4 DATE);`,
``,
`CREATE OR REPLACE TABLE SELFTEST.MYTBL2 (C1 INT, C2 VARCHAR(100), C3 TIMESTAMP, C4 DATE);`,
``,
`INSERT INTO SELFTEST.MYTBL VALUES (0, 'ADAM', CURRENT TIMESTAMP, CURRENT DATE);`,
``,
`INSERT INTO SELFTEST.MYTBL VALUES (1, 'LIAM', CURRENT TIMESTAMP + 1 SECOND, CURRENT DATE + 1 DAY);`,
``,
`INSERT INTO SELFTEST.MYTBL VALUES (2, 'RYAN', CURRENT TIMESTAMP + 2 SECOND, CURRENT DATE + 2 DAY);`,
``,
`INSERT INTO SELFTEST.MYTBL VALUES (3, NULL, CURRENT TIMESTAMP + 2 SECOND, CURRENT DATE + 2 DAY);`,
``,
`INSERT INTO SELFTEST.MYTBL2 VALUES (0, 'TIM', CURRENT TIMESTAMP, CURRENT DATE);`,
``,
`INSERT INTO SELFTEST.MYTBL2 VALUES (1, 'SCOTT', CURRENT TIMESTAMP + 1 SECOND, CURRENT DATE + 1 DAY);`,
``,
`INSERT INTO SELFTEST.MYTBL2 VALUES (2, 'JESSIE', CURRENT TIMESTAMP + 2 SECOND, CURRENT DATE + 2 DAY);`
]
await getInstance().getContent().runSQL(selfTestSchema.join(`\n`));

} catch (e) {
console.log(`Possible fail`);
}
}},
...testSelfCodes()]
}
87 changes: 79 additions & 8 deletions src/views/jobManager/jobManagerView.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import vscode, { MarkdownString, ProgressLocation, ThemeIcon, TreeItem, TreeItemCollapsibleState, Uri, commands, env, window, workspace } from "vscode";
import { TreeDataProvider } from "vscode";
import { Config, JobManager } from "../../config";
import { JobInfo, SQLJobManager } from "../../connection/manager";
import { editJobUi } from "./editJob";
import { displayJobLog } from "./jobLog";
import { ServerTraceDest, ServerTraceLevel } from "../../connection/types";
import vscode, { ProgressLocation, TreeDataProvider, TreeItemCollapsibleState, Uri, commands, env, window } from "vscode";
import { JobManager } from "../../config";
import { JobInfo } from "../../connection/manager";
import { ServerComponent } from "../../connection/serverComponent";
import { updateStatusBar } from "./statusBar";
import { SQLJob, TransactionEndType } from "../../connection/sqlJob";
import { ServerTraceDest, ServerTraceLevel } from "../../connection/types";
import { ConfigGroup, ConfigManager } from "./ConfigManager";
import { editJobUi } from "./editJob";
import { displayJobLog } from "./jobLog";
import { selfCodesMap } from "./selfCodes/selfCodes";
import { SelfCodesQuickPickItem } from "./selfCodes/selfCodesBrowser";
import { updateStatusBar } from "./statusBar";

const selectJobCommand = `vscode-db2i.jobManager.selectJob`;
const activeColor = new vscode.ThemeColor(`minimapGutter.addedBackground`);
Expand Down Expand Up @@ -127,6 +128,76 @@ export class JobManagerView implements TreeDataProvider<any> {
}
}),

vscode.commands.registerCommand(`vscode-db2i.jobManager.editSelfCodes`, async (node?: SQLJobItem) => {
const id = node ? node.label as string : undefined;
let selected = id ? JobManager.getJob(id) : JobManager.getSelection();
if (selected) {
try {
const currentSelfCodes = selected.job.options.selfcodes;
const selfCodeItems: SelfCodesQuickPickItem[] = selfCodesMap.map(
(code) => new SelfCodesQuickPickItem(code)
);
const currentSelfCodeItems: SelfCodesQuickPickItem[] =
selfCodeItems.filter((item) =>
currentSelfCodes ? currentSelfCodes.includes(item.label) : false
);

const quickPick = vscode.window.createQuickPick();
quickPick.title = `Select SELF codes`;
quickPick.canSelectMany = true;
quickPick.matchOnDetail = true;
quickPick.items = [
{
kind: vscode.QuickPickItemKind.Separator,
label: "Currently selected SELF codes",
},
...currentSelfCodeItems,
{
kind: vscode.QuickPickItemKind.Separator,
label: "All Available SELF codes",
},
...selfCodeItems.filter((item) =>
currentSelfCodeItems
? !currentSelfCodeItems.includes(item)
: true
),
];

quickPick.selectedItems = currentSelfCodeItems;

quickPick.onDidAccept(async () => {
const selections = quickPick.selectedItems;
// SET SYSIBMADM.SELFCODES = SYSIBMADM.VALIDATE_SELF('-514, -204, -501, +30, -199');
if (selections) {
const codes: string[] = selections.map((code) => code.label);
selected.job.setSelfCodes(codes);
vscode.window.showInformationMessage(`Applied SELF codes: ${codes}`);
}
quickPick.hide();
});
quickPick.onDidHide(() => quickPick.dispose());
quickPick.show();
} catch (e) {
vscode.window.showErrorMessage(e.message);
}
}
}),

vscode.commands.registerCommand(`vscode-db2i.jobManager.getSelfErrors`, async (node?: SQLJobItem) => {
if (node) {
const id = node.label as string;
const selected = await JobManager.getJob(id);

const content = `SELECT * FROM QSYS2.SQL_ERROR_LOG WHERE JOB_NAME = '${selected.job.id}'`;

vscode.commands.executeCommand(`vscode-db2i.runEditorStatement`, {
content,
qualifier: `statement`,
open: false,
});
}
}),

vscode.commands.registerCommand(`vscode-db2i.jobManager.enableTracing`, async (node?: SQLJobItem) => {
if (node) {
const id = node.label as string;
Expand Down
25 changes: 25 additions & 0 deletions src/views/jobManager/selfCodes/selfCodes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export interface SelfCodeObject {
code: string;
message: string;
}

export const selfCodesMap: SelfCodeObject[] = [
{ code: "138", message: "Argument of substringing function not valid" },
{ code: "180", message: "Syntax of date, time, or timestamp not valid" },
{
code: "181",
message: "Value in date, time, or timestamp string not valid",
},
{ code: "182", message: "A date, time, or timestamp expression not valid" },
{ code: "183", message: "Result of date or timestamp expression not valid" },
{ code: "199", message: "Keyword not expected, valid tokens:" },
{ code: "203", message: "Name is ambiguous" },
{ code: "204", message: "&1 in &2 type *&3 not found." },
{ code: "205", message: "Column not in table" },
{ code: "206", message: "Column or global variable not found" },
{ code: "304", message: "Conversion error in assignment to variable" },
{ code: "420", message: "Value for cast argument not valid" },
{ code: "551", message: "Not authorized to object &1 in &2 type *&3." },
{ code: "802", message: "Data conversion or mapping error" },
{ code: "811", message: "Result of SELECT more than one row." },
];
14 changes: 14 additions & 0 deletions src/views/jobManager/selfCodes/selfCodesBrowser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as vscode from 'vscode';
import { JobManager } from '../../../config';
import { SelfCodeObject } from './selfCodes';

export class SelfCodesQuickPickItem implements vscode.QuickPickItem {
label: string;
description?: string;
detail?: string;

constructor(object: SelfCodeObject) {
this.label = object.code;
this.description = object.message;
}
}
Loading
Loading