Skip to content

Commit 597d0c6

Browse files
committed
Merge branch 'feature/new_self_codes' of https://github.com/halcyon-tech/vscode-db2i into feature/new_self_codes
2 parents f09f8ab + daaa1cc commit 597d0c6

File tree

10 files changed

+185
-98
lines changed

10 files changed

+185
-98
lines changed

package.json

Lines changed: 16 additions & 5 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": "0.7.1",
5+
"version": "0.8.0",
66
"preview": true,
77
"engines": {
88
"vscode": "^1.70.0"
@@ -378,6 +378,12 @@
378378
"category": "Db2 for i",
379379
"icon": "$(notebook-execute)"
380380
},
381+
{
382+
"command": "vscode-db2i.statement.cancel",
383+
"title": "Cancel",
384+
"category": "Db2 for i",
385+
"icon": "$(stop)"
386+
},
381387
{
382388
"command": "vscode-db2i.editorExplain.withRun",
383389
"title": "Run and explain statement",
@@ -620,16 +626,21 @@
620626
],
621627
"editor/title": [
622628
{
623-
"when": "editorLangId == sql && code-for-ibmi:connected == true",
624-
"group": "navigation@sql",
629+
"when": "editorLangId == sql && code-for-ibmi:connected == true && vscode-db2i:statementCanCancel != true",
630+
"group": "navigation@1",
625631
"submenu": "sql/editor/context"
632+
},
633+
{
634+
"command": "vscode-db2i.statement.cancel",
635+
"when": "editorLangId == sql && vscode-db2i:statementCanCancel == true",
636+
"group": "navigation@1"
626637
}
627638
],
628639
"sql/editor/context": [
629640
{
630641
"command": "vscode-db2i.runEditorStatement",
631-
"when": "editorLangId == sql",
632-
"group": "1_general@sql"
642+
"when": "editorLangId == sql && vscode-db2i:statementCanCancel != true",
643+
"group": "navigation@1"
633644
},
634645
{
635646
"command": "vscode-db2i.editorExplain.withRun",

src/connection/manager.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ export interface JobInfo {
1111
job: SQLJob;
1212
}
1313

14+
const NO_SELECTED_JOB = -1;
15+
1416
export class SQLJobManager {
1517
private totalJobs = 0;
1618
private jobs: JobInfo[] = [];
17-
selectedJob: number = -1;
19+
selectedJob: number = NO_SELECTED_JOB;
1820

1921
constructor() { }
2022

@@ -50,13 +52,13 @@ export class SQLJobManager {
5052
}
5153

5254
getRunningJobs() {
53-
return this.jobs.filter(info => [JobStatus.Ready, JobStatus.Active].includes(info.job.getStatus()));
55+
return this.jobs.filter(info => [JobStatus.Ready, JobStatus.Busy].includes(info.job.getStatus()));
5456
}
5557

5658
async endAll() {
5759
await Promise.all(this.jobs.map(current => current.job.close()));
5860
this.jobs = [];
59-
this.selectedJob = -1;
61+
this.selectedJob = NO_SELECTED_JOB;
6062
}
6163

6264
async closeJob(index?: number) {
@@ -86,12 +88,12 @@ export class SQLJobManager {
8688
return this.jobs.find(info => info.name === name);
8789
}
8890

89-
setSelection(selectedName: string): boolean {
91+
setSelection(selectedName: string): JobInfo|undefined {
9092
const jobExists = this.jobs.findIndex(info => info.name === selectedName);
9193

9294
this.selectedJob = jobExists;
9395

94-
return (this.selectedJob >= 0);
96+
return this.jobs[jobExists];
9597
}
9698

9799
/**
@@ -103,7 +105,6 @@ export class SQLJobManager {
103105
* @returns
104106
*/
105107
async runSQL<T>(query: string, opts?: QueryOptions): Promise<T[]> {
106-
107108
// 2147483647 is NOT arbitrary. On the server side, this is processed as a Java
108109
// int. This is the largest number available without overflow (Integer.MAX_VALUE)
109110
const rowsToFetch = 2147483647;

src/connection/sqlJob.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { CommandResult } from "@halcyontech/vscode-ibmi-types";
21
import { getInstance } from "../base";
32
import { ServerComponent } from "./serverComponent";
43
import { JDBCOptions, ConnectionResult, Rows, QueryResult, JobLogEntry, CLCommandResult, VersionCheckResult, GetTraceDataResult, ServerTraceDest, ServerTraceLevel, SetConfigResult, QueryOptions, ExplainResults } from "./types";
@@ -8,7 +7,7 @@ import { EventEmitter } from "stream";
87
export enum JobStatus {
98
NotStarted = "notStarted",
109
Ready = "ready",
11-
Active = "active",
10+
Busy = "busy",
1211
Ended = "ended"
1312
}
1413

@@ -36,7 +35,6 @@ const TransactionCountQuery = [
3635
const DB2I_VERSION = (process.env[`DB2I_VERSION`] || `<version unknown>`) + ((process.env.DEV) ? ``:`-dev`);
3736

3837
export class SQLJob {
39-
4038
private static uniqueIdCounter: number = 0;
4139
private channel: any;
4240
private responseEmitter: EventEmitter = new EventEmitter();
@@ -130,7 +128,6 @@ export class SQLJob {
130128

131129
let req: ReqRespFmt = JSON.parse(content);
132130
this.channel.stdin.write(content + `\n`);
133-
this.status = JobStatus.Active;
134131
return new Promise((resolve, reject) => {
135132
this.responseEmitter.on(req.id, (x: string) => {
136133
this.responseEmitter.removeAllListeners(req.id);
@@ -140,7 +137,9 @@ export class SQLJob {
140137
}
141138

142139
getStatus() {
143-
return this.status;
140+
const currentListenerCount = this.responseEmitter.eventNames().length;
141+
142+
return currentListenerCount > 0 ? JobStatus.Busy : this.status;
144143
}
145144

146145
async connect(): Promise<ConnectionResult> {
@@ -204,6 +203,20 @@ export class SQLJob {
204203
return new Query(this, sql, opts);
205204
}
206205

206+
async requestCancel(): Promise<boolean> {
207+
const instance = getInstance();
208+
const content = instance.getContent();
209+
210+
// Note that this statement is run via the base extension since it has to be done on a job other than the one whose SQL is getting canceled
211+
await content.runSQL(`CALL QSYS2.CANCEL_SQL('${this.id}')`);
212+
213+
const [row] = await content.runSQL(`select V_SQL_STMT_STATUS as STATUS from table(qsys2.get_job_info('${this.id}'))`) as {STATUS: string|null}[];
214+
215+
if (row && row.STATUS === `ACTIVE`) return false;
216+
217+
return true;
218+
}
219+
207220
async getVersion(): Promise<VersionCheckResult> {
208221
const verObj = {
209222
id: SQLJob.getNewUniqueId(),
@@ -303,7 +316,7 @@ export class SQLJob {
303316
}
304317

305318
underCommitControl() {
306-
return this.options["transaction isolation"] !== `none`;
319+
return this.options["transaction isolation"] && this.options["transaction isolation"] !== `none`;
307320
}
308321

309322
async getPendingTransactions() {

src/database/schemas.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ export default class Schemas {
124124
}
125125
}
126126

127-
const query = `${selects.join(" UNION ALL ")} Order by QSYS2.DELIMIT_NAME(NAME) asc`;
127+
const query = `with results as (${selects.join(" UNION ALL ")}) select * from results Order by QSYS2.DELIMIT_NAME(NAME) asc`;
128128

129129
const objects: any[] = await JobManager.runSQL([
130130
query,

src/testing/database.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import assert from "assert";
22
import { TestSuite } from ".";
33
import { JobManager } from "../config";
4-
import Database from "../database/schemas";
4+
import Database, { AllSQLTypes } from "../database/schemas";
55
import Statement from "../database/statement";
66
import Callable from "../database/callable";
77
import { getInstance } from "../base";
@@ -97,6 +97,12 @@ export const DatabaseSuite: TestSuite = {
9797
assert.notStrictEqual(objects.length, 0);
9898
}},
9999

100+
{name: `Schema filter test`, test: async () => {
101+
const objects = await Database.getObjects(systemLibrary, AllSQLTypes, {filter: `emp`});
102+
103+
assert.notStrictEqual(objects.length, 0);
104+
}},
105+
100106
{name: `Get tables, sqlSchema name`, test: async () => {
101107
const objects = await Database.getObjects(Statement.noQuotes(sqlSchema), [`tables`]);
102108

src/views/html.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ export function getHeader(options: {withCollapsed?: boolean} = {}): string {
6969
position: relative;
7070
border-radius: 50% 50% 0 0;
7171
border-bottom: 10px solid #0055ff;
72-
background-color: #FFF;
73-
background-image: radial-gradient(ellipse at center, #FFF 34%, #0055ff 35%, #0055ff 54%, #FFF 55%), linear-gradient(#0055ff 10px, transparent 0);
72+
background-color: #d6dce3;
73+
background-image: radial-gradient(ellipse at center, #d6dce3 34%, #0055ff 35%, #0055ff 54%, #d6dce3 55%), linear-gradient(#0055ff 10px, transparent 0);
7474
background-size: 28px 28px;
7575
background-position: center 20px , center 2px;
7676
background-repeat: no-repeat;

src/views/jobManager/jobManagerView.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import vscode, { ProgressLocation, TreeDataProvider, TreeItemCollapsibleState, U
22
import { JobManager } from "../../config";
33
import { JobInfo } from "../../connection/manager";
44
import { ServerComponent } from "../../connection/serverComponent";
5-
import { SQLJob, TransactionEndType } from "../../connection/sqlJob";
5+
import { JobStatus, SQLJob, TransactionEndType } from "../../connection/sqlJob";
66
import { JDBCOptions, ServerTraceDest, ServerTraceLevel } from "../../connection/types";
77
import { ConfigGroup, ConfigManager } from "./ConfigManager";
88
import { editJobUi } from "./editJob";
@@ -11,6 +11,7 @@ import { selfCodesMap } from "./selfCodes/nodes";
1111
import { SelfCodesQuickPickItem } from "./selfCodes/selfCodesBrowser";
1212
import { updateStatusBar } from "./statusBar";
1313
import { selfCodesResultsView } from "./selfCodes/selfCodesResultsView";
14+
import { setCancelButtonVisibility } from "../results";
1415

1516
const selectJobCommand = `vscode-db2i.jobManager.selectJob`;
1617
const activeColor = new vscode.ThemeColor(`minimapGutter.addedBackground`);
@@ -317,6 +318,9 @@ export class JobManagerView implements TreeDataProvider<any> {
317318

318319
this._onDidChangeTreeData.fire();
319320
updateStatusBar();
321+
322+
const selectedJob = JobManager.getSelection();
323+
setCancelButtonVisibility(selectedJob && selectedJob.job.getStatus() === JobStatus.Busy);
320324
}
321325

322326
getTreeItem(element: vscode.TreeItem) {

src/views/jobManager/statusBar.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { getInstance } from "../../base";
55

66
const item = window.createStatusBarItem(`sqlJob`, StatusBarAlignment.Left);
77

8-
export async function updateStatusBar(options: {newJob?: boolean} = {}) {
8+
export async function updateStatusBar(options: {newJob?: boolean, canceling?: boolean, jobIsBusy?: boolean, executing?: boolean} = {}) {
99
const instance = getInstance();
1010
const connection = instance.getConnection();
1111

@@ -16,6 +16,15 @@ export async function updateStatusBar(options: {newJob?: boolean} = {}) {
1616
let backgroundColour: ThemeColor|undefined = undefined;
1717
let toolTipItems = [];
1818

19+
if (options.executing) {
20+
text = `$(sync~spin) Executing...`;
21+
} else
22+
if (options.canceling) {
23+
text = `$(sync~spin) Canceling...`;
24+
} else
25+
if (options.jobIsBusy) {
26+
text = `🙁 Job is busy`;
27+
} else
1928
if (options.newJob) {
2029
text = `$(sync~spin) Spinning up job...`;
2130
} else

0 commit comments

Comments
 (0)