diff --git a/integration-tests/__tests__/deploy-database.spec.js b/integration-tests/__tests__/deploy-database.spec.js index 2144588b4..00c789340 100644 --- a/integration-tests/__tests__/deploy-database.spec.js +++ b/integration-tests/__tests__/deploy-database.spec.js @@ -506,9 +506,9 @@ describe('Deploy database', () => { ], { dbdiffOptionsExtra: { - allowTableMarkDropped: true, - allowSqlObjectMarkDropped: true, - allowColumnMarkDropped: true, + deletedTablePrefix: '_deleted_', + deletedColumnPrefix: '_deleted_', + deletedSqlObjectPrefix: '_deleted_', }, finalCheckAgainstModel: [ { @@ -528,7 +528,7 @@ describe('Deploy database', () => { }) ); - test.each(engines.map(engine => [engine.label, engine]))( + test.each(engines.filter(engine => engine.supportRenameSqlObject).map(engine => [engine.label, engine]))( 'Mark view removed - %s', testWrapper(async (conn, driver, engine) => { await testDatabaseDeploy( @@ -569,9 +569,9 @@ describe('Deploy database', () => { ], { dbdiffOptionsExtra: { - allowTableMarkDropped: true, - allowSqlObjectMarkDropped: true, - allowColumnMarkDropped: true, + deletedTablePrefix: '_deleted_', + deletedColumnPrefix: '_deleted_', + deletedSqlObjectPrefix: '_deleted_', }, finalCheckAgainstModel: [ { @@ -594,4 +594,60 @@ describe('Deploy database', () => { ); }) ); + + test.each(engines.map(engine => [engine.label, engine]))( + 'Mark column removed - %s', + testWrapper(async (conn, driver, engine) => { + await testDatabaseDeploy( + engine, + conn, + driver, + [ + [ + { + name: 't1.table.yaml', + json: { + name: 't1', + columns: [ + { name: 'id', type: 'int' }, + { name: 'val', type: 'int' }, + ], + primaryKey: ['id'], + }, + }, + ], + [ + { + name: 't1.table.yaml', + json: { + name: 't1', + columns: [{ name: 'id', type: 'int' }], + primaryKey: ['id'], + }, + }, + ], + ], + { + dbdiffOptionsExtra: { + deletedTablePrefix: '_deleted_', + deletedColumnPrefix: '_deleted_', + deletedSqlObjectPrefix: '_deleted_', + }, + finalCheckAgainstModel: [ + { + name: 't1.table.yaml', + json: { + name: 't1', + columns: [ + { name: 'id', type: 'int' }, + { name: '_deleted_val', type: 'int' }, + ], + primaryKey: ['id'], + }, + }, + ], + } + ); + }) + ); }); diff --git a/packages/tools/src/diffTools.ts b/packages/tools/src/diffTools.ts index ce65a8d9c..6425b730b 100644 --- a/packages/tools/src/diffTools.ts +++ b/packages/tools/src/diffTools.ts @@ -36,15 +36,15 @@ export interface DbDiffOptions { noDropTable?: boolean; allowTableRecreateWhenNoDrop?: boolean; - allowTableMarkDropped?: boolean; + deletedTablePrefix?: string; noDropColumn?: boolean; - allowColumnMarkDropped?: boolean; + deletedColumnPrefix?: string; noDropConstraint?: boolean; noDropSqlObject?: boolean; - allowSqlObjectMarkDropped?: boolean; + deletedSqlObjectPrefix?: string; noRenameTable?: boolean; noRenameColumn?: boolean; @@ -425,7 +425,11 @@ function planAlterTable(plan: AlterPlan, oldTable: TableInfo, newTable: TableInf if (!opts.noDropConstraint) { constraintPairs.filter(x => x[1] == null).forEach(x => plan.dropConstraint(x[0])); } - if (!opts.noDropColumn) { + if (opts.deletedColumnPrefix) { + columnPairs + .filter(x => x[1] == null) + .forEach(x => plan.renameColumn(x[0], opts.deletedColumnPrefix + x[0].columnName)); + } else if (!opts.noDropColumn) { columnPairs.filter(x => x[1] == null).forEach(x => plan.dropColumn(x[0])); } @@ -573,8 +577,8 @@ export function createAlterDatabasePlan( const newobj = (newDb[objectTypeField] || []).find(x => x.pairingId == oldobj.pairingId); if (objectTypeField == 'tables') { if (newobj == null) { - if (opts.allowTableMarkDropped) { - plan.renameTable(oldobj, '_deleted_' + oldobj.pureName); + if (opts.deletedTablePrefix) { + plan.renameTable(oldobj, opts.deletedTablePrefix + oldobj.pureName); } else if (!opts.noDropTable) { plan.dropTable(oldobj); } @@ -583,8 +587,8 @@ export function createAlterDatabasePlan( } } else { if (newobj == null) { - if (opts.allowSqlObjectMarkDropped && driver.dialect.renameSqlObject) { - plan.renameSqlObject(oldobj, '_deleted_' + oldobj.pureName); + if (opts.deletedSqlObjectPrefix && driver.dialect.renameSqlObject) { + plan.renameSqlObject(oldobj, opts.deletedSqlObjectPrefix + oldobj.pureName); } else if (!opts.noDropSqlObject) { plan.dropSqlObject(oldobj); }