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

Cleanup of code that checks OS version and features #223

Merged
merged 3 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@
"title": "General",
"order": 1,
"properties": {
"vscode-db2i.autoRefreshSelfCodesView": {
"vscode-db2i.jobSelfViewAutoRefresh": {
"type": "boolean",
"title": "Auto-refresh SELF Codes view",
"description": "Enable auto-refresh for SELF Codes view when connecting to a system",
"default": false
},
Expand Down
86 changes: 86 additions & 0 deletions src/IBMiDetail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { getInstance } from "./base";
import { ServerComponent } from "./connection/serverComponent";

export type Db2FeatureIds = `SELF`;

const featureRequirements: { [id in Db2FeatureIds]: { [osVersion: number]: number } } = {
'SELF': {
7.4: 26,
7.5: 5
}
};

export class IBMiDetail {
private version: number = 0;
private db2Level: number = 0;
private features: { [id in Db2FeatureIds]: boolean } = {
'SELF': false
};

setFeatureSupport(featureId: Db2FeatureIds, supported: boolean) {
this.features[featureId] = supported;
}

getVersion() {
return this.version;
}

getDb2Level() {
return this.db2Level;
}

async fetchSystemInfo() {
const instance = getInstance();
const content = instance.getContent();

let levelCheckFailed = false;

const versionResults = await content.runSQL(`select OS_VERSION concat '.' concat OS_RELEASE as VERSION from sysibmadm.env_sys_info`);
this.version = Number(versionResults[0].VERSION);

try {
const db2LevelResults = await content.runSQL([
`select max(ptf_group_level) as HIGHEST_DB2_PTF_GROUP_LEVEL`,
`from qsys2.group_ptf_info`,
`where PTF_GROUP_DESCRIPTION like 'DB2 FOR IBM I%' and`,
`ptf_group_status = 'INSTALLED';`
].join(` `));

this.db2Level = Number(db2LevelResults[0].HIGHEST_DB2_PTF_GROUP_LEVEL);
} catch (e) {
ServerComponent.writeOutput(`Failed to get Db2 level: ${e.message}`);
levelCheckFailed = true;
}

const features = Object.keys(featureRequirements) as Db2FeatureIds[];
for (const featureId of features) {
const requiredLevelForFeature = featureRequirements[featureId][String(this.version)];
const supported = requiredLevelForFeature && this.db2Level >= requiredLevelForFeature;
this.setFeatureSupport(featureId, supported);
}

if (levelCheckFailed) {
const selfSupported = await this.validateSelfInstallation();
this.setFeatureSupport('SELF', selfSupported);
}
}

getFeatures() {
return this.features;
}

private async validateSelfInstallation() {
const instance = getInstance();
const content = instance.getContent();

try {
await content.runSQL(`values SYSIBMADM.SELFCODES`);

// This means we have the SELF feature
return true;
} catch (e) {
// If we can't run this, then we don't have the SELF feature
return false;
}
}
}
77 changes: 13 additions & 64 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,24 @@ import Configuration from "./configuration";
import { ConfigManager } from "./views/jobManager/ConfigManager";
import { Examples, ServiceInfoLabel } from "./views/examples";
import { updateStatusBar } from "./views/jobManager/statusBar";

interface IBMiLevels {
version: number;
db2Level: number;
}
import { IBMiDetail } from "./IBMiDetail";

export let Config: ConnectionStorage;
export let OSData: IBMiLevels|undefined;
export let osDetail: IBMiDetail;
export let JobManager: SQLJobManager = new SQLJobManager();

export type Db2Features = `SELF`;

const featureRequirements: {[id in Db2Features]: {[osVersion: number]: number}} = {
'SELF': {
7.4: 26,
7.5: 5
}
}

export async function onConnectOrServerInstall(): Promise<boolean> {
const instance = getInstance();

Config.setConnectionName(instance.getConnection().currentConnectionName);
determineFeatures();

await Config.fixPastQueries();

osDetail = new IBMiDetail();

await osDetail.fetchSystemInfo();

await ServerComponent.initialise().then(installed => {
if (installed) {
JobManagerView.setVisible(true);
Expand All @@ -44,6 +35,7 @@ export async function onConnectOrServerInstall(): Promise<boolean> {
await ServerComponent.checkForUpdate();

updateStatusBar();
toggleViews();

if (ServerComponent.isInstalled()) {
JobManagerView.setVisible(true);
Expand Down Expand Up @@ -75,7 +67,7 @@ export async function onConnectOrServerInstall(): Promise<boolean> {
return false;
}

export function setupConfig(context: ExtensionContext) {
export function initConfig(context: ExtensionContext) {
Config = new ConnectionStorage(context);

getInstance().onEvent(`disconnected`, async () => {
Expand All @@ -91,55 +83,12 @@ export function setupConfig(context: ExtensionContext) {
});
}

export async function fetchSystemInfo() {
const instance = getInstance();
const content = instance.getContent();

const [versionResults, db2LevelResults] = await Promise.all([
content.runSQL(`select OS_VERSION concat '.' concat OS_RELEASE as VERSION from sysibmadm.env_sys_info`),
content.runSQL([
`select max(ptf_group_level) as HIGHEST_DB2_PTF_GROUP_LEVEL`,
`from qsys2.group_ptf_info`,
`where PTF_GROUP_DESCRIPTION like 'DB2 FOR IBM I%' and`,
`ptf_group_status = 'INSTALLED';`
].join(` `))
]);

const version = Number(versionResults[0].VERSION);
const db2Level = Number(db2LevelResults[0].HIGHEST_DB2_PTF_GROUP_LEVEL);

if (version && db2Level) {
OSData = {
version,
db2Level
}
}
}

export function determineFeatures() {
const result: {[id in Db2Features]: boolean} = {
'SELF': false
};

if (OSData) {
const {version, db2Level} = OSData;

const features = Object.keys(featureRequirements) as Db2Features[];
for (const featureId of features) {
const requiredLevelForFeature = featureRequirements[featureId][String(version)];
const supported = requiredLevelForFeature && db2Level >= requiredLevelForFeature;
commands.executeCommand(`setContext`, `vscode-db2i:${featureId}Supported`, supported);
result[featureId] = supported;
}
}

return result;
}
export function toggleViews() {
const features = osDetail.getFeatures();

export function turnOffAllFeatures() {
const features = Object.keys(featureRequirements);
for (const featureId of features) {
commands.executeCommand(`setContext`, `vscode-db2i:${featureId}Supported`, false);
const featureIds = Object.keys(features) as (keyof typeof features)[];
for (const featureId of featureIds) {
commands.executeCommand(`setContext`, `vscode-db2i:${featureId}Supported`, features[featureId]);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/connection/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Query } from "./query";
import { ServerComponent, UpdateStatus } from "./serverComponent";
import { JobStatus, SQLJob } from "./sqlJob";
import { QueryOptions } from "./types";
import { askAboutNewJob, determineFeatures, onConnectOrServerInstall } from "../config";
import { askAboutNewJob, onConnectOrServerInstall, osDetail } from "../config";
import { SelfValue } from "../views/jobManager/selfCodes/nodes";
import Configuration from "../configuration";

Expand All @@ -24,7 +24,7 @@ export class SQLJobManager {

async newJob(predefinedJob?: SQLJob, name?: string) {
if (ServerComponent.isInstalled()) {
const features = determineFeatures();
const features = osDetail.getFeatures();

const instance = getInstance();
const config = instance.getConfig();
Expand Down
19 changes: 7 additions & 12 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as JSONServices from "./language/json";
import * as resultsProvider from "./views/results";

import { getInstance, loadBase } from "./base";
import { JobManager, fetchSystemInfo, onConnectOrServerInstall, setupConfig, turnOffAllFeatures } from "./config";
import { JobManager, onConnectOrServerInstall, initConfig } from "./config";
import { queryHistory } from "./views/queryHistoryView";
import { ExampleBrowser } from "./views/examples/exampleBrowser";
import { languageInit } from "./language";
Expand Down Expand Up @@ -70,7 +70,7 @@ export function activate(context: vscode.ExtensionContext): Db2i {
JSONServices.initialise(context);
resultsProvider.initialise(context);

setupConfig(context);
initConfig(context);

console.log(`Developer environment: ${process.env.DEV}`);
if (process.env.DEV) {
Expand All @@ -81,19 +81,14 @@ export function activate(context: vscode.ExtensionContext): Db2i {
const instance = getInstance();

instance.onEvent(`connected`, () => {
// We need to fetch the system info
fetchSystemInfo().then(() => {
// Refresh the examples when we have it, so we only display certain examples
onConnectOrServerInstall();
selfCodesView.setRefreshEnabled(false);
// Refresh the examples when we have it, so we only display certain examples
onConnectOrServerInstall().then(() => {
exampleBrowser.refresh();
selfCodesView.setRefreshEnabled(Configuration.get(`autoRefreshSelfCodesView`) || false)
})
selfCodesView.setRefreshEnabled(Configuration.get(`jobSelfViewAutoRefresh`) || false)
});
});

instance.onEvent(`disconnected`, () => {
turnOffAllFeatures();
})

return { sqlJobManager: JobManager, sqlJob: (options?: JDBCOptions) => new SQLJob(options) };
}

Expand Down
10 changes: 5 additions & 5 deletions src/views/examples/exampleBrowser.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Event, EventEmitter, ExtensionContext, MarkdownString, ThemeIcon, TreeDataProvider, TreeItem, TreeItemCollapsibleState, Uri, commands, window, workspace } from "vscode";
import { Examples, SQLExample, ServiceInfoLabel } from ".";
import { getInstance } from "../../base";
import { OSData, fetchSystemInfo } from "../../config";
import { getServiceInfo } from "../../database/serviceInfo";
import { osDetail } from "../../config";

export const openExampleCommand = `vscode-db2i.examples.open`;

Expand Down Expand Up @@ -113,13 +112,14 @@ class SQLExampleItem extends TreeItem {
}

function exampleWorksForOnOS(example: SQLExample): boolean {
if (OSData) {
const myOsVersion = OSData.version;

if (osDetail) {
const myOsVersion = osDetail.getVersion();

// If this example has specific system requirements defined
if (example.requirements &&
example.requirements[myOsVersion] &&
OSData.db2Level < example.requirements[myOsVersion]) {
osDetail.getDb2Level() < example.requirements[myOsVersion]) {
return false;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/views/jobManager/jobManagerView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class JobManagerView implements TreeDataProvider<any> {
...ConfigManager.initialiseSaveCommands(),

vscode.commands.registerCommand(`vscode-db2i.jobManager.defaultSelfSettings`, () => {
vscode.commands.executeCommand('workbench.action.openSettings', 'vscode-db2i.jobSelfDefault');
vscode.commands.executeCommand('workbench.action.openSettings', 'vscode-db2i.jobSelf');
}),

vscode.commands.registerCommand(`vscode-db2i.jobManager.newJob`, async (options?: JDBCOptions, name?: string) => {
Expand Down
12 changes: 7 additions & 5 deletions src/views/jobManager/selfCodes/selfCodesResultsView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,13 @@ export class selfCodesResultsView implements TreeDataProvider<any> {
token: vscode.CancellationToken
): ProviderResult<TreeItem> {
if (!item.tooltip) {
// Only set the tooltip if it hasn't been set yet
item.tooltip = new vscode.MarkdownString(
`**SQL Statement:** ${element.STMTTEXT}\n\n---\n\n**Detail:** ${element.MESSAGE_SECOND_LEVEL_TEXT}`
);
item.tooltip.isTrusted = true; // Make sure to allow Markdown content
if (element.STMTTEXT && element.MESSAGE_SECOND_LEVEL_TEXT) {
// Only set the tooltip if it hasn't been set yet
item.tooltip = new vscode.MarkdownString(
`**SQL Statement:** ${element.STMTTEXT}\n\n---\n\n**Detail:** ${element.MESSAGE_SECOND_LEVEL_TEXT}`
);
item.tooltip.isTrusted = true; // Make sure to allow Markdown content
}
}
return item;
}
Expand Down
Loading