From a2102a51a186790a2d768f256e60cbdb2b7f882d Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Fri, 31 May 2024 10:17:48 +0200 Subject: [PATCH 01/15] use oracledb purejs client --- adjustPackageJson.js | 3 --- app/package.json | 3 +-- app/yarn.lock | 5 ----- fillNativeModules.js | 3 --- packages/api/package.json | 5 ++--- plugins/dbgate-plugin-oracle/package.json | 3 +++ .../src/backend/drivers.js | 20 ++----------------- .../dbgate-plugin-oracle/src/backend/index.js | 3 --- .../webpack-backend.config.js | 2 +- yarn.lock | 8 ++++---- 10 files changed, 13 insertions(+), 42 deletions(-) diff --git a/adjustPackageJson.js b/adjustPackageJson.js index 8581fb30..d805f266 100644 --- a/adjustPackageJson.js +++ b/adjustPackageJson.js @@ -5,9 +5,6 @@ function adjustFile(file) { if (process.platform != 'win32') { delete json.optionalDependencies.msnodesqlv8; } - if (process.arch == 'arm64') { - delete json.optionalDependencies.oracledb; - } fs.writeFileSync(file, JSON.stringify(json, null, 2), 'utf-8'); } diff --git a/app/package.json b/app/package.json index 1bb4a2a1..f79b1fe7 100644 --- a/app/package.json +++ b/app/package.json @@ -121,7 +121,6 @@ }, "optionalDependencies": { "better-sqlite3": "9.6.0", - "msnodesqlv8": "^4.2.1", - "oracledb": "^5.5.0" + "msnodesqlv8": "^4.2.1" } } diff --git a/app/yarn.lock b/app/yarn.lock index 6d846e92..63e86571 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -1944,11 +1944,6 @@ open@^7.4.2: is-docker "^2.0.0" is-wsl "^2.1.1" -oracledb@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/oracledb/-/oracledb-5.5.0.tgz#0cf9af5d0c0815f74849ae9ed56aee823514d71b" - integrity sha512-i5cPvMENpZP8nnqptB6l0pjiOyySj1IISkbM4Hr3yZEDdANo2eezarwZb9NQ8fTh5pRjmgpZdSyIbnn9N3AENw== - os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" diff --git a/fillNativeModules.js b/fillNativeModules.js index cc390b39..07d7c1cf 100644 --- a/fillNativeModules.js +++ b/fillNativeModules.js @@ -5,9 +5,6 @@ let fillContent = ''; if (process.platform == 'win32') { fillContent += `content.msnodesqlv8 = () => require('msnodesqlv8');`; } -if (process.arch != 'arm64') { - fillContent += `content.oracledb = () => require('oracledb');`; -} fillContent += `content['better-sqlite3'] = () => require('better-sqlite3');`; const getContent = empty => ` diff --git a/packages/api/package.json b/packages/api/package.json index 204a919b..f56c346c 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -26,10 +26,10 @@ "compare-versions": "^3.6.0", "cors": "^2.8.5", "cross-env": "^6.0.3", + "dbgate-datalib": "^5.0.0-alpha.1", "dbgate-query-splitter": "^4.9.3", "dbgate-sqltree": "^5.0.0-alpha.1", "dbgate-tools": "^5.0.0-alpha.1", - "dbgate-datalib": "^5.0.0-alpha.1", "debug": "^4.3.4", "diff": "^5.0.0", "diff2html": "^3.4.13", @@ -83,7 +83,6 @@ }, "optionalDependencies": { "better-sqlite3": "9.6.0", - "msnodesqlv8": "^4.2.1", - "oracledb": "^5.5.0" + "msnodesqlv8": "^4.2.1" } } diff --git a/plugins/dbgate-plugin-oracle/package.json b/plugins/dbgate-plugin-oracle/package.json index 4b9e205b..ba6d05e6 100644 --- a/plugins/dbgate-plugin-oracle/package.json +++ b/plugins/dbgate-plugin-oracle/package.json @@ -36,5 +36,8 @@ "lodash": "^4.17.21", "webpack": "^5.91.0", "webpack-cli": "^5.1.4" + }, + "dependencies": { + "oracledb": "^6.5.1" } } diff --git a/plugins/dbgate-plugin-oracle/src/backend/drivers.js b/plugins/dbgate-plugin-oracle/src/backend/drivers.js index 8e71ba58..388dc177 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/drivers.js +++ b/plugins/dbgate-plugin-oracle/src/backend/drivers.js @@ -4,20 +4,10 @@ const stream = require('stream'); const driverBases = require('../frontend/drivers'); const Analyser = require('./Analyser'); //--const pg = require('pg'); -//const oracledb = require('oracledb'); +const oracledb = require('oracledb'); const { createBulkInsertStreamBase, makeUniqueColumnNames } = require('dbgate-tools'); -let requireOracledb; // native module - -let oracledbValue; -function getOracledb() { - if (!oracledbValue) { - oracledbValue = requireOracledb(); - } - return oracledbValue; -} - /* pg.types.setTypeParser(1082, 'text', val => val); // date pg.types.setTypeParser(1114, 'text', val => val); // timestamp without timezone @@ -62,7 +52,7 @@ const drivers = driverBases.map(driverBase => ({ authType, socketPath, }) { - client = await getOracledb().getConnection({ + client = await oracledb.getConnection({ user, password, connectString: useDatabaseUrl ? databaseUrl : port ? `${server}:${port}` : server, @@ -283,10 +273,4 @@ const drivers = driverBases.map(driverBase => ({ }, })); -drivers.initialize = dbgateEnv => { - if (dbgateEnv.nativeModules && dbgateEnv.nativeModules.oracledb) { - requireOracledb = dbgateEnv.nativeModules.oracledb; - } -}; - module.exports = drivers; diff --git a/plugins/dbgate-plugin-oracle/src/backend/index.js b/plugins/dbgate-plugin-oracle/src/backend/index.js index bc9f75e8..de004729 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/index.js +++ b/plugins/dbgate-plugin-oracle/src/backend/index.js @@ -3,7 +3,4 @@ const drivers = require('./drivers'); module.exports = { packageName: 'dbgate-plugin-oracle', drivers, - initialize(dbgateEnv) { - drivers.initialize(dbgateEnv); - }, }; diff --git a/plugins/dbgate-plugin-oracle/webpack-backend.config.js b/plugins/dbgate-plugin-oracle/webpack-backend.config.js index c3ac033c..05b19540 100644 --- a/plugins/dbgate-plugin-oracle/webpack-backend.config.js +++ b/plugins/dbgate-plugin-oracle/webpack-backend.config.js @@ -22,7 +22,7 @@ var config = { plugins: [ new webpack.IgnorePlugin({ checkResource(resource) { - const lazyImports = ['oracledb', 'uws']; + const lazyImports = ['uws']; if (!lazyImports.includes(resource)) { return false; } diff --git a/yarn.lock b/yarn.lock index 1bdd0085..f74f131b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7978,10 +7978,10 @@ optionator@^0.8.1, optionator@^0.8.3: resolved "https://registry.yarnpkg.com/opts/-/opts-2.0.2.tgz#a17e189fbbfee171da559edd8a42423bc5993ce1" integrity sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg== -oracledb@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/oracledb/-/oracledb-5.5.0.tgz#0cf9af5d0c0815f74849ae9ed56aee823514d71b" - integrity sha512-i5cPvMENpZP8nnqptB6l0pjiOyySj1IISkbM4Hr3yZEDdANo2eezarwZb9NQ8fTh5pRjmgpZdSyIbnn9N3AENw== +oracledb@^6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/oracledb/-/oracledb-6.5.1.tgz#814d985035acdb1a6470b1152af0ca3767569ede" + integrity sha512-JzoSGei1wnvmqgKnAZK1W650mzHTZXx+7hClV4mwsbY/ZjUtrpnojNJMYJ2jkOhj7XG5oJPfXc4GqDKaNzkxqg== os-tmpdir@~1.0.2: version "1.0.2" From 2723c4183283e100c9a9de152432f64384128027 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Fri, 31 May 2024 14:35:35 +0200 Subject: [PATCH 02/15] oracle analyser per schema --- packages/api/src/controllers/connections.js | 1 + packages/tools/src/DatabaseAnalyser.ts | 19 ++++++++--- .../settings/ConnectionDriverFields.svelte | 4 +++ packages/web/src/tabs/ConnectionTab.svelte | 1 + .../web/src/utility/getConnectionLabel.ts | 3 ++ .../src/backend/Analyser.js | 33 +++++++++---------- .../src/backend/drivers.js | 11 ++++--- .../src/backend/sql/columns.js | 2 +- .../src/backend/sql/foreignKeys.js | 2 +- .../src/backend/sql/indexes.js | 2 +- .../src/backend/sql/matviewColumns.js | 2 +- .../src/backend/sql/matviews.js | 2 +- .../src/backend/sql/routines.js | 1 + .../src/backend/sql/tableList.js | 2 +- .../src/backend/sql/uniqueNames.js | 2 +- .../src/backend/sql/views.js | 2 +- .../src/frontend/drivers.js | 26 +++------------ .../src/backend/Analyser.js | 15 --------- 18 files changed, 58 insertions(+), 72 deletions(-) diff --git a/packages/api/src/controllers/connections.js b/packages/api/src/controllers/connections.js index c17566cb..2cda2e87 100644 --- a/packages/api/src/controllers/connections.js +++ b/packages/api/src/controllers/connections.js @@ -61,6 +61,7 @@ function getPortalCollections() { useDatabaseUrl: !!process.env[`URL_${id}`], databaseFile: process.env[`FILE_${id}`], socketPath: process.env[`SOCKET_PATH_${id}`], + serviceName: process.env[`SERVICE_NAME_${id}`], authType: process.env[`AUTH_TYPE_${id}`] || (process.env[`SOCKET_PATH_${id}`] ? 'socket' : undefined), defaultDatabase: process.env[`DATABASE_${id}`] || diff --git a/packages/tools/src/DatabaseAnalyser.ts b/packages/tools/src/DatabaseAnalyser.ts index 699ce6d6..0480d0af 100644 --- a/packages/tools/src/DatabaseAnalyser.ts +++ b/packages/tools/src/DatabaseAnalyser.ts @@ -180,8 +180,15 @@ export class DatabaseAnalyser { // return this.createQueryCore('=OBJECT_ID_CONDITION', typeFields) != ' is not null'; // } - createQuery(template, typeFields) { - return this.createQueryCore(template, typeFields); + createQuery(template, typeFields, replacements = {}) { + return this.createQueryCore(this.processQueryReplacements(template, replacements), typeFields); + } + + processQueryReplacements(query, replacements) { + for (const repl in replacements) { + query = query.replaceAll(repl, replacements[repl]); + } + return query; } createQueryCore(template, typeFields) { @@ -302,8 +309,8 @@ export class DatabaseAnalyser { return [..._compact(res), ...this.getDeletedObjects(snapshot)]; } - async analyserQuery(template, typeFields) { - const sql = this.createQuery(template, typeFields); + async analyserQuery(template, typeFields, replacements = {}) { + const sql = this.createQuery(template, typeFields, replacements); if (!sql) { return { @@ -311,7 +318,9 @@ export class DatabaseAnalyser { }; } try { - return await this.driver.query(this.pool, sql); + const res = await this.driver.query(this.pool, sql); + this.logger.debug({ rows: res.rows.length, template }, `Loaded analyser query`); + return res; } catch (err) { logger.error({ err }, 'Error running analyser query'); return { diff --git a/packages/web/src/settings/ConnectionDriverFields.svelte b/packages/web/src/settings/ConnectionDriverFields.svelte index eb3e1a6a..0bfdc127 100644 --- a/packages/web/src/settings/ConnectionDriverFields.svelte +++ b/packages/web/src/settings/ConnectionDriverFields.svelte @@ -123,6 +123,10 @@ {/if} {/if} +{#if driver?.showConnectionField('serviceName', $values)} + +{/if} + {#if driver?.showConnectionField('socketPath', $values)} driver?.showConnectionField(x, $values)); const omitProps = _.difference(allProps, visibleProps); diff --git a/packages/web/src/utility/getConnectionLabel.ts b/packages/web/src/utility/getConnectionLabel.ts index 034e975f..2350ecc8 100644 --- a/packages/web/src/utility/getConnectionLabel.ts +++ b/packages/web/src/utility/getConnectionLabel.ts @@ -24,6 +24,9 @@ function getConnectionLabelCore(connection, { allowExplicitDatabase = true } = { if (connection.singleDatabase && connection.defaultDatabase) { return `${connection.defaultDatabase}`; } + if (connection.useDatabaseUrl) { + return `${connection.databaseUrl}`; + } return ''; } diff --git a/plugins/dbgate-plugin-oracle/src/backend/Analyser.js b/plugins/dbgate-plugin-oracle/src/backend/Analyser.js index e5e39e8f..e95dbb6a 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/Analyser.js +++ b/plugins/dbgate-plugin-oracle/src/backend/Analyser.js @@ -55,8 +55,8 @@ class Analyser extends DatabaseAnalyser { super(pool, driver, version); } - createQuery(resFileName, typeFields) { - const query = super.createQuery(sql[resFileName], typeFields); + createQuery(resFileName, typeFields, replacements = {}) { + const query = super.createQuery(sql[resFileName], typeFields, replacements); //if (query) return query.replace('#REFTABLECOND#', this.driver.__analyserInternals.refTableCond); return query; } @@ -68,40 +68,39 @@ class Analyser extends DatabaseAnalyser { async _runAnalysis() { this.feedback({ analysingMessage: 'Loading tables' }); - const tables = await this.analyserQuery(this.driver.dialect.stringAgg ? 'tableList' : 'tableList', ['tables']); + const tables = await this.analyserQuery('tableList', ['tables'], { $owner: this.pool._schema_name }); this.feedback({ analysingMessage: 'Loading columns' }); - const columns = await this.analyserQuery('columns', ['tables', 'views']); + const columns = await this.analyserQuery('columns', ['tables', 'views'], { $owner: this.pool._schema_name }); this.feedback({ analysingMessage: 'Loading primary keys' }); - const pkColumns = await this.analyserQuery('primaryKeys', ['tables']); + const pkColumns = await this.analyserQuery('primaryKeys', ['tables'], { $owner: this.pool._schema_name }); //let fkColumns = null; this.feedback({ analysingMessage: 'Loading foreign keys' }); - const fkColumns = await this.analyserQuery('foreignKeys', ['tables']); + const fkColumns = await this.analyserQuery('foreignKeys', ['tables'], { $owner: this.pool._schema_name }); this.feedback({ analysingMessage: 'Loading views' }); - const views = await this.analyserQuery('views', ['views']); + const views = await this.analyserQuery('views', ['views'], { $owner: this.pool._schema_name }); let geometryColumns = { rows: [] }; let geographyColumns = { rows: [] }; this.feedback({ analysingMessage: 'Loading materialized views' }); - const matviews = this.driver.dialect.materializedViews ? await this.analyserQuery('matviews', ['matviews']) : null; + const matviews = this.driver.dialect.materializedViews + ? await this.analyserQuery('matviews', ['matviews'], { $owner: this.pool._schema_name }) + : null; this.feedback({ analysingMessage: 'Loading materialized view columns' }); const matviewColumns = this.driver.dialect.materializedViews - ? await this.analyserQuery('matviewColumns', ['matviews']) + ? await this.analyserQuery('matviewColumns', ['matviews'], { $owner: this.pool._schema_name }) : null; this.feedback({ analysingMessage: 'Loading routines' }); - const routines = await this.analyserQuery('routines', ['procedures', 'functions']); + const routines = await this.analyserQuery('routines', ['procedures', 'functions'], { + $owner: this.pool._schema_name, + }); this.feedback({ analysingMessage: 'Loading indexes' }); - const indexes = this.driver.__analyserInternals.skipIndexes - ? { rows: [] } - : await this.analyserQuery('indexes', ['tables']); + const indexes = await this.analyserQuery('indexes', ['tables'], { $owner: this.pool._schema_name }); this.feedback({ analysingMessage: 'Loading index columns' }); - // const indexcols = this.driver.__analyserInternals.skipIndexes - // ? { rows: [] } - // : await this.driver.query(this.pool, this.createQuery('indexcols', ['tables'])); this.feedback({ analysingMessage: 'Loading unique names' }); - const uniqueNames = await this.analyserQuery('uniqueNames', ['tables']); + const uniqueNames = await this.analyserQuery('uniqueNames', ['tables'], { $owner: this.pool._schema_name }); this.feedback({ analysingMessage: 'Finalizing DB structure' }); const fkColumnsMapped = fkColumns.rows.map(x => ({ diff --git a/plugins/dbgate-plugin-oracle/src/backend/drivers.js b/plugins/dbgate-plugin-oracle/src/backend/drivers.js index 388dc177..57ae6d94 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/drivers.js +++ b/plugins/dbgate-plugin-oracle/src/backend/drivers.js @@ -7,7 +7,6 @@ const Analyser = require('./Analyser'); const oracledb = require('oracledb'); const { createBulkInsertStreamBase, makeUniqueColumnNames } = require('dbgate-tools'); - /* pg.types.setTypeParser(1082, 'text', val => val); // date pg.types.setTypeParser(1114, 'text', val => val); // timestamp without timezone @@ -47,6 +46,7 @@ const drivers = driverBases.map(driverBase => ({ database, databaseUrl, useDatabaseUrl, + serviceName, ssl, isReadOnly, authType, @@ -55,8 +55,9 @@ const drivers = driverBases.map(driverBase => ({ client = await oracledb.getConnection({ user, password, - connectString: useDatabaseUrl ? databaseUrl : port ? `${server}:${port}` : server, + connectString: useDatabaseUrl ? databaseUrl : port ? `${server}:${port}/${serviceName}` : server, }); + client._schema_name = database; return client; }, async close(pool) { @@ -64,7 +65,7 @@ const drivers = driverBases.map(driverBase => ({ }, async query(client, sql) { //console.log('query sql', sql); - if (sql == null) { + if (sql == null) {a return { rows: [], columns: [], @@ -250,12 +251,12 @@ const drivers = driverBases.map(driverBase => ({ return pass; }, - async writeTable(pool, name, options) { + async writeTable(pootl, name, options) { // @ts-ignore return createBulkInsertStreamBase(this, stream, pool, name, options); }, async listDatabases(client) { - const { rows } = await this.query(client, 'SELECT instance_name AS "name" FROM v$instance'); + const { rows } = await this.query(client, 'SELECT username as "name" from all_users order by username'); return rows; }, diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/columns.js b/plugins/dbgate-plugin-oracle/src/backend/sql/columns.js index 3e046a39..09b086d7 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/columns.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/columns.js @@ -10,6 +10,6 @@ select data_scale as "numeric_scale", data_default as "default_value" FROM all_tab_columns av - where TABLE_NAME =OBJECT_ID_CONDITION + where OWNER='$owner' AND TABLE_NAME =OBJECT_ID_CONDITION order by column_id `; \ No newline at end of file diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/foreignKeys.js b/plugins/dbgate-plugin-oracle/src/backend/sql/foreignKeys.js index ffaa26f5..4a8b3a89 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/foreignKeys.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/foreignKeys.js @@ -10,7 +10,7 @@ select fk.constraint_name as "constraint_name", basecol.column_name as "column_name", refcol.column_name as "ref_column_name" from all_cons_columns refcol, all_cons_columns basecol, all_constraints ref, all_constraints fk -where fk.constraint_type = 'R' +where fk.OWNER = '$owner' AND fk.constraint_type = 'R' and ref.owner = fk.r_owner and ref.constraint_name = fk.r_constraint_name and basecol.owner = fk.owner diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/indexes.js b/plugins/dbgate-plugin-oracle/src/backend/sql/indexes.js index 32aa1043..2a294606 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/indexes.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/indexes.js @@ -8,7 +8,7 @@ select i.table_name as "tableName", ic.column_position as "postion", ic.descend as "descending" from all_ind_columns ic, all_indexes i -where ic.index_owner = i.owner +where INDEX_OWNER = '$owner' AND ic.index_owner = i.owner and ic.index_name = i.index_name and i.index_name =OBJECT_ID_CONDITION order by i.table_owner, diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/matviewColumns.js b/plugins/dbgate-plugin-oracle/src/backend/sql/matviewColumns.js index 2049c1d3..19545fc3 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/matviewColumns.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/matviewColumns.js @@ -4,6 +4,6 @@ SELECT owner "schema_name" , column_name "column_name" , data_type "data_type" FROM all_tab_columns av - where table_name =OBJECT_ID_CONDITION + where OWNER = '$owner' AND table_name =OBJECT_ID_CONDITION order by column_id `; diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/matviews.js b/plugins/dbgate-plugin-oracle/src/backend/sql/matviews.js index 6504753d..233ecc04 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/matviews.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/matviews.js @@ -14,6 +14,6 @@ SELECT owner as schema_name, '//text()' )) definition FROM all_mviews -where mview_name=OBJECT_ID_CONDITION +where OWNER = '$owner' AND mview_name=OBJECT_ID_CONDITION order by owner, mview_name `; \ No newline at end of file diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/routines.js b/plugins/dbgate-plugin-oracle/src/backend/sql/routines.js index c66004bd..7385514e 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/routines.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/routines.js @@ -32,6 +32,7 @@ from (select all_procedures ap, all_objects ao where + ap.owner = '$owner' and ap.owner = ao.owner and ap.object_name = ao.object_name and ao.object_type in ('PACKAGE', 'PROCEDURE', 'FUNCTION') diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/tableList.js b/plugins/dbgate-plugin-oracle/src/backend/sql/tableList.js index 33ac51bb..81e07e11 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/tableList.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/tableList.js @@ -4,6 +4,6 @@ select table_name "pure_name" from all_tables - where TABLE_NAME =OBJECT_ID_CONDITION + where OWNER='$owner' AND TABLE_NAME =OBJECT_ID_CONDITION `; diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/uniqueNames.js b/plugins/dbgate-plugin-oracle/src/backend/sql/uniqueNames.js index 5832aa80..62a5b12d 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/uniqueNames.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/uniqueNames.js @@ -1,6 +1,6 @@ module.exports = ` select constraint_name from all_constraints -where constraint_type = 'U' +where OWNER='$owner' and constraint_type = 'U' and constraint_name =OBJECT_ID_CONDITION `; diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/views.js b/plugins/dbgate-plugin-oracle/src/backend/sql/views.js index 8e8b33d7..9f10f7fb 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/views.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/views.js @@ -6,7 +6,7 @@ from (select owner as "schema_name", SUBSTR(text_vc, 1, 3900) AS "create_sql" from all_views av - where text_vc is not null + where owner = '$owner' and text_vc is not null ) avv where "pure_name" =OBJECT_ID_CONDITION `; diff --git a/plugins/dbgate-plugin-oracle/src/frontend/drivers.js b/plugins/dbgate-plugin-oracle/src/frontend/drivers.js index 4f253b57..1c04f2a1 100644 --- a/plugins/dbgate-plugin-oracle/src/frontend/drivers.js +++ b/plugins/dbgate-plugin-oracle/src/frontend/drivers.js @@ -19,7 +19,6 @@ const dialect = { quoteIdentifier(s) { return '"' + s + '"'; }, - stringAgg: true, createColumn: true, dropColumn: true, @@ -110,32 +109,15 @@ const oracleDriverBase = { getQuerySplitterOptions: () => oracleSplitterOptions, readOnlySessions: true, - databaseUrlPlaceholder: 'e.g. oracledb://user:password@localhost:1521', + databaseUrlPlaceholder: 'e.g. localhost:1521/orcl', showConnectionField: (field, values) => { if (field == 'useDatabaseUrl') return true; if (values.useDatabaseUrl) { - return ['databaseUrl', 'isReadOnly'].includes(field); + return ['databaseUrl', 'user', 'password'].includes(field); } - return ['user', 'password', 'defaultDatabase', 'singleDatabase', 'isReadOnly', 'server', 'port'].includes(field); - }, - - beforeConnectionSave: connection => { - const { databaseUrl } = connection; - if (databaseUrl) { - const m = databaseUrl.match(/\/([^/]+)($|\?)/); - return { - ...connection, - singleDatabase: !!m, - defaultDatabase: m ? m[1] : null, - }; - } - return connection; - }, - - __analyserInternals: { - refTableCond: '', + return ['user', 'password', 'server', 'port', 'serviceName'].includes(field); }, getNewObjectTemplates() { @@ -189,7 +171,7 @@ const oracleDriver = { return dialect; }, - showConnectionTab: (field) => field == 'sshTunnel', + showConnectionTab: field => field == 'sshTunnel', }; module.exports = [oracleDriver]; diff --git a/plugins/dbgate-plugin-postgres/src/backend/Analyser.js b/plugins/dbgate-plugin-postgres/src/backend/Analyser.js index 4ec6c674..693d0cf1 100644 --- a/plugins/dbgate-plugin-postgres/src/backend/Analyser.js +++ b/plugins/dbgate-plugin-postgres/src/backend/Analyser.js @@ -70,29 +70,23 @@ class Analyser extends DatabaseAnalyser { const tables = await this.analyserQuery(this.driver.dialect.stringAgg ? 'tableModifications' : 'tableList', [ 'tables', ]); - this.logger.debug({ count: tables.rows.length }, 'Tables loaded'); this.feedback({ analysingMessage: 'Loading columns' }); const columns = await this.analyserQuery('columns', ['tables', 'views']); - this.logger.debug({ count: columns.rows.length }, 'Columns loaded'); this.feedback({ analysingMessage: 'Loading primary keys' }); const pkColumns = await this.analyserQuery('primaryKeys', ['tables']); - this.logger.debug({ count: pkColumns.rows.length }, 'Primary keys loaded'); let fkColumns = null; this.feedback({ analysingMessage: 'Loading foreign key constraints' }); const fk_tableConstraints = await this.analyserQuery('fk_tableConstraints', ['tables']); - this.logger.debug({ count: fk_tableConstraints.rows.length }, 'Foreign keys loaded'); this.feedback({ analysingMessage: 'Loading foreign key refs' }); const fk_referentialConstraints = await this.analyserQuery('fk_referentialConstraints', ['tables']); - this.logger.debug({ count: fk_referentialConstraints.rows.length }, 'Foreign key refs loaded'); this.feedback({ analysingMessage: 'Loading foreign key columns' }); const fk_keyColumnUsage = await this.analyserQuery('fk_keyColumnUsage', ['tables']); - this.logger.debug({ count: fk_keyColumnUsage.rows.length }, 'Foreign key columns loaded'); const cntKey = x => `${x.constraint_name}|${x.constraint_schema}`; const fkRows = []; @@ -134,50 +128,41 @@ class Analyser extends DatabaseAnalyser { this.feedback({ analysingMessage: 'Loading views' }); const views = await this.analyserQuery('views', ['views']); - this.logger.debug({ count: views.rows.length }, 'Views loaded'); this.feedback({ analysingMessage: 'Loading materialized views' }); const matviews = this.driver.dialect.materializedViews ? await this.analyserQuery('matviews', ['matviews']) : null; - this.logger.debug({ count: matviews.rows.length }, 'Materialized views loaded'); this.feedback({ analysingMessage: 'Loading materialized view columns' }); const matviewColumns = this.driver.dialect.materializedViews ? await this.analyserQuery('matviewColumns', ['matviews']) : null; - this.logger.debug({ count: matviewColumns.rows.length }, 'Materialized view columns loaded'); this.feedback({ analysingMessage: 'Loading routines' }); const routines = await this.analyserQuery('routines', ['procedures', 'functions']); - this.logger.debug({ count: routines.rows.length }, 'Routines loaded'); this.feedback({ analysingMessage: 'Loading indexes' }); const indexes = this.driver.__analyserInternals.skipIndexes ? { rows: [] } : await this.analyserQuery('indexes', ['tables']); - this.logger.debug({ count: indexes.rows.length }, 'Indexes loaded'); this.feedback({ analysingMessage: 'Loading index columns' }); const indexcols = this.driver.__analyserInternals.skipIndexes ? { rows: [] } : await this.analyserQuery('indexcols', ['tables']); - this.logger.debug({ count: indexcols.rows.length }, 'Indexes columns loaded'); this.feedback({ analysingMessage: 'Loading unique names' }); const uniqueNames = await this.analyserQuery('uniqueNames', ['tables']); - this.logger.debug({ count: uniqueNames.rows.length }, 'Uniques loaded'); let geometryColumns = { rows: [] }; if (views.rows.find(x => x.pure_name == 'geometry_columns' && x.schema_name == 'public')) { this.feedback({ analysingMessage: 'Loading geometry columns' }); geometryColumns = await this.analyserQuery('geometryColumns', ['tables']); - this.logger.debug({ count: geometryColumns.rows.length }, 'Geometry columns loaded'); } let geographyColumns = { rows: [] }; if (views.rows.find(x => x.pure_name == 'geography_columns' && x.schema_name == 'public')) { this.feedback({ analysingMessage: 'Loading geography columns' }); geographyColumns = await this.analyserQuery('geographyColumns', ['tables']); - this.logger.debug({ count: geographyColumns.rows.length }, 'Geography columns loaded'); } this.feedback({ analysingMessage: 'Finalizing DB structure' }); From df60d4013485d534945a8fe2368edc35870c9e81 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Fri, 31 May 2024 15:21:49 +0200 Subject: [PATCH 03/15] oracle - using default schema --- plugins/dbgate-plugin-oracle/src/backend/drivers.js | 3 +++ plugins/dbgate-plugin-oracle/src/backend/sql/columns.js | 2 +- .../dbgate-plugin-oracle/src/backend/sql/foreignKeys.js | 6 +++--- plugins/dbgate-plugin-oracle/src/backend/sql/indexes.js | 2 +- .../src/backend/sql/matviewColumns.js | 4 ++-- plugins/dbgate-plugin-oracle/src/backend/sql/matviews.js | 2 +- .../dbgate-plugin-oracle/src/backend/sql/primaryKeys.js | 2 +- plugins/dbgate-plugin-oracle/src/backend/sql/routines.js | 2 +- .../dbgate-plugin-oracle/src/backend/sql/tableList.js | 2 +- plugins/dbgate-plugin-oracle/src/backend/sql/views.js | 2 +- plugins/dbgate-plugin-oracle/src/frontend/Dumper.js | 9 +++++++++ 11 files changed, 24 insertions(+), 12 deletions(-) diff --git a/plugins/dbgate-plugin-oracle/src/backend/drivers.js b/plugins/dbgate-plugin-oracle/src/backend/drivers.js index 57ae6d94..eb10a4e5 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/drivers.js +++ b/plugins/dbgate-plugin-oracle/src/backend/drivers.js @@ -57,6 +57,9 @@ const drivers = driverBases.map(driverBase => ({ password, connectString: useDatabaseUrl ? databaseUrl : port ? `${server}:${port}/${serviceName}` : server, }); + if (database) { + await client.execute(`ALTER SESSION SET CURRENT_SCHEMA = ${database}`); + } client._schema_name = database; return client; }, diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/columns.js b/plugins/dbgate-plugin-oracle/src/backend/sql/columns.js index 09b086d7..f605bb3b 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/columns.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/columns.js @@ -1,6 +1,6 @@ module.exports = ` select - owner as "schema_name", + -- owner as "schema_name", table_name as "pure_name", column_name as "column_name", nullable as "is_nullable", diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/foreignKeys.js b/plugins/dbgate-plugin-oracle/src/backend/sql/foreignKeys.js index 4a8b3a89..945ae784 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/foreignKeys.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/foreignKeys.js @@ -1,12 +1,12 @@ module.exports = ` select fk.constraint_name as "constraint_name", - fk.owner as "constraint_schema", + -- fk.owner as "constraint_schema", fk.table_name as "pure_name", - fk.owner as "schema_name", + -- fk.owner as "schema_name", fk.delete_rule as "update_action", fk.delete_rule as "delete_action", ref.table_name as "ref_table_name", - ref.owner as "ref_schema_name", + -- ref.owner as "ref_schema_name", basecol.column_name as "column_name", refcol.column_name as "ref_column_name" from all_cons_columns refcol, all_cons_columns basecol, all_constraints ref, all_constraints fk diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/indexes.js b/plugins/dbgate-plugin-oracle/src/backend/sql/indexes.js index 2a294606..b1eb9d2e 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/indexes.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/indexes.js @@ -1,6 +1,6 @@ module.exports = ` select i.table_name as "tableName", - i.table_owner as "schemaName", + -- i.table_owner as "schemaName", i.index_name as "constraintName", i.index_type as "indexType", i.uniqueness as "Unique", diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/matviewColumns.js b/plugins/dbgate-plugin-oracle/src/backend/sql/matviewColumns.js index 19545fc3..85f60334 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/matviewColumns.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/matviewColumns.js @@ -1,6 +1,6 @@ module.exports = ` -SELECT owner "schema_name" - , table_name "pure_name" +SELECT -- owner "schema_name" + table_name "pure_name" , column_name "column_name" , data_type "data_type" FROM all_tab_columns av diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/matviews.js b/plugins/dbgate-plugin-oracle/src/backend/sql/matviews.js index 233ecc04..dad92438 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/matviews.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/matviews.js @@ -1,5 +1,5 @@ module.exports = ` -SELECT owner as schema_name, +SELECT -- owner as schema_name, mview_name pure_name, container_name, '' || trim( diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/primaryKeys.js b/plugins/dbgate-plugin-oracle/src/backend/sql/primaryKeys.js index 6d10262d..ffe38fc3 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/primaryKeys.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/primaryKeys.js @@ -1,6 +1,6 @@ module.exports = ` select - pk.owner as "constraint_schema", + -- pk.owner as "constraint_schema", pk.constraint_name as "constraint_name", pk.owner as "schema_name", pk.table_name as "pure_name", diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/routines.js b/plugins/dbgate-plugin-oracle/src/backend/sql/routines.js index 7385514e..533d9d96 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/routines.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/routines.js @@ -1,7 +1,7 @@ module.exports = ` select routine_name as "pure_name", - routine_schema as "schema_name", + -- routine_schema as "schema_name", routine_definition as "definition", standard_hash(routine_definition, 'MD5') as "hash_code", routine_type as "object_type", diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/tableList.js b/plugins/dbgate-plugin-oracle/src/backend/sql/tableList.js index 81e07e11..0a4ab93f 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/tableList.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/tableList.js @@ -1,6 +1,6 @@ module.exports = ` select - owner "schema_name", + -- owner "schema_name", table_name "pure_name" from all_tables diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/views.js b/plugins/dbgate-plugin-oracle/src/backend/sql/views.js index 9f10f7fb..d001c8d9 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/views.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/views.js @@ -3,7 +3,7 @@ select avv.*, ora_hash("create_sql") as "hash_code" from (select view_name as "pure_name", - owner as "schema_name", + -- owner as "schema_name", SUBSTR(text_vc, 1, 3900) AS "create_sql" from all_views av where owner = '$owner' and text_vc is not null diff --git a/plugins/dbgate-plugin-oracle/src/frontend/Dumper.js b/plugins/dbgate-plugin-oracle/src/frontend/Dumper.js index d47aa78d..b60deb8f 100644 --- a/plugins/dbgate-plugin-oracle/src/frontend/Dumper.js +++ b/plugins/dbgate-plugin-oracle/src/frontend/Dumper.js @@ -1,6 +1,15 @@ const { SqlDumper, arrayToHexString, testEqualTypes } = global.DBGATE_TOOLS; class Dumper extends SqlDumper { + createDatabase(name) { + this.putCmd(`CREATE USER c##${name} + IDENTIFIED BY ${name} + DEFAULT TABLESPACE users + TEMPORARY TABLESPACE temp + QUOTA 10M ON users;`, name); + } + + /** @param type {import('dbgate-types').TransformType} */ transform(type, dumpExpr) { switch (type) { From 8f5b395935d11c41cd1c096cfffd53b33fca2bc6 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Fri, 31 May 2024 16:06:39 +0200 Subject: [PATCH 04/15] oracle analyser code cleanup --- plugins/dbgate-plugin-oracle/src/backend/Analyser.js | 9 +-------- .../src/backend/sql/fk_key_column_usage.js | 2 -- .../src/backend/sql/fk_referential_constraints.js | 2 -- .../src/backend/sql/fk_table_constraints.js | 2 -- .../src/backend/sql/geographyColumns.js | 2 -- .../src/backend/sql/geometryColumns.js | 2 -- plugins/dbgate-plugin-oracle/src/backend/sql/index.js | 10 ---------- .../dbgate-plugin-oracle/src/backend/sql/indexcols.js | 2 -- .../src/backend/sql/matviewColumns.js | 9 --------- .../src/backend/sql/matviewModifications.js | 2 -- .../src/backend/sql/primaryKeys.js | 3 ++- .../src/backend/sql/routineModifications.js | 2 -- .../src/backend/sql/tableModifications.js | 2 -- .../src/backend/sql/viewModifications.js | 2 -- 14 files changed, 3 insertions(+), 48 deletions(-) delete mode 100644 plugins/dbgate-plugin-oracle/src/backend/sql/fk_key_column_usage.js delete mode 100644 plugins/dbgate-plugin-oracle/src/backend/sql/fk_referential_constraints.js delete mode 100644 plugins/dbgate-plugin-oracle/src/backend/sql/fk_table_constraints.js delete mode 100644 plugins/dbgate-plugin-oracle/src/backend/sql/geographyColumns.js delete mode 100644 plugins/dbgate-plugin-oracle/src/backend/sql/geometryColumns.js delete mode 100644 plugins/dbgate-plugin-oracle/src/backend/sql/indexcols.js delete mode 100644 plugins/dbgate-plugin-oracle/src/backend/sql/matviewColumns.js delete mode 100644 plugins/dbgate-plugin-oracle/src/backend/sql/matviewModifications.js delete mode 100644 plugins/dbgate-plugin-oracle/src/backend/sql/routineModifications.js delete mode 100644 plugins/dbgate-plugin-oracle/src/backend/sql/tableModifications.js delete mode 100644 plugins/dbgate-plugin-oracle/src/backend/sql/viewModifications.js diff --git a/plugins/dbgate-plugin-oracle/src/backend/Analyser.js b/plugins/dbgate-plugin-oracle/src/backend/Analyser.js index e95dbb6a..c1d14d92 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/Analyser.js +++ b/plugins/dbgate-plugin-oracle/src/backend/Analyser.js @@ -88,17 +88,12 @@ class Analyser extends DatabaseAnalyser { const matviews = this.driver.dialect.materializedViews ? await this.analyserQuery('matviews', ['matviews'], { $owner: this.pool._schema_name }) : null; - this.feedback({ analysingMessage: 'Loading materialized view columns' }); - const matviewColumns = this.driver.dialect.materializedViews - ? await this.analyserQuery('matviewColumns', ['matviews'], { $owner: this.pool._schema_name }) - : null; this.feedback({ analysingMessage: 'Loading routines' }); const routines = await this.analyserQuery('routines', ['procedures', 'functions'], { $owner: this.pool._schema_name, }); this.feedback({ analysingMessage: 'Loading indexes' }); const indexes = await this.analyserQuery('indexes', ['tables'], { $owner: this.pool._schema_name }); - this.feedback({ analysingMessage: 'Loading index columns' }); this.feedback({ analysingMessage: 'Loading unique names' }); const uniqueNames = await this.analyserQuery('uniqueNames', ['tables'], { $owner: this.pool._schema_name }); this.feedback({ analysingMessage: 'Finalizing DB structure' }); @@ -187,9 +182,7 @@ class Analyser extends DatabaseAnalyser { schemaName: matview.schema_name, contentHash: matview.hash_code, createSql: `CREATE MATERIALIZED VIEW "${matview.schema_name}"."${matview.pure_name}"\nAS\n${matview.definition}`, - columns: matviewColumns.rows - .filter(col => col.pure_name == matview.pure_name && col.schema_name == matview.schema_name) - .map(col => getColumnInfo(col)), + columns: (columnsGrouped[columnGroup(view)] || []).map(col => getColumnInfo(col)), })) : undefined, procedures: routines.rows diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/fk_key_column_usage.js b/plugins/dbgate-plugin-oracle/src/backend/sql/fk_key_column_usage.js deleted file mode 100644 index 1cb29038..00000000 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/fk_key_column_usage.js +++ /dev/null @@ -1,2 +0,0 @@ -module.exports = ` -`; diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/fk_referential_constraints.js b/plugins/dbgate-plugin-oracle/src/backend/sql/fk_referential_constraints.js deleted file mode 100644 index 1cb29038..00000000 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/fk_referential_constraints.js +++ /dev/null @@ -1,2 +0,0 @@ -module.exports = ` -`; diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/fk_table_constraints.js b/plugins/dbgate-plugin-oracle/src/backend/sql/fk_table_constraints.js deleted file mode 100644 index 1cb29038..00000000 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/fk_table_constraints.js +++ /dev/null @@ -1,2 +0,0 @@ -module.exports = ` -`; diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/geographyColumns.js b/plugins/dbgate-plugin-oracle/src/backend/sql/geographyColumns.js deleted file mode 100644 index 5b78f239..00000000 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/geographyColumns.js +++ /dev/null @@ -1,2 +0,0 @@ -module.exports = ` -`; \ No newline at end of file diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/geometryColumns.js b/plugins/dbgate-plugin-oracle/src/backend/sql/geometryColumns.js deleted file mode 100644 index 5b78f239..00000000 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/geometryColumns.js +++ /dev/null @@ -1,2 +0,0 @@ -module.exports = ` -`; \ No newline at end of file diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/index.js b/plugins/dbgate-plugin-oracle/src/backend/sql/index.js index 3c3eb665..ca1b3f24 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/index.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/index.js @@ -1,15 +1,10 @@ const columns = require('./columns'); -const tableModifications = require('./tableList'); const tableList = require('./tableList'); -const viewModifications = require('./views'); -const matviewModifications = require('./matviews'); const primaryKeys = require('./primaryKeys'); const foreignKeys = require('./foreignKeys'); const views = require('./views'); const matviews = require('./matviews'); const routines = require('./routines'); -const routineModifications = require('./routines'); -const matviewColumns = require('./matviewColumns'); const indexes = require('./indexes'); // use mysql //const indexcols = require('./indexcols'); const uniqueNames = require('./uniqueNames'); @@ -22,17 +17,12 @@ const uniqueNames = require('./uniqueNames'); module.exports = { columns, - tableModifications, tableList, - viewModifications, primaryKeys, foreignKeys, views, routines, - routineModifications, matviews, - matviewModifications, - matviewColumns, indexes, // indexcols, uniqueNames, diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/indexcols.js b/plugins/dbgate-plugin-oracle/src/backend/sql/indexcols.js deleted file mode 100644 index 1cb29038..00000000 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/indexcols.js +++ /dev/null @@ -1,2 +0,0 @@ -module.exports = ` -`; diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/matviewColumns.js b/plugins/dbgate-plugin-oracle/src/backend/sql/matviewColumns.js deleted file mode 100644 index 85f60334..00000000 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/matviewColumns.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = ` -SELECT -- owner "schema_name" - table_name "pure_name" - , column_name "column_name" - , data_type "data_type" - FROM all_tab_columns av - where OWNER = '$owner' AND table_name =OBJECT_ID_CONDITION -order by column_id -`; diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/matviewModifications.js b/plugins/dbgate-plugin-oracle/src/backend/sql/matviewModifications.js deleted file mode 100644 index 1cb29038..00000000 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/matviewModifications.js +++ /dev/null @@ -1,2 +0,0 @@ -module.exports = ` -`; diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/primaryKeys.js b/plugins/dbgate-plugin-oracle/src/backend/sql/primaryKeys.js index ffe38fc3..a5ac5f73 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/primaryKeys.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/primaryKeys.js @@ -2,7 +2,7 @@ module.exports = ` select -- pk.owner as "constraint_schema", pk.constraint_name as "constraint_name", - pk.owner as "schema_name", + -- pk.owner as "schema_name", pk.table_name as "pure_name", basecol.column_name as "column_name" from all_cons_columns basecol, @@ -12,5 +12,6 @@ and basecol.owner = pk.owner and basecol.constraint_name = pk.constraint_name and basecol.table_name = pk.table_name and pk.constraint_name =OBJECT_ID_CONDITION +and pk.owner = '$owner' order by basecol.position `; diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/routineModifications.js b/plugins/dbgate-plugin-oracle/src/backend/sql/routineModifications.js deleted file mode 100644 index 1cb29038..00000000 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/routineModifications.js +++ /dev/null @@ -1,2 +0,0 @@ -module.exports = ` -`; diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/tableModifications.js b/plugins/dbgate-plugin-oracle/src/backend/sql/tableModifications.js deleted file mode 100644 index 1cb29038..00000000 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/tableModifications.js +++ /dev/null @@ -1,2 +0,0 @@ -module.exports = ` -`; diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/viewModifications.js b/plugins/dbgate-plugin-oracle/src/backend/sql/viewModifications.js deleted file mode 100644 index 1cb29038..00000000 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/viewModifications.js +++ /dev/null @@ -1,2 +0,0 @@ -module.exports = ` -`; From 2d1ac9719172c0089479cbf42045426cea5d7351 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Fri, 31 May 2024 16:45:33 +0200 Subject: [PATCH 05/15] oracle: fixed analysing constraints --- plugins/dbgate-plugin-oracle/src/backend/Analyser.js | 5 +++-- plugins/dbgate-plugin-oracle/src/backend/sql/indexes.js | 1 - plugins/dbgate-plugin-oracle/src/backend/sql/uniqueNames.js | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/dbgate-plugin-oracle/src/backend/Analyser.js b/plugins/dbgate-plugin-oracle/src/backend/Analyser.js index c1d14d92..07b45835 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/Analyser.js +++ b/plugins/dbgate-plugin-oracle/src/backend/Analyser.js @@ -139,7 +139,7 @@ class Analyser extends DatabaseAnalyser { indexes: _.uniqBy( indexes.rows.filter( idx => - idx.tableName == table.pureName && !uniqueNames.rows.find(x => x.constraintName == idx.constraintName) + idx.tableName == newTable.pureName && !uniqueNames.rows.find(x => x.constraintName == idx.constraintName) ), 'constraintName' ).map(idx => ({ @@ -149,12 +149,13 @@ class Analyser extends DatabaseAnalyser { .filter(col => col.tableName == idx.tableName && col.constraintName == idx.constraintName) .map(col => ({ ..._.pick(col, ['columnName']), + isDescending: col.descending == 'DESC', })), })), uniques: _.uniqBy( indexes.rows.filter( idx => - idx.tableName == table.pureName && uniqueNames.rows.find(x => x.constraintName == idx.constraintName) + idx.tableName == newTable.pureName && uniqueNames.rows.find(x => x.constraintName == idx.constraintName) ), 'constraintName' ).map(idx => ({ diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/indexes.js b/plugins/dbgate-plugin-oracle/src/backend/sql/indexes.js index b1eb9d2e..fae13e68 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/indexes.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/indexes.js @@ -5,7 +5,6 @@ select i.table_name as "tableName", i.index_type as "indexType", i.uniqueness as "Unique", ic.column_name as "columnName", - ic.column_position as "postion", ic.descend as "descending" from all_ind_columns ic, all_indexes i where INDEX_OWNER = '$owner' AND ic.index_owner = i.owner diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/uniqueNames.js b/plugins/dbgate-plugin-oracle/src/backend/sql/uniqueNames.js index 62a5b12d..b2d7d964 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/uniqueNames.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/uniqueNames.js @@ -1,6 +1,6 @@ module.exports = ` -select constraint_name +select constraint_name as "constraintName" from all_constraints -where OWNER='$owner' and constraint_type = 'U' +where owner='$owner' and constraint_type = 'U' and constraint_name =OBJECT_ID_CONDITION `; From ebdcd9ad941a68df5343b0810fc900b3e7263a88 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Fri, 31 May 2024 16:49:43 +0200 Subject: [PATCH 06/15] oracle: detect autoincrement column --- .../src/backend/Analyser.js | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/plugins/dbgate-plugin-oracle/src/backend/Analyser.js b/plugins/dbgate-plugin-oracle/src/backend/Analyser.js index 07b45835..9adfa279 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/Analyser.js +++ b/plugins/dbgate-plugin-oracle/src/backend/Analyser.js @@ -22,25 +22,7 @@ function getColumnInfo( if (char_max_length && isTypeString(normDataType)) fullDataType = `${normDataType}(${char_max_length})`; if (numeric_precision && numeric_ccale && isTypeNumeric(normDataType)) fullDataType = `${normDataType}(${numeric_precision},${numeric_ccale})`; - const autoIncrement = !!(default_value && default_value.startsWith('nextval(')); - if ( - table && - geometryColumns && - geometryColumns.rows.find( - x => x.schema_name == table.schemaName && x.pure_name == table.pureName && x.column_name == column_name - ) - ) { - fullDataType = 'geometry'; - } - if ( - table && - geographyColumns && - geographyColumns.rows.find( - x => x.schema_name == table.schemaName && x.pure_name == table.pureName && x.column_name == column_name - ) - ) { - fullDataType = 'geography'; - } + const autoIncrement = !!(default_value && default_value.endsWith('.nextval')); return { columnName: column_name, dataType: fullDataType, From 1f75a818c81bb98de06a4fc79163271f0c430ebd Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Fri, 31 May 2024 17:03:35 +0200 Subject: [PATCH 07/15] oracle: code cleanup, not null detection --- .../src/backend/Analyser.js | 74 ++----------------- 1 file changed, 5 insertions(+), 69 deletions(-) diff --git a/plugins/dbgate-plugin-oracle/src/backend/Analyser.js b/plugins/dbgate-plugin-oracle/src/backend/Analyser.js index 9adfa279..b4eb03d8 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/Analyser.js +++ b/plugins/dbgate-plugin-oracle/src/backend/Analyser.js @@ -13,9 +13,7 @@ function normalizeTypeName(dataType) { function getColumnInfo( { is_nullable, column_name, data_type, char_max_length, numeric_precision, numeric_ccale, default_value }, - table = undefined, - geometryColumns = undefined, - geographyColumns = undefined + table = undefined ) { const normDataType = normalizeTypeName(data_type); let fullDataType = normDataType; @@ -26,7 +24,7 @@ function getColumnInfo( return { columnName: column_name, dataType: fullDataType, - notNull: !is_nullable || is_nullable == 'NO' || is_nullable == 'no', + notNull: is_nullable == 'N', defaultValue: autoIncrement ? undefined : default_value, autoIncrement, }; @@ -63,8 +61,6 @@ class Analyser extends DatabaseAnalyser { const fkColumns = await this.analyserQuery('foreignKeys', ['tables'], { $owner: this.pool._schema_name }); this.feedback({ analysingMessage: 'Loading views' }); const views = await this.analyserQuery('views', ['views'], { $owner: this.pool._schema_name }); - let geometryColumns = { rows: [] }; - let geographyColumns = { rows: [] }; this.feedback({ analysingMessage: 'Loading materialized views' }); const matviews = this.driver.dialect.materializedViews @@ -113,15 +109,14 @@ class Analyser extends DatabaseAnalyser { }; return { ...newTable, - columns: (columnsGrouped[columnGroup(table)] || []).map(col => - getColumnInfo(col, newTable, geometryColumns, geographyColumns) - ), + columns: (columnsGrouped[columnGroup(table)] || []).map(col => getColumnInfo(col, newTable)), primaryKey: DatabaseAnalyser.extractPrimaryKeys(newTable, pkColumnsMapped), foreignKeys: DatabaseAnalyser.extractForeignKeys(newTable, fkColumnsMapped), indexes: _.uniqBy( indexes.rows.filter( idx => - idx.tableName == newTable.pureName && !uniqueNames.rows.find(x => x.constraintName == idx.constraintName) + idx.tableName == newTable.pureName && + !uniqueNames.rows.find(x => x.constraintName == idx.constraintName) ), 'constraintName' ).map(idx => ({ @@ -188,69 +183,10 @@ class Analyser extends DatabaseAnalyser { })), }; - // this.feedback({ analysingMessage: 'Debug sleep' }); - // await new Promise(resolve => setTimeout(resolve, 90 * 1000)); - this.feedback({ analysingMessage: null }); return res; } - - async _getFastSnapshot() { - return null; - - const tableModificationsQueryData = this.driver.dialect.stringAgg - ? await this.analyserQuery('tableModifications') - : null; - const viewModificationsQueryData = await this.analyserQuery('viewModifications'); - const matviewModificationsQueryData = this.driver.dialect.materializedViews - ? await this.analyserQuery('matviewModifications') - : null; - const routineModificationsQueryData = await this.analyserQuery('routineModifications'); - - return { - tables: tableModificationsQueryData - ? tableModificationsQueryData.rows.map(x => ({ - objectId: `tables:${x.schema_name}.${x.pure_name}`, - pureName: x.pure_name, - schemaName: x.schema_name, - contentHash: `${x.hash_code_columns}-${x.hash_code_constraints}`, - })) - : null, - views: viewModificationsQueryData - ? viewModificationsQueryData.rows.map(x => ({ - objectId: `views:${x.schema_name}.${x.pure_name}`, - pureName: x.pure_name, - schemaName: x.schema_name, - contentHash: x.hash_code, - })) - : undefined, - matviews: matviewModificationsQueryData - ? matviewModificationsQueryData.rows.map(x => ({ - objectId: `matviews:${x.schema_name}.${x.pure_name}`, - pureName: x.pure_name, - schemaName: x.schema_name, - contentHash: x.hash_code, - })) - : undefined, - procedures: routineModificationsQueryData.rows - .filter(x => x.object_type == 'PROCEDURE') - .map(x => ({ - objectId: `procedures:${x.schema_name}.${x.pure_name}`, - pureName: x.pure_name, - schemaName: x.schema_name, - contentHash: x.hash_code, - })), - functions: routineModificationsQueryData.rows - .filter(x => x.object_type == 'FUNCTION') - .map(x => ({ - objectId: `functions:${x.schema_name}.${x.pure_name}`, - pureName: x.pure_name, - schemaName: x.schema_name, - contentHash: x.hash_code, - })), - }; - } } module.exports = Analyser; From bbf2e2f7edc1fdbddde6d7f81e00f3873f8f909b Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 1 Jun 2024 08:12:18 +0200 Subject: [PATCH 08/15] fixes --- .../src/frontend/drivers.js | 69 +++++++------------ 1 file changed, 25 insertions(+), 44 deletions(-) diff --git a/plugins/dbgate-plugin-oracle/src/frontend/drivers.js b/plugins/dbgate-plugin-oracle/src/frontend/drivers.js index 1c04f2a1..2aa6d790 100644 --- a/plugins/dbgate-plugin-oracle/src/frontend/drivers.js +++ b/plugins/dbgate-plugin-oracle/src/frontend/drivers.js @@ -6,7 +6,7 @@ const spatialTypes = ['GEOGRAPHY']; /** @type {import('dbgate-types').SqlDialect} */ const dialect = { - rangeSelect: false, + rangeSelect: true, limitSelect: false, offsetFetchRangeSyntax: true, ilike: true, @@ -37,49 +37,30 @@ const dialect = { dropReferencesWhenDropTable: true, predefinedDataTypes: [ - 'bigint', - 'bigserial', - 'bit', - 'varbit', - 'boolean', - 'box', - 'bytea', - 'char(20)', - 'varchar(250)', - 'cidr', - 'circle', - 'date', - 'double precision', - 'inet', - 'int', - 'interval', - 'json', - 'jsonb', - 'line', - 'lseg', - 'macaddr', - 'macaddr8', - 'money', - 'numeric(10,2)', - 'path', - 'pg_lsn', - 'pg_snapshot', - 'point', - 'polygon', - 'real', - 'smallint', - 'smallserial', - 'serial', - 'text', - 'time', - 'timetz', - 'timestamp', - 'timestamptz', - 'tsquery', - 'tsvector', - 'txid_snapshot', - 'uuid', - 'xml', + 'VARCHAR2', + 'NUMBER', + 'DATE', + 'CLOB', + 'BLOB', + 'INTEGER', + + 'BFILE', + 'BINARY_DOUBLE', + 'BINARY_FLOAT', + 'CHAR', + 'FLOAT', + 'INTERVAL DAY', + 'INTERVAL YEAR', + 'LONG', + 'LONG RAW', + 'NCHAR', + 'NCLOB', + 'NVARCHAR2', + 'RAW', + 'ROWID', + 'TIMESTAMP', + 'UROWID', + // 'XMLTYPE', ], createColumnViewExpression(columnName, dataType, source, alias) { From 68a40e5da6caf4c013640ae0eb332b435a7f9c27 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 1 Jun 2024 08:16:37 +0200 Subject: [PATCH 09/15] oracle: upgraded query spliiter --- packages/api/package.json | 2 +- packages/tools/package.json | 2 +- packages/web/package.json | 2 +- plugins/dbgate-plugin-mongo/package.json | 2 +- plugins/dbgate-plugin-mssql/package.json | 2 +- plugins/dbgate-plugin-mysql/package.json | 2 +- plugins/dbgate-plugin-oracle/package.json | 2 +- plugins/dbgate-plugin-postgres/package.json | 2 +- plugins/dbgate-plugin-redis/package.json | 2 +- plugins/dbgate-plugin-sqlite/package.json | 2 +- yarn.lock | 8 ++++---- 11 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/api/package.json b/packages/api/package.json index f56c346c..2ee30f82 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -27,7 +27,7 @@ "cors": "^2.8.5", "cross-env": "^6.0.3", "dbgate-datalib": "^5.0.0-alpha.1", - "dbgate-query-splitter": "^4.9.3", + "dbgate-query-splitter": "^4.10.1", "dbgate-sqltree": "^5.0.0-alpha.1", "dbgate-tools": "^5.0.0-alpha.1", "debug": "^4.3.4", diff --git a/packages/tools/package.json b/packages/tools/package.json index 74053dc9..e63be9a8 100644 --- a/packages/tools/package.json +++ b/packages/tools/package.json @@ -31,7 +31,7 @@ "typescript": "^4.4.3" }, "dependencies": { - "dbgate-query-splitter": "^4.9.3", + "dbgate-query-splitter": "^4.10.1", "dbgate-sqltree": "^5.0.0-alpha.1", "debug": "^4.3.4", "json-stable-stringify": "^1.0.1", diff --git a/packages/web/package.json b/packages/web/package.json index ae7f0429..8e405fa9 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -24,7 +24,7 @@ "chartjs-adapter-moment": "^1.0.0", "cross-env": "^7.0.3", "dbgate-datalib": "^5.0.0-alpha.1", - "dbgate-query-splitter": "^4.9.3", + "dbgate-query-splitter": "^4.10.1", "dbgate-sqltree": "^5.0.0-alpha.1", "dbgate-tools": "^5.0.0-alpha.1", "dbgate-types": "^5.0.0-alpha.1", diff --git a/plugins/dbgate-plugin-mongo/package.json b/plugins/dbgate-plugin-mongo/package.json index 00d208bb..d7b2ad15 100644 --- a/plugins/dbgate-plugin-mongo/package.json +++ b/plugins/dbgate-plugin-mongo/package.json @@ -32,7 +32,7 @@ }, "devDependencies": { "dbgate-plugin-tools": "^1.0.7", - "dbgate-query-splitter": "^4.9.3", + "dbgate-query-splitter": "^4.10.1", "webpack": "^5.91.0", "webpack-cli": "^5.1.4", "dbgate-tools": "^5.0.0-alpha.1", diff --git a/plugins/dbgate-plugin-mssql/package.json b/plugins/dbgate-plugin-mssql/package.json index 48478dae..850dfbf4 100644 --- a/plugins/dbgate-plugin-mssql/package.json +++ b/plugins/dbgate-plugin-mssql/package.json @@ -32,7 +32,7 @@ }, "devDependencies": { "dbgate-plugin-tools": "^1.0.7", - "dbgate-query-splitter": "^4.9.3", + "dbgate-query-splitter": "^4.10.1", "webpack": "^5.91.0", "webpack-cli": "^5.1.4", "dbgate-tools": "^5.0.0-alpha.1", diff --git a/plugins/dbgate-plugin-mysql/package.json b/plugins/dbgate-plugin-mysql/package.json index 34454cc0..4cb74235 100644 --- a/plugins/dbgate-plugin-mysql/package.json +++ b/plugins/dbgate-plugin-mysql/package.json @@ -33,7 +33,7 @@ "devDependencies": { "antares-mysql-dumper": "^0.0.1", "dbgate-plugin-tools": "^1.0.7", - "dbgate-query-splitter": "^4.9.3", + "dbgate-query-splitter": "^4.10.1", "dbgate-tools": "^5.0.0-alpha.1", "mysql2": "^3.9.7", "webpack": "^5.91.0", diff --git a/plugins/dbgate-plugin-oracle/package.json b/plugins/dbgate-plugin-oracle/package.json index ba6d05e6..37b02879 100644 --- a/plugins/dbgate-plugin-oracle/package.json +++ b/plugins/dbgate-plugin-oracle/package.json @@ -31,7 +31,7 @@ }, "devDependencies": { "dbgate-plugin-tools": "^1.0.8", - "dbgate-query-splitter": "^4.9.0", + "dbgate-query-splitter": "^4.10.1", "dbgate-tools": "^5.0.0-alpha.1", "lodash": "^4.17.21", "webpack": "^5.91.0", diff --git a/plugins/dbgate-plugin-postgres/package.json b/plugins/dbgate-plugin-postgres/package.json index d2a6d452..29bcc34e 100644 --- a/plugins/dbgate-plugin-postgres/package.json +++ b/plugins/dbgate-plugin-postgres/package.json @@ -31,7 +31,7 @@ }, "devDependencies": { "dbgate-plugin-tools": "^1.0.7", - "dbgate-query-splitter": "^4.9.3", + "dbgate-query-splitter": "^4.10.1", "dbgate-tools": "^5.0.0-alpha.1", "lodash": "^4.17.21", "pg": "^8.11.5", diff --git a/plugins/dbgate-plugin-redis/package.json b/plugins/dbgate-plugin-redis/package.json index f2b449e5..8b437602 100644 --- a/plugins/dbgate-plugin-redis/package.json +++ b/plugins/dbgate-plugin-redis/package.json @@ -30,7 +30,7 @@ }, "devDependencies": { "dbgate-plugin-tools": "^1.0.7", - "dbgate-query-splitter": "^4.9.3", + "dbgate-query-splitter": "^4.10.1", "dbgate-tools": "^5.0.0-alpha.1", "lodash": "^4.17.21", "webpack": "^5.91.0", diff --git a/plugins/dbgate-plugin-sqlite/package.json b/plugins/dbgate-plugin-sqlite/package.json index b79d5a38..d1569804 100644 --- a/plugins/dbgate-plugin-sqlite/package.json +++ b/plugins/dbgate-plugin-sqlite/package.json @@ -32,7 +32,7 @@ "devDependencies": { "dbgate-tools": "^5.0.0-alpha.1", "dbgate-plugin-tools": "^1.0.4", - "dbgate-query-splitter": "^4.9.3", + "dbgate-query-splitter": "^4.10.1", "byline": "^5.0.0", "webpack": "^5.91.0", "webpack-cli": "^5.1.4" diff --git a/yarn.lock b/yarn.lock index f74f131b..7c89521b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3202,10 +3202,10 @@ dbgate-plugin-xml@^5.0.0-alpha.1: resolved "https://registry.yarnpkg.com/dbgate-plugin-xml/-/dbgate-plugin-xml-5.2.7.tgz#0762af51ba6f100e75a63907ea6c679e827c9f7c" integrity sha512-gBXy4qetf7eJQW6lM01B+OKLnKB8MKesojdYKysD9oZ+YpQCX8Tq7aHJCrN14FiyIDinpX61kmFH1+LGJ2RkxQ== -dbgate-query-splitter@^4.9.0, dbgate-query-splitter@^4.9.3: - version "4.9.3" - resolved "https://registry.yarnpkg.com/dbgate-query-splitter/-/dbgate-query-splitter-4.9.3.tgz#f66396da9ae3cc8f775a282143bfca3441248aa2" - integrity sha512-QMppAy3S6NGQMawNokmhbpZURvLCETyu/8yTfqWUHGdlK963fdSpmoX1A+9SjCDp62sX0vYntfD7uzd6jVSRcw== +dbgate-query-splitter@^4.10.1: + version "4.10.1" + resolved "https://registry.yarnpkg.com/dbgate-query-splitter/-/dbgate-query-splitter-4.10.1.tgz#dc40d792de06f779a743cad054d5e786006b03a9" + integrity sha512-KqrB7NLP1jXbx8rN7gSmYUVorm6ICeqOV+oR+jHaBLXqqhWepHsKr6JJlFEeb/LhoVjnTDY/cy5zhW1dMIQF6A== debug@2.6.9, debug@^2.2.0, debug@^2.3.3: version "2.6.9" From 0cc7a983916a7a6782662147e39315811c24108e Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 1 Jun 2024 08:36:13 +0200 Subject: [PATCH 10/15] oracle: fixed commit --- .../src/backend/drivers.js | 7 +- .../src/frontend/Dumper.js | 177 +++++++++--------- 2 files changed, 96 insertions(+), 88 deletions(-) diff --git a/plugins/dbgate-plugin-oracle/src/backend/drivers.js b/plugins/dbgate-plugin-oracle/src/backend/drivers.js index eb10a4e5..2520bb5b 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/drivers.js +++ b/plugins/dbgate-plugin-oracle/src/backend/drivers.js @@ -67,8 +67,11 @@ const drivers = driverBases.map(driverBase => ({ return pool.end(); }, async query(client, sql) { - //console.log('query sql', sql); - if (sql == null) {a + if (sql.trim() == 'COMMIT;') { + sql = 'COMMIT'; + } + + if (sql == null) { return { rows: [], columns: [], diff --git a/plugins/dbgate-plugin-oracle/src/frontend/Dumper.js b/plugins/dbgate-plugin-oracle/src/frontend/Dumper.js index b60deb8f..9c8a2f9f 100644 --- a/plugins/dbgate-plugin-oracle/src/frontend/Dumper.js +++ b/plugins/dbgate-plugin-oracle/src/frontend/Dumper.js @@ -2,108 +2,113 @@ const { SqlDumper, arrayToHexString, testEqualTypes } = global.DBGATE_TOOLS; class Dumper extends SqlDumper { createDatabase(name) { - this.putCmd(`CREATE USER c##${name} + this.putCmd( + `CREATE USER c##${name} IDENTIFIED BY ${name} DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp - QUOTA 10M ON users;`, name); + QUOTA 10M ON users;`, + name + ); } + // oracle uses implicit transactions + beginTransaction() {} - /** @param type {import('dbgate-types').TransformType} */ - transform(type, dumpExpr) { - switch (type) { - case 'GROUP:YEAR': - case 'YEAR': - this.put('^extract(^year ^from %c)', dumpExpr); - break; - case 'MONTH': - this.put('^extract(^month ^from %c)', dumpExpr); - break; - case 'DAY': - this.put('^extract(^day ^from %c)', dumpExpr); - break; - case 'GROUP:MONTH': - this.put("^to_char(%c, '%s')", dumpExpr, 'YYYY-MM'); - break; - case 'GROUP:DAY': - this.put("^to_char(%c, '%s')", dumpExpr, 'YYYY-MM-DD'); - break; - default: - dumpExpr(); - break; - } - } + // /** @param type {import('dbgate-types').TransformType} */ + // transform(type, dumpExpr) { + // switch (type) { + // case 'GROUP:YEAR': + // case 'YEAR': + // this.put('^extract(^year ^from %c)', dumpExpr); + // break; + // case 'MONTH': + // this.put('^extract(^month ^from %c)', dumpExpr); + // break; + // case 'DAY': + // this.put('^extract(^day ^from %c)', dumpExpr); + // break; + // case 'GROUP:MONTH': + // this.put("^to_char(%c, '%s')", dumpExpr, 'YYYY-MM'); + // break; + // case 'GROUP:DAY': + // this.put("^to_char(%c, '%s')", dumpExpr, 'YYYY-MM-DD'); + // break; + // default: + // dumpExpr(); + // break; + // } + // } - dropRecreatedTempTable(tmptable) { - this.putCmd('^drop ^table %i ^cascade', tmptable); - } + // dropRecreatedTempTable(tmptable) { + // this.putCmd('^drop ^table %i ^cascade', tmptable); + // } - renameTable(obj, newname) { - this.putCmd('^alter ^table %f ^rename ^to %i', obj, newname); - } + // renameTable(obj, newname) { + // this.putCmd('^alter ^table %f ^rename ^to %i', obj, newname); + // } - renameColumn(column, newcol) { - this.putCmd('^alter ^table %f ^rename ^column %i ^to %i', column, column.columnName, newcol); - } + // renameColumn(column, newcol) { + // this.putCmd('^alter ^table %f ^rename ^column %i ^to %i', column, column.columnName, newcol); + // } - dropTable(obj, options = {}) { - this.put('^drop ^table'); - if (options.testIfExists) this.put(' ^if ^exists'); - this.put(' %f', obj); - this.endCommand(); - } + // dropTable(obj, options = {}) { + // this.put('^drop ^table'); + // if (options.testIfExists) this.put(' ^if ^exists'); + // this.put(' %f', obj); + // this.endCommand(); + // } - //public override void CreateIndex(IndexInfo ix) - //{ - //} + // //public override void CreateIndex(IndexInfo ix) + // //{ + // //} - enableConstraints(table, enabled) { - this.putCmd('^alter ^table %f %k ^trigger ^all', table, enabled ? 'enable' : 'disable'); - } + // enableConstraints(table, enabled) { + // this.putCmd('^alter ^table %f %k ^trigger ^all', table, enabled ? 'enable' : 'disable'); + // } - columnDefinition(col, options) { - if (col.autoIncrement) { - this.put('^serial'); - return; - } - super.columnDefinition(col, options); - } + // columnDefinition(col, options) { + // if (col.autoIncrement) { + // this.put('^serial'); + // return; + // } + // super.columnDefinition(col, options); + // } - changeColumn(oldcol, newcol, constraints) { - if (oldcol.columnName != newcol.columnName) { - this.putCmd('^alter ^table %f ^rename ^column %i ^to %i', oldcol, oldcol.columnName, newcol.columnName); - } - if (!testEqualTypes(oldcol, newcol)) { - this.putCmd('^alter ^table %f ^alter ^column %i ^type %s', oldcol, newcol.columnName, newcol.dataType); - } - if (oldcol.notNull != newcol.notNull) { - if (newcol.notNull) this.putCmd('^alter ^table %f ^alter ^column %i ^set ^not ^null', newcol, newcol.columnName); - else this.putCmd('^alter ^table %f ^alter ^column %i ^drop ^not ^null', newcol, newcol.columnName); - } - if (oldcol.defaultValue != newcol.defaultValue) { - if (newcol.defaultValue == null) { - this.putCmd('^alter ^table %f ^alter ^column %i ^drop ^default', newcol, newcol.columnName); - } else { - this.putCmd( - '^alter ^table %f ^alter ^column %i ^set ^default %s', - newcol, - newcol.columnName, - newcol.defaultValue - ); - } - } - } + // changeColumn(oldcol, newcol, constraints) { + // if (oldcol.columnName != newcol.columnName) { + // this.putCmd('^alter ^table %f ^rename ^column %i ^to %i', oldcol, oldcol.columnName, newcol.columnName); + // } + // if (!testEqualTypes(oldcol, newcol)) { + // this.putCmd('^alter ^table %f ^alter ^column %i ^type %s', oldcol, newcol.columnName, newcol.dataType); + // } + // if (oldcol.notNull != newcol.notNull) { + // if (newcol.notNull) this.putCmd('^alter ^table %f ^alter ^column %i ^set ^not ^null', newcol, newcol.columnName); + // else this.putCmd('^alter ^table %f ^alter ^column %i ^drop ^not ^null', newcol, newcol.columnName); + // } + // if (oldcol.defaultValue != newcol.defaultValue) { + // if (newcol.defaultValue == null) { + // this.putCmd('^alter ^table %f ^alter ^column %i ^drop ^default', newcol, newcol.columnName); + // } else { + // this.putCmd( + // '^alter ^table %f ^alter ^column %i ^set ^default %s', + // newcol, + // newcol.columnName, + // newcol.defaultValue + // ); + // } + // } + // } - putValue(value) { - if (value === true) this.putRaw('true'); - else if (value === false) this.putRaw('false'); - else super.putValue(value); - } + // putValue(value) { + // if (value === true) this.putRaw('true'); + // else if (value === false) this.putRaw('false'); + // else super.putValue(value); + // } - putByteArrayValue(value) { - this.putRaw(`e'\\\\x${arrayToHexString(value)}'`); - } + // putByteArrayValue(value) { + // this.putRaw(`e'\\\\x${arrayToHexString(value)}'`); + // } } module.exports = Dumper; From ca0ae2084c5893a582c4084cc3f057a8e7370f4e Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 1 Jun 2024 10:49:38 +0200 Subject: [PATCH 11/15] oracle: handle statements in stream --- .../src/backend/drivers.js | 164 +++++++++++------- 1 file changed, 97 insertions(+), 67 deletions(-) diff --git a/plugins/dbgate-plugin-oracle/src/backend/drivers.js b/plugins/dbgate-plugin-oracle/src/backend/drivers.js index 2520bb5b..f2c61a9c 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/drivers.js +++ b/plugins/dbgate-plugin-oracle/src/backend/drivers.js @@ -98,78 +98,108 @@ const drivers = driverBases.map(driverBase => ({ }); */ // console.log('queryStream', sql); - const query = client.queryStream(sql); - // const consumeStream = new Promise((resolve, reject) => { - let rowcount = 0; - let wasHeader = false; - query.on('metadata', row => { - // console.log('metadata', row); - if (!wasHeader) { - columns = extractOracleColumns(row); - if (columns && columns.length > 0) { - options.recordset(columns); + if (sql.trim().toLowerCase().startsWith('select')) { + const query = client.queryStream(sql); + // const consumeStream = new Promise((resolve, reject) => { + let rowcount = 0; + let wasHeader = false; + + query.on('metadata', row => { + // console.log('metadata', row); + if (!wasHeader) { + columns = extractOracleColumns(row); + if (columns && columns.length > 0) { + options.recordset(columns); + } + wasHeader = true; } - wasHeader = true; - } - // options.row(zipDataRow(row, columns)); - }); - - query.on('data', row => { - // console.log('stream DATA'); - if (!wasHeader) { - columns = extractOracleColumns(row); - if (columns && columns.length > 0) { - options.recordset(columns); - } - wasHeader = true; - } - options.row(zipDataRow(row, columns)); - }); - - query.on('end', () => { - const { command, rowCount } = query._result || {}; - - if (command != 'SELECT' && _.isNumber(rowCount)) { - options.info({ - message: `${rowCount} rows affected`, - time: new Date(), - severity: 'info', - }); - } - - if (!wasHeader) { - columns = extractOracleColumns(query._result); - if (columns && columns.length > 0) { - options.recordset(columns); - } - wasHeader = true; - } - - options.done(); - }); - - query.on('error', error => { - console.log('ERROR', error); - const { message, lineNumber, procName } = error; - options.info({ - message, - line: lineNumber, - procedure: procName, - time: new Date(), - severity: 'error', + // options.row(zipDataRow(row, columns)); }); - options.done(); - }); - query.on('close', function () { - //console.log("stream 'close' event"); - // The underlying ResultSet has been closed, so the connection can now - // be closed, if desired. Note: do not close connections on 'end'. - //resolve(rowcount); - }); - //}); + query.on('data', row => { + // console.log('stream DATA'); + if (!wasHeader) { + columns = extractOracleColumns(row); + if (columns && columns.length > 0) { + options.recordset(columns); + } + wasHeader = true; + } + options.row(zipDataRow(row, columns)); + }); + + query.on('end', () => { + const { command, rowCount } = query._result || {}; + + if (command != 'SELECT' && _.isNumber(rowCount)) { + options.info({ + message: `${rowCount} rows affected`, + time: new Date(), + severity: 'info', + }); + } + + if (!wasHeader) { + columns = extractOracleColumns(query._result); + if (columns && columns.length > 0) { + options.recordset(columns); + } + wasHeader = true; + } + + options.done(); + }); + + query.on('error', error => { + console.log('ERROR', error); + const { message, lineNumber, procName } = error; + options.info({ + message, + line: lineNumber, + procedure: procName, + time: new Date(), + severity: 'error', + }); + options.done(); + }); + query.on('close', function () { + //console.log("stream 'close' event"); + // The underlying ResultSet has been closed, so the connection can now + // be closed, if desired. Note: do not close connections on 'end'. + //resolve(rowcount); + }); + //}); + } else { + client.execute(sql, (err, res) => { + if (err) { + console.log('Error query', err, sql); + options.info({ + message: err.message, + time: new Date(), + severity: 'error', + }); + } else { + const { rowsAffected, metaData, rows } = res || {}; + + if (rows && metaData) { + const columns = extractOracleColumns(metaData); + options.recordset(columns); + for (const row of rows) { + options.row(zipDataRow(row, columns)); + } + } else if (rowsAffected) { + options.info({ + message: `${rowsAffected} rows affected`, + time: new Date(), + severity: 'info', + }); + } + } + options.done(); + }); + } //const numrows = await consumeStream; //console.log('Rows selected: ' + numrows); //client.query(query); From 728f3621ebe2db392bdc9201909a0e931e445852 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 1 Jun 2024 12:37:57 +0200 Subject: [PATCH 12/15] fix --- plugins/dbgate-plugin-oracle/src/backend/drivers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/dbgate-plugin-oracle/src/backend/drivers.js b/plugins/dbgate-plugin-oracle/src/backend/drivers.js index f2c61a9c..1d98eb5a 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/drivers.js +++ b/plugins/dbgate-plugin-oracle/src/backend/drivers.js @@ -287,7 +287,7 @@ const drivers = driverBases.map(driverBase => ({ return pass; }, - async writeTable(pootl, name, options) { + async writeTable(pool, name, options) { // @ts-ignore return createBulkInsertStreamBase(this, stream, pool, name, options); }, From cafe0e68c3604ec65db8a7e80d25725fa9c44df9 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 1 Jun 2024 13:08:51 +0200 Subject: [PATCH 13/15] fixes --- packages/tools/src/SqlDumper.ts | 21 ++++++++++++------- .../src/frontend/Dumper.js | 9 ++++++++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/packages/tools/src/SqlDumper.ts b/packages/tools/src/SqlDumper.ts index d4de0c39..38161bda 100644 --- a/packages/tools/src/SqlDumper.ts +++ b/packages/tools/src/SqlDumper.ts @@ -199,14 +199,8 @@ export class SqlDumper implements AlterProcessor { selectScopeIdentity(table: TableInfo) {} - columnDefinition(column: ColumnInfo, { includeDefault = true, includeNullable = true, includeCollate = true } = {}) { - if (column.computedExpression) { - this.put('^as %s', column.computedExpression); - if (column.isPersisted) this.put(' ^persisted'); - return; - } - - const type = column.dataType || this.dialect.fallbackDataType; + columnType(dataType: string) { + const type = dataType || this.dialect.fallbackDataType; const typeWithValues = type.match(/([^(]+)(\(.+[^)]\))/); if (typeWithValues?.length) { @@ -217,6 +211,17 @@ export class SqlDumper implements AlterProcessor { this.putRaw(SqlDumper.convertKeywordCase(type)); } + } + + columnDefinition(column: ColumnInfo, { includeDefault = true, includeNullable = true, includeCollate = true } = {}) { + if (column.computedExpression) { + this.put('^as %s', column.computedExpression); + if (column.isPersisted) this.put(' ^persisted'); + return; + } + + this.columnType(column.dataType); + if (column.autoIncrement) { this.autoIncrement(); } diff --git a/plugins/dbgate-plugin-oracle/src/frontend/Dumper.js b/plugins/dbgate-plugin-oracle/src/frontend/Dumper.js index 9c8a2f9f..74b3f0ed 100644 --- a/plugins/dbgate-plugin-oracle/src/frontend/Dumper.js +++ b/plugins/dbgate-plugin-oracle/src/frontend/Dumper.js @@ -15,6 +15,15 @@ class Dumper extends SqlDumper { // oracle uses implicit transactions beginTransaction() {} + columnDefinition(col, options) { + if (col.autoIncrement) { + super.columnType(col.dataType); + this.put(' ^generated ^by ^default ^on ^null ^as ^identity'); + return; + } + super.columnDefinition(col, options); + } + // /** @param type {import('dbgate-types').TransformType} */ // transform(type, dumpExpr) { // switch (type) { From a812ff510dba1a75f40e2f3a058debd733ba4af4 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 1 Jun 2024 14:35:40 +0200 Subject: [PATCH 14/15] oracle: import data works --- .../tools/src/createBulkInsertStreamBase.ts | 48 +++++++++++++------ packages/types/dialect.d.ts | 1 + packages/types/engines.d.ts | 1 + .../src/frontend/drivers.js | 1 + .../src/backend/Analyser.js | 38 +++++++-------- .../src/backend/drivers.js | 2 +- .../src/backend/sql/columns.js | 2 +- .../src/backend/sql/foreignKeys.js | 2 +- .../src/backend/sql/indexes.js | 2 +- .../src/backend/sql/matviews.js | 2 +- .../src/backend/sql/primaryKeys.js | 2 +- .../src/backend/sql/tableList.js | 6 +-- .../src/backend/sql/uniqueNames.js | 2 +- .../src/backend/sql/views.js | 2 +- .../src/frontend/drivers.js | 1 + .../src/frontend/driver.js | 1 + 16 files changed, 68 insertions(+), 45 deletions(-) diff --git a/packages/tools/src/createBulkInsertStreamBase.ts b/packages/tools/src/createBulkInsertStreamBase.ts index 689771bb..eb16d9ff 100644 --- a/packages/tools/src/createBulkInsertStreamBase.ts +++ b/packages/tools/src/createBulkInsertStreamBase.ts @@ -56,24 +56,42 @@ export function createBulkInsertStreamBase(driver: EngineDriver, stream, pool, n const rows = writable.buffer; writable.buffer = []; - const dmp = driver.createDumper(); + if (driver.dialect.allowMultipleValuesInsert) { + const dmp = driver.createDumper(); + dmp.putRaw(`INSERT INTO ${fullNameQuoted} (`); + dmp.putCollection(',', writable.columnNames, col => dmp.putRaw(driver.dialect.quoteIdentifier(col as string))); + dmp.putRaw(')\n VALUES\n'); - dmp.putRaw(`INSERT INTO ${fullNameQuoted} (`); - dmp.putCollection(',', writable.columnNames, col => dmp.putRaw(driver.dialect.quoteIdentifier(col as string))); - dmp.putRaw(')\n VALUES\n'); + let wasRow = false; + for (const row of rows) { + if (wasRow) dmp.putRaw(',\n'); + dmp.putRaw('('); + dmp.putCollection(',', writable.columnNames, col => dmp.putValue(row[col as string])); + dmp.putRaw(')'); + wasRow = true; + } + dmp.putRaw(';'); + // require('fs').writeFileSync('/home/jena/test.sql', dmp.s); + // console.log(dmp.s); + await driver.query(pool, dmp.s, { discardResult: true }); + } else { + for (const row of rows) { + const dmp = driver.createDumper(); + dmp.putRaw(`INSERT INTO ${fullNameQuoted} (`); + dmp.putCollection(',', writable.columnNames, col => dmp.putRaw(driver.dialect.quoteIdentifier(col as string))); + dmp.putRaw(')\n VALUES\n'); - let wasRow = false; - for (const row of rows) { - if (wasRow) dmp.putRaw(',\n'); - dmp.putRaw('('); - dmp.putCollection(',', writable.columnNames, col => dmp.putValue(row[col as string])); - dmp.putRaw(')'); - wasRow = true; + dmp.putRaw('('); + dmp.putCollection(',', writable.columnNames, col => dmp.putValue(row[col as string])); + dmp.putRaw(')'); + await driver.query(pool, dmp.s, { discardResult: true }); + } + } + if (options.commitAfterInsert) { + const dmp = driver.createDumper(); + dmp.commitTransaction(); + await driver.query(pool, dmp.s, { discardResult: true }); } - dmp.putRaw(';'); - // require('fs').writeFileSync('/home/jena/test.sql', dmp.s); - // console.log(dmp.s); - await driver.query(pool, dmp.s, { discardResult: true }); }; writable.sendIfFull = async () => { diff --git a/packages/types/dialect.d.ts b/packages/types/dialect.d.ts index 166d8298..47642df6 100644 --- a/packages/types/dialect.d.ts +++ b/packages/types/dialect.d.ts @@ -12,6 +12,7 @@ export interface SqlDialect { defaultSchemaName?: string; enableConstraintsPerTable?: boolean; requireStandaloneSelectForScopeIdentity?: boolean; + allowMultipleValuesInsert?: boolean; dropColumnDependencies?: string[]; changeColumnDependencies?: string[]; diff --git a/packages/types/engines.d.ts b/packages/types/engines.d.ts index 5c2f4943..2b09547a 100644 --- a/packages/types/engines.d.ts +++ b/packages/types/engines.d.ts @@ -24,6 +24,7 @@ export interface WriteTableOptions { dropIfExists?: boolean; truncate?: boolean; createIfNotExists?: boolean; + commitAfterInsert?: boolean; } export interface EngineAuthType { diff --git a/plugins/dbgate-plugin-mysql/src/frontend/drivers.js b/plugins/dbgate-plugin-mysql/src/frontend/drivers.js index d773c39f..8198e1ed 100644 --- a/plugins/dbgate-plugin-mysql/src/frontend/drivers.js +++ b/plugins/dbgate-plugin-mysql/src/frontend/drivers.js @@ -22,6 +22,7 @@ const dialect = { enableConstraintsPerTable: false, anonymousPrimaryKey: true, explicitDropConstraint: true, + allowMultipleValuesInsert: true, quoteIdentifier(s) { return '`' + s + '`'; }, diff --git a/plugins/dbgate-plugin-oracle/src/backend/Analyser.js b/plugins/dbgate-plugin-oracle/src/backend/Analyser.js index b4eb03d8..7006877e 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/Analyser.js +++ b/plugins/dbgate-plugin-oracle/src/backend/Analyser.js @@ -42,8 +42,8 @@ class Analyser extends DatabaseAnalyser { } async _computeSingleObjectId() { - const { typeField, schemaName, pureName } = this.singleObjectFilter; - this.singleObjectId = `${typeField}:${schemaName || 'public'}.${pureName}`; + const { typeField, pureName } = this.singleObjectFilter; + this.singleObjectId = `${typeField}:${pureName}`; } async _runAnalysis() { @@ -78,7 +78,7 @@ class Analyser extends DatabaseAnalyser { const fkColumnsMapped = fkColumns.rows.map(x => ({ pureName: x.pure_name, - schemaName: x.schema_name, + // schemaName: x.schema_name, constraintSchema: x.constraint_schema, constraintName: x.constraint_name, columnName: x.column_name, @@ -86,11 +86,11 @@ class Analyser extends DatabaseAnalyser { updateAction: x.update_action, deleteAction: x.delete_action, refTableName: x.ref_table_name, - refSchemaName: x.ref_schema_name, + // refSchemaName: x.ref_schema_name, })); const pkColumnsMapped = pkColumns.rows.map(x => ({ pureName: x.pure_name, - schemaName: x.schema_name, + // schemaName: x.schema_name, constraintSchema: x.constraint_schema, constraintName: x.constraint_name, columnName: x.column_name, @@ -103,8 +103,8 @@ class Analyser extends DatabaseAnalyser { tables: tables.rows.map(table => { const newTable = { pureName: table.pure_name, - schemaName: table.schema_name, - objectId: `tables:${table.schema_name}.${table.pure_name}`, + // schemaName: table.schema_name, + objectId: `tables:${table.pure_name}`, contentHash: table.hash_code_columns ? `${table.hash_code_columns}-${table.hash_code_constraints}` : null, }; return { @@ -146,39 +146,39 @@ class Analyser extends DatabaseAnalyser { }; }), views: views.rows.map(view => ({ - objectId: `views:${view.schema_name}.${view.pure_name}`, + objectId: `views:${view.pure_name}`, pureName: view.pure_name, - schemaName: view.schema_name, + // schemaName: view.schema_name, contentHash: view.hash_code, - createSql: `CREATE VIEW "${view.schema_name}"."${view.pure_name}"\nAS\n${view.create_sql}`, + createSql: `CREATE VIEW "${view.pure_name}"\nAS\n${view.create_sql}`, columns: (columnsGrouped[columnGroup(view)] || []).map(col => getColumnInfo(col)), })), matviews: matviews ? matviews.rows.map(matview => ({ - objectId: `matviews:${matview.schema_name}.${matview.pure_name}`, + objectId: `matviews:${matview.pure_name}`, pureName: matview.pure_name, - schemaName: matview.schema_name, + // schemaName: matview.schema_name, contentHash: matview.hash_code, - createSql: `CREATE MATERIALIZED VIEW "${matview.schema_name}"."${matview.pure_name}"\nAS\n${matview.definition}`, + createSql: `CREATE MATERIALIZED VIEW "${matview.pure_name}"\nAS\n${matview.definition}`, columns: (columnsGrouped[columnGroup(view)] || []).map(col => getColumnInfo(col)), })) : undefined, procedures: routines.rows .filter(x => x.object_type == 'PROCEDURE') .map(proc => ({ - objectId: `procedures:${proc.schema_name}.${proc.pure_name}`, + objectId: `procedures:${proc.pure_name}`, pureName: proc.pure_name, - schemaName: proc.schema_name, - createSql: `CREATE PROCEDURE "${proc.schema_name}"."${proc.pure_name}"() LANGUAGE ${proc.language}\nAS\n$$\n${proc.definition}\n$$`, + // schemaName: proc.schema_name, + createSql: `CREATE PROCEDURE "${proc.pure_name}"() LANGUAGE ${proc.language}\nAS\n$$\n${proc.definition}\n$$`, contentHash: proc.hash_code, })), functions: routines.rows .filter(x => x.object_type == 'FUNCTION') .map(func => ({ - objectId: `functions:${func.schema_name}.${func.pure_name}`, - createSql: `CREATE FUNCTION "${func.schema_name}"."${func.pure_name}"() RETURNS ${func.data_type} LANGUAGE ${func.language}\nAS\n$$\n${func.definition}\n$$`, + objectId: `functions:${func.pure_name}`, + createSql: `CREATE FUNCTION "${func.pure_name}"() RETURNS ${func.data_type} LANGUAGE ${func.language}\nAS\n$$\n${func.definition}\n$$`, pureName: func.pure_name, - schemaName: func.schema_name, + // schemaName: func.schema_name, contentHash: func.hash_code, })), }; diff --git a/plugins/dbgate-plugin-oracle/src/backend/drivers.js b/plugins/dbgate-plugin-oracle/src/backend/drivers.js index 1d98eb5a..02eed9df 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/drivers.js +++ b/plugins/dbgate-plugin-oracle/src/backend/drivers.js @@ -289,7 +289,7 @@ const drivers = driverBases.map(driverBase => ({ }, async writeTable(pool, name, options) { // @ts-ignore - return createBulkInsertStreamBase(this, stream, pool, name, options); + return createBulkInsertStreamBase(this, stream, pool, name, { ...options, commitAfterInsert: true }); }, async listDatabases(client) { const { rows } = await this.query(client, 'SELECT username as "name" from all_users order by username'); diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/columns.js b/plugins/dbgate-plugin-oracle/src/backend/sql/columns.js index f605bb3b..a47a7960 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/columns.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/columns.js @@ -10,6 +10,6 @@ select data_scale as "numeric_scale", data_default as "default_value" FROM all_tab_columns av - where OWNER='$owner' AND TABLE_NAME =OBJECT_ID_CONDITION + where OWNER='$owner' AND 'tables:' || TABLE_NAME =OBJECT_ID_CONDITION order by column_id `; \ No newline at end of file diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/foreignKeys.js b/plugins/dbgate-plugin-oracle/src/backend/sql/foreignKeys.js index 945ae784..97cbeb17 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/foreignKeys.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/foreignKeys.js @@ -19,6 +19,6 @@ and basecol.table_name = fk.table_name and refcol.owner = ref.owner and refcol.constraint_name = ref.constraint_name and refcol.table_name = ref.table_name -AND fk.constraint_name =OBJECT_ID_CONDITION +AND 'tables:' || fk.table_name =OBJECT_ID_CONDITION order by basecol.position `; diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/indexes.js b/plugins/dbgate-plugin-oracle/src/backend/sql/indexes.js index fae13e68..45577d6c 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/indexes.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/indexes.js @@ -9,7 +9,7 @@ select i.table_name as "tableName", from all_ind_columns ic, all_indexes i where INDEX_OWNER = '$owner' AND ic.index_owner = i.owner and ic.index_name = i.index_name -and i.index_name =OBJECT_ID_CONDITION +and 'tables:' || i.table_name =OBJECT_ID_CONDITION order by i.table_owner, i.table_name, i.index_name, diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/matviews.js b/plugins/dbgate-plugin-oracle/src/backend/sql/matviews.js index dad92438..a60e6f24 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/matviews.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/matviews.js @@ -14,6 +14,6 @@ SELECT -- owner as schema_name, '//text()' )) definition FROM all_mviews -where OWNER = '$owner' AND mview_name=OBJECT_ID_CONDITION +where OWNER = '$owner' AND 'matviews:' || mview_name=OBJECT_ID_CONDITION order by owner, mview_name `; \ No newline at end of file diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/primaryKeys.js b/plugins/dbgate-plugin-oracle/src/backend/sql/primaryKeys.js index a5ac5f73..f10ff6ff 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/primaryKeys.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/primaryKeys.js @@ -11,7 +11,7 @@ where constraint_type = 'P' and basecol.owner = pk.owner and basecol.constraint_name = pk.constraint_name and basecol.table_name = pk.table_name -and pk.constraint_name =OBJECT_ID_CONDITION +and 'tables:' || basecol.table_name =OBJECT_ID_CONDITION and pk.owner = '$owner' order by basecol.position `; diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/tableList.js b/plugins/dbgate-plugin-oracle/src/backend/sql/tableList.js index 0a4ab93f..47b4167e 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/tableList.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/tableList.js @@ -1,9 +1,9 @@ module.exports = ` select - -- owner "schema_name", - table_name "pure_name" + -- owner "schema_name", + table_name "pure_name" from all_tables - where OWNER='$owner' AND TABLE_NAME =OBJECT_ID_CONDITION + where OWNER='$owner' AND 'tables:' || TABLE_NAME =OBJECT_ID_CONDITION `; diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/uniqueNames.js b/plugins/dbgate-plugin-oracle/src/backend/sql/uniqueNames.js index b2d7d964..c752cc79 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/uniqueNames.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/uniqueNames.js @@ -2,5 +2,5 @@ module.exports = ` select constraint_name as "constraintName" from all_constraints where owner='$owner' and constraint_type = 'U' - and constraint_name =OBJECT_ID_CONDITION + and 'tables:' || table_name =OBJECT_ID_CONDITION `; diff --git a/plugins/dbgate-plugin-oracle/src/backend/sql/views.js b/plugins/dbgate-plugin-oracle/src/backend/sql/views.js index d001c8d9..dfefd893 100644 --- a/plugins/dbgate-plugin-oracle/src/backend/sql/views.js +++ b/plugins/dbgate-plugin-oracle/src/backend/sql/views.js @@ -8,5 +8,5 @@ from (select from all_views av where owner = '$owner' and text_vc is not null ) avv - where "pure_name" =OBJECT_ID_CONDITION + where 'views:' || "pure_name" =OBJECT_ID_CONDITION `; diff --git a/plugins/dbgate-plugin-postgres/src/frontend/drivers.js b/plugins/dbgate-plugin-postgres/src/frontend/drivers.js index fa2f2bb9..897f545f 100644 --- a/plugins/dbgate-plugin-postgres/src/frontend/drivers.js +++ b/plugins/dbgate-plugin-postgres/src/frontend/drivers.js @@ -33,6 +33,7 @@ const dialect = { dropUnique: true, createCheck: true, dropCheck: true, + allowMultipleValuesInsert: true, dropReferencesWhenDropTable: true, requireStandaloneSelectForScopeIdentity: true, diff --git a/plugins/dbgate-plugin-sqlite/src/frontend/driver.js b/plugins/dbgate-plugin-sqlite/src/frontend/driver.js index a24bacb5..fbf78dcf 100644 --- a/plugins/dbgate-plugin-sqlite/src/frontend/driver.js +++ b/plugins/dbgate-plugin-sqlite/src/frontend/driver.js @@ -17,6 +17,7 @@ const dialect = { explicitDropConstraint: true, stringEscapeChar: "'", fallbackDataType: 'nvarchar', + allowMultipleValuesInsert: true, dropColumnDependencies: ['indexes', 'primaryKey', 'uniques'], quoteIdentifier(s) { return `[${s}]`; From e572cd392c7b05a2a90e3b469e8c6e70e799066d Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 1 Jun 2024 14:36:57 +0200 Subject: [PATCH 15/15] removed experimental oracle status --- README.md | 2 +- plugins/dbgate-plugin-oracle/src/frontend/drivers.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9f728a44..6535545a 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ DbGate is licensed under MIT license and is completely free. * MySQL * PostgreSQL * SQL Server -* Oracle (experimental) +* Oracle * MongoDB * Redis * SQLite diff --git a/plugins/dbgate-plugin-oracle/src/frontend/drivers.js b/plugins/dbgate-plugin-oracle/src/frontend/drivers.js index 2aa6d790..69608365 100644 --- a/plugins/dbgate-plugin-oracle/src/frontend/drivers.js +++ b/plugins/dbgate-plugin-oracle/src/frontend/drivers.js @@ -131,7 +131,7 @@ $$ LANGUAGE plpgsql;`, const oracleDriver = { ...oracleDriverBase, engine: 'oracle@dbgate-plugin-oracle', - title: 'OracleDB (Experimental)', + title: 'OracleDB', defaultPort: 1521, dialect: { ...dialect,