mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-17 21:26:00 +00:00
postgres analyser fixed - broken loading FKs in incremental analysis
This commit is contained in:
@@ -757,7 +757,7 @@ const enginesOnCi = [
|
||||
const enginesOnLocal = [
|
||||
// all engines, which would be run on local test
|
||||
// cassandraEngine,
|
||||
//mysqlEngine,
|
||||
// mysqlEngine,
|
||||
// mariaDbEngine,
|
||||
postgreSqlEngine,
|
||||
//sqlServerEngine,
|
||||
|
||||
@@ -299,6 +299,23 @@ export class DatabaseAnalyser<TClient = any> {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -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']);
|
||||
|
||||
@@ -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
|
||||
;
|
||||
`;
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user