diff --git a/integration-tests/engines.js b/integration-tests/engines.js index 94700af94..5d9451e83 100644 --- a/integration-tests/engines.js +++ b/integration-tests/engines.js @@ -757,7 +757,7 @@ const enginesOnCi = [ const enginesOnLocal = [ // all engines, which would be run on local test // cassandraEngine, - //mysqlEngine, + // mysqlEngine, // mariaDbEngine, postgreSqlEngine, //sqlServerEngine, diff --git a/packages/tools/src/DatabaseAnalyser.ts b/packages/tools/src/DatabaseAnalyser.ts index e10e23ab8..d48cfd49b 100644 --- a/packages/tools/src/DatabaseAnalyser.ts +++ b/packages/tools/src/DatabaseAnalyser.ts @@ -299,6 +299,23 @@ export class DatabaseAnalyser { } } + objectIdConditionApplied(typeFields) { + if (!this.modifications || !typeFields || this.modifications.length == 0) { + return false; + } + if (this.modifications.some(x => typeFields.includes(x.objectTypeField) && x.action == 'all')) { + // do not filter objects + return false; + } + const filterIds = this.modifications + .filter(x => typeFields.includes(x.objectTypeField) && (x.action == 'add' || x.action == 'change')) + .map(x => x.objectId); + if (filterIds.length == 0) { + return false; + } + return true; + } + async getModifications() { const snapshot = await this._getFastSnapshot(); if (!snapshot) return null; diff --git a/plugins/dbgate-plugin-postgres/src/backend/Analyser.js b/plugins/dbgate-plugin-postgres/src/backend/Analyser.js index dfb24af3a..e9361c781 100644 --- a/plugins/dbgate-plugin-postgres/src/backend/Analyser.js +++ b/plugins/dbgate-plugin-postgres/src/backend/Analyser.js @@ -99,55 +99,60 @@ class Analyser extends DatabaseAnalyser { this.feedback({ analysingMessage: 'DBGM-00244 Loading foreign key constraints' }); // const fk_tableConstraints = await this.analyserQuery('fk_tableConstraints', ['tables']); - this.feedback({ analysingMessage: 'DBGM-00245 Loading foreign key refs' }); - const foreignKeys = await this.analyserQuery('foreignKeys', ['tables']); + if (this.objectIdConditionApplied(['tables'])) { + this.feedback({ analysingMessage: 'DBGM-00000 Loading foreign key refs' }); + fkColumns = await this.analyserQuery('foreignKeyColumns', ['tables']); + } else { + this.feedback({ analysingMessage: 'DBGM-00245 Loading foreign key refs' }); + const foreignKeys = await this.analyserQuery('foreignKeys', ['tables']); - this.feedback({ analysingMessage: 'DBGM-00246 Loading foreign key columns' }); - const fk_keyColumnUsage = await this.analyserQuery('fk_keyColumnUsage', ['tables']); + this.feedback({ analysingMessage: 'DBGM-00246 Loading foreign key columns' }); + const fk_keyColumnUsage = await this.analyserQuery('fk_keyColumnUsage', ['tables']); - // const cntKey = x => `${x.constraint_name}|${x.constraint_schema}`; - const fkRows = []; - // const fkConstraintDct = _.keyBy(fk_tableConstraints.rows, cntKey); - for (const fkRef of foreignKeys.rows) { - // const cntBase = fkConstraintDct[cntKey(fkRef)]; - // const cntRef = fkConstraintDct[`${fkRef.unique_constraint_name}|${fkRef.unique_constraint_schema}`]; - // if (!cntBase || !cntRef) continue; - const baseCols = _.sortBy( - fk_keyColumnUsage.rows.filter( - x => - x.table_name == fkRef.table_name && - x.constraint_name == fkRef.constraint_name && - x.table_schema == fkRef.table_schema - ), - 'ordinal_position' - ); - const refCols = _.sortBy( - fk_keyColumnUsage.rows.filter( - x => - x.table_name == fkRef.ref_table_name && - x.constraint_name == fkRef.unique_constraint_name && - x.table_schema == fkRef.ref_table_schema - ), - 'ordinal_position' - ); - if (baseCols.length != refCols.length) continue; + // const cntKey = x => `${x.constraint_name}|${x.constraint_schema}`; + const fkRows = []; + // const fkConstraintDct = _.keyBy(fk_tableConstraints.rows, cntKey); + for (const fkRef of foreignKeys.rows) { + // const cntBase = fkConstraintDct[cntKey(fkRef)]; + // const cntRef = fkConstraintDct[`${fkRef.unique_constraint_name}|${fkRef.unique_constraint_schema}`]; + // if (!cntBase || !cntRef) continue; + const baseCols = _.sortBy( + fk_keyColumnUsage.rows.filter( + x => + x.table_name == fkRef.table_name && + x.constraint_name == fkRef.constraint_name && + x.table_schema == fkRef.table_schema + ), + 'ordinal_position' + ); + const refCols = _.sortBy( + fk_keyColumnUsage.rows.filter( + x => + x.table_name == fkRef.ref_table_name && + x.constraint_name == fkRef.unique_constraint_name && + x.table_schema == fkRef.ref_table_schema + ), + 'ordinal_position' + ); + if (baseCols.length != refCols.length) continue; - for (let i = 0; i < baseCols.length; i++) { - const baseCol = baseCols[i]; - const refCol = refCols[i]; + for (let i = 0; i < baseCols.length; i++) { + const baseCol = baseCols[i]; + const refCol = refCols[i]; - fkRows.push({ - ...fkRef, - pure_name: fkRef.table_name, - schema_name: fkRef.table_schema, - ref_table_name: fkRef.ref_table_name, - ref_schema_name: fkRef.ref_table_schema, - column_name: baseCol.column_name, - ref_column_name: refCol.column_name, - }); + fkRows.push({ + ...fkRef, + pure_name: fkRef.table_name, + schema_name: fkRef.table_schema, + ref_table_name: fkRef.ref_table_name, + ref_schema_name: fkRef.ref_table_schema, + column_name: baseCol.column_name, + ref_column_name: refCol.column_name, + }); + } } + fkColumns = { rows: fkRows }; } - fkColumns = { rows: fkRows }; this.feedback({ analysingMessage: 'DBGM-00247 Loading views' }); const views = await this.analyserQuery('views', ['views']); diff --git a/plugins/dbgate-plugin-postgres/src/backend/sql/foreignKeyColumns.js b/plugins/dbgate-plugin-postgres/src/backend/sql/foreignKeyColumns.js new file mode 100644 index 000000000..1c9d5f7ed --- /dev/null +++ b/plugins/dbgate-plugin-postgres/src/backend/sql/foreignKeyColumns.js @@ -0,0 +1,36 @@ +module.exports = ` +SELECT + tc.table_schema as schema_name, + tc.table_name as pure_name, + tc.constraint_name, + tc_pk.table_schema AS ref_schema_name, + tc_pk.table_name AS ref_table_name, + rc.unique_constraint_name, + kcu.column_name, + kcu.ordinal_position, + ccu.column_name AS ref_column_name +FROM information_schema.table_constraints AS tc +JOIN information_schema.key_column_usage AS kcu + ON tc.constraint_name = kcu.constraint_name + AND tc.table_schema = kcu.table_schema +JOIN information_schema.referential_constraints AS rc + ON rc.constraint_name = tc.constraint_name + AND rc.constraint_schema = tc.table_schema +JOIN information_schema.table_constraints AS tc_pk + ON tc_pk.constraint_name = rc.unique_constraint_name + AND tc_pk.constraint_schema = rc.unique_constraint_schema +JOIN information_schema.key_column_usage AS ccu + ON ccu.constraint_name = rc.unique_constraint_name + AND ccu.constraint_schema = rc.unique_constraint_schema + AND ccu.ordinal_position = kcu.position_in_unique_constraint +WHERE tc.constraint_type = 'FOREIGN KEY' +AND (('tables:' || tc.table_schema || '.' || tc.table_name) =OBJECT_ID_CONDITION AND tc.table_schema =SCHEMA_NAME_CONDITION) +OR +(('tables:' || tc_pk.table_schema || '.' || tc_pk.table_name) =OBJECT_ID_CONDITION AND tc.table_schema =SCHEMA_NAME_CONDITION) +ORDER BY + tc.table_schema, + tc.table_name, + tc.constraint_name, + kcu.ordinal_position +; +`; diff --git a/plugins/dbgate-plugin-postgres/src/backend/sql/index.js b/plugins/dbgate-plugin-postgres/src/backend/sql/index.js index 833153196..f40108ffb 100644 --- a/plugins/dbgate-plugin-postgres/src/backend/sql/index.js +++ b/plugins/dbgate-plugin-postgres/src/backend/sql/index.js @@ -16,6 +16,7 @@ const geometryColumns = require('./geometryColumns'); const geographyColumns = require('./geographyColumns'); const proceduresParameters = require('./proceduresParameters'); const foreignKeys = require('./foreignKeys'); +const foreignKeyColumns = require('./foreignKeyColumns'); const triggers = require('./triggers'); const listDatabases = require('./listDatabases'); const listVariables = require('./listVariables'); @@ -30,6 +31,7 @@ module.exports = { viewModifications, primaryKeys, fk_keyColumnUsage, + foreignKeyColumns, foreignKeys, views, routines,