diff --git a/package-lock.json b/package-lock.json index f2592f82..2a4c8483 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "vscode-db2i", - "version": "1.7.0-syntaxcheck11", + "version": "1.8.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "vscode-db2i", - "version": "1.7.0-syntaxcheck11", + "version": "1.8.0", "dependencies": { "@ibm/mapepire-js": "^0.3.0", "chart.js": "^4.4.2", @@ -19,7 +19,7 @@ }, "devDependencies": { "@continuedev/core": "^1.0.13", - "@halcyontech/vscode-ibmi-types": "^2.14.0", + "@halcyontech/vscode-ibmi-types": "^2.14.5", "@types/glob": "^7.1.3", "@types/node": "18.x", "@types/vscode": "^1.95.0", @@ -12550,9 +12550,9 @@ } }, "node_modules/undici": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.0.tgz", - "integrity": "sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==", + "version": "6.21.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz", + "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==", "dev": true, "engines": { "node": ">=18.17" @@ -12782,9 +12782,9 @@ } }, "node_modules/vite": { - "version": "5.4.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", - "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "version": "5.4.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", + "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", "dev": true, "dependencies": { "esbuild": "^0.21.3", diff --git a/package.json b/package.json index 64a8f9f8..3a46b440 100644 --- a/package.json +++ b/package.json @@ -970,7 +970,7 @@ }, { "command": "vscode-db2i.getObjectLocks", - "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", + "when": "viewItem == table || viewItem == view || viewItem == alias || viewItem == function || viewItem == variable || viewItem == index || viewItem == procedure || viewItem == sequence || viewItem == package || viewItem == trigger || viewItem == type", "group": "db2workWith@5" }, { @@ -1322,7 +1322,7 @@ }, "devDependencies": { "@continuedev/core": "^1.0.13", - "@halcyontech/vscode-ibmi-types": "^2.14.0", + "@halcyontech/vscode-ibmi-types": "^2.14.5", "@types/glob": "^7.1.3", "@types/node": "18.x", "@types/vscode": "^1.95.0", diff --git a/src/database/schemas.ts b/src/database/schemas.ts index eeeca265..152ee781 100644 --- a/src/database/schemas.ts +++ b/src/database/schemas.ts @@ -1,6 +1,6 @@ +import path from "path"; import { getInstance } from "../base"; - import { JobManager } from "../config"; 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 { * @param object Not user input */ static async generateSQL(schema: string, object: string, internalType: string): Promise { - const lines = await JobManager.runSQL<{ SRCDTA: string }>([ - `CALL QSYS2.GENERATE_SQL(?, ?, ?, CREATE_OR_REPLACE_OPTION => '1', PRIVILEGES_OPTION => '0')` - ].join(` `), { parameters: [object, schema, internalType] }); - - const generatedStatement = lines.map(line => line.SRCDTA).join(`\n`); - - return generatedStatement; + const instance = getInstance(); + const connection = instance.getConnection(); + + const result = await connection.withTempDirectory(async (tempDir) => { + const tempFilePath = path.posix.join(tempDir, `generatedSql.sql`); + await JobManager.runSQL<{ SRCDTA: string }>([ + `CALL QSYS2.GENERATE_SQL( DATABASE_OBJECT_NAME => ?, DATABASE_OBJECT_LIBRARY_NAME => ?, DATABASE_OBJECT_TYPE => ? + , CREATE_OR_REPLACE_OPTION => '1', PRIVILEGES_OPTION => '0' + , DATABASE_SOURCE_FILE_NAME => '*STMF' + , STATEMENT_FORMATTING_OPTION => '0' + , SOURCE_STREAM_FILE => '${tempFilePath}' + , SOURCE_STREAM_FILE_END_OF_LINE => 'LF' + , SOURCE_STREAM_FILE_CCSID => 1208 )` + ].join(` `), { parameters: [object, schema, internalType] }); + + // TODO: eventually .content -> .getContent(), it's not available yet + const contents = (await connection.content.downloadStreamfileRaw(tempFilePath)).toString(); + return contents; + }) + + return result; } static async deleteObject(schema: string, name: string, type: string): Promise { diff --git a/src/views/schemaBrowser/index.ts b/src/views/schemaBrowser/index.ts index 3387e17d..424e27af 100644 --- a/src/views/schemaBrowser/index.ts +++ b/src/views/schemaBrowser/index.ts @@ -44,9 +44,9 @@ const itemIcons = { export default class schemaBrowser { emitter: vscode.EventEmitter; onDidChangeTreeData: vscode.Event; - cache: {[key: string]: object[]}; + cache: { [key: string]: object[] }; - filters: {[schema: string]: string} = {}; + filters: { [schema: string]: string } = {}; /** * @param {vscode.ExtensionContext} context @@ -138,13 +138,15 @@ export default class schemaBrowser { vscode.commands.registerCommand(`vscode-db2i.generateSQL`, async (object: SQLObject) => { if (object) { - try { - const content = await Schemas.generateSQL(object.schema, object.uniqueName(), object.type.toUpperCase()); - const textDoc = await vscode.workspace.openTextDocument({language: `sql`, content}); - await vscode.window.showTextDocument(textDoc); - } catch (e) { - vscode.window.showErrorMessage(e.message); - } + vscode.window.withProgress({ location: vscode.ProgressLocation.Window, title: `Generating SQL` }, async () => { + try { + const content = await Schemas.generateSQL(object.schema, object.uniqueName(), object.type.toUpperCase()); + const textDoc = await vscode.workspace.openTextDocument({ language: `sql`, content }); + await vscode.window.showTextDocument(textDoc); + } catch (e) { + vscode.window.showErrorMessage(e.message); + } + }); } }), @@ -162,10 +164,10 @@ export default class schemaBrowser { } }), - vscode.commands.registerCommand(`vscode-db2i.getMTIs`, async (object: SQLObject|SchemaItem) => { + vscode.commands.registerCommand(`vscode-db2i.getMTIs`, async (object: SQLObject | SchemaItem) => { if (object) { const content = getMTIStatement(object.schema, (`name` in object ? object.name : undefined)); - + if (content) { vscode.commands.executeCommand(`vscode-db2i.runEditorStatement`, { content, @@ -186,7 +188,7 @@ export default class schemaBrowser { }); } }), - + vscode.commands.registerCommand(`vscode-db2i.getAuthorities`, async (object: SQLObject) => { if (object) { const content = getAuthoritiesStatement(object.schema, object.name, object.type.toUpperCase(), object.tableType); @@ -209,16 +211,16 @@ export default class schemaBrowser { } }), - vscode.commands.registerCommand(`vscode-db2i.advisedIndexes`, async (object: SQLObject|SchemaItem) => { //table + vscode.commands.registerCommand(`vscode-db2i.advisedIndexes`, async (object: SQLObject | SchemaItem) => { //table if (object) { - let content: string|undefined; + let content: string | undefined; if (`name` in object) { content = getAdvisedIndexesStatement(object.schema, object.name); } else { content = getAdvisedIndexesStatement(object.schema); } - + if (content) { vscode.commands.executeCommand(`vscode-db2i.runEditorStatement`, { content, @@ -229,16 +231,16 @@ export default class schemaBrowser { } }), - vscode.commands.registerCommand(`vscode-db2i.clearAdvisedIndexes`, async (object: SQLObject|SchemaItem) => { + vscode.commands.registerCommand(`vscode-db2i.clearAdvisedIndexes`, async (object: SQLObject | SchemaItem) => { if (object) { const isObject = `name` in object; let result; - result = await vscode.window.showWarningMessage(`Are you sure you want to clear all of the advised index rows from the Index Advisor for ${object.schema}${isObject ? `${object.name}` : ''}?`, { + result = await vscode.window.showWarningMessage(`Are you sure you want to clear all of the advised index rows from the Index Advisor for ${object.schema}${isObject ? `${object.name}` : ''}?`, { modal: true, }, 'No', 'Yes'); - - if(result === 'Yes') { + + if (result === 'Yes') { try { await Schemas.clearAdvisedIndexes(object.schema, isObject ? object.name : undefined); } catch (e) { @@ -254,7 +256,7 @@ export default class schemaBrowser { modal: true, }, 'No', 'Yes'); - if(result === 'Yes') { + if (result === 'Yes') { try { await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, @@ -289,7 +291,7 @@ export default class schemaBrowser { }, async () => { await Schemas.renameObject(object.schema, object.name, name, object.type); }); - + vscode.window.showInformationMessage(`Renamed ${object.name} to ${name}`); this.clearCacheAndRefresh(); } catch (e) { @@ -301,14 +303,14 @@ export default class schemaBrowser { } } }), - + vscode.commands.registerCommand(`vscode-db2i.clearData`, async (object: SQLObject) => { if (object) { const result = await vscode.window.showWarningMessage(`Are you sure you want to clear ${object.name}?`, { modal: true, }, 'No', 'Yes'); - if(result === 'Yes') { + if (result === 'Yes') { try { await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, @@ -328,8 +330,8 @@ export default class schemaBrowser { vscode.commands.registerCommand(`vscode-db2i.copyData`, async (object: SQLObject) => { if (object) { const page = await getCopyUi().loadPage((`Copy File - ${object.schema}.${object.name}`)); - - if(page && page.data) { + + if (page && page.data) { const data = page.data; page.panel.dispose(); @@ -341,7 +343,7 @@ export default class schemaBrowser { }, async () => { await Table.copyFile(object.system.schema, object.system.name, data); }); - + vscode.window.showInformationMessage(`Table copied`); this.clearCacheAndRefresh(); } catch (e) { @@ -369,7 +371,7 @@ export default class schemaBrowser { const config = getInstance().getConfig(); const currentLibrary = config.currentLibrary.toUpperCase(); - + if (schema && schema !== currentLibrary) { config.currentLibrary = schema; await getInstance().setConfig(config); @@ -477,7 +479,7 @@ export default class schemaBrowser { return element; } - async getChildren(element?: Schema|SchemaItem|SQLObject) { + async getChildren(element?: Schema | SchemaItem | SQLObject) { let items = []; if (element) { @@ -489,7 +491,7 @@ export default class schemaBrowser { let filterValue = this.filters[element.schema]; if (filterValue) { const validSchemaName = Statement.noQuotes(element.schema); - const filteredObjects = await Schemas.getObjects(validSchemaName, AllSQLTypes, {filter: filterValue}); + const filteredObjects = await Schemas.getObjects(validSchemaName, AllSQLTypes, { filter: filterValue }); items = filteredObjects.map(obj => new SQLObject(obj)); } else { @@ -499,16 +501,16 @@ export default class schemaBrowser { } else - if (element instanceof SchemaItem) { - items = await this.fetchData(element.schema, contextValue as SQLType, false); - } else - if (element instanceof SQLObject) { - const type = element.type; - - if (Types[type]) { - items = await Types[type].getChildren(element.schema, element.uniqueName()); - } - } + if (element instanceof SchemaItem) { + items = await this.fetchData(element.schema, contextValue as SQLType, false); + } else + if (element instanceof SQLObject) { + const type = element.type; + + if (Types[type]) { + items = await Types[type].getChildren(element.schema, element.uniqueName()); + } + } } else { const connection = getInstance().getConnection();