mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-22 21:36:00 +00:00
dbdeploy: undelete table works
This commit is contained in:
@@ -503,6 +503,7 @@ describe('Deploy database', () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
[],
|
[],
|
||||||
|
[],
|
||||||
],
|
],
|
||||||
{
|
{
|
||||||
dbdiffOptionsExtra: {
|
dbdiffOptionsExtra: {
|
||||||
@@ -510,6 +511,7 @@ describe('Deploy database', () => {
|
|||||||
deletedColumnPrefix: '_deleted_',
|
deletedColumnPrefix: '_deleted_',
|
||||||
deletedSqlObjectPrefix: '_deleted_',
|
deletedSqlObjectPrefix: '_deleted_',
|
||||||
},
|
},
|
||||||
|
disallowExtraObjects: true,
|
||||||
finalCheckAgainstModel: [
|
finalCheckAgainstModel: [
|
||||||
{
|
{
|
||||||
name: 't1.table.yaml',
|
name: 't1.table.yaml',
|
||||||
@@ -573,6 +575,7 @@ describe('Deploy database', () => {
|
|||||||
deletedColumnPrefix: '_deleted_',
|
deletedColumnPrefix: '_deleted_',
|
||||||
deletedSqlObjectPrefix: '_deleted_',
|
deletedSqlObjectPrefix: '_deleted_',
|
||||||
},
|
},
|
||||||
|
disallowExtraObjects: true,
|
||||||
finalCheckAgainstModel: [
|
finalCheckAgainstModel: [
|
||||||
{
|
{
|
||||||
name: 't1.table.yaml',
|
name: 't1.table.yaml',
|
||||||
@@ -633,6 +636,7 @@ describe('Deploy database', () => {
|
|||||||
deletedColumnPrefix: '_deleted_',
|
deletedColumnPrefix: '_deleted_',
|
||||||
deletedSqlObjectPrefix: '_deleted_',
|
deletedSqlObjectPrefix: '_deleted_',
|
||||||
},
|
},
|
||||||
|
disallowExtraObjects: true,
|
||||||
finalCheckAgainstModel: [
|
finalCheckAgainstModel: [
|
||||||
{
|
{
|
||||||
name: 't1.table.yaml',
|
name: 't1.table.yaml',
|
||||||
@@ -650,4 +654,67 @@ describe('Deploy database', () => {
|
|||||||
);
|
);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test.each(engines.map(engine => [engine.label, engine]))(
|
||||||
|
'Undelete table - %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'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// delete table
|
||||||
|
[],
|
||||||
|
// undelete table
|
||||||
|
[
|
||||||
|
{
|
||||||
|
name: 't1.table.yaml',
|
||||||
|
json: {
|
||||||
|
name: 't1',
|
||||||
|
columns: [
|
||||||
|
{ name: 'id', type: 'int' },
|
||||||
|
{ name: 'val', type: 'int' },
|
||||||
|
],
|
||||||
|
primaryKey: ['id'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
{
|
||||||
|
dbdiffOptionsExtra: {
|
||||||
|
deletedTablePrefix: '_deleted_',
|
||||||
|
deletedColumnPrefix: '_deleted_',
|
||||||
|
deletedSqlObjectPrefix: '_deleted_',
|
||||||
|
},
|
||||||
|
disallowExtraObjects: true,
|
||||||
|
finalCheckAgainstModel: [
|
||||||
|
{
|
||||||
|
name: 't1.table.yaml',
|
||||||
|
json: {
|
||||||
|
name: 't1',
|
||||||
|
columns: [
|
||||||
|
{ name: 'id', type: 'int' },
|
||||||
|
{ name: 'val', type: 'int' },
|
||||||
|
],
|
||||||
|
primaryKey: ['id'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -144,7 +144,36 @@ export function generateDbPairingId(db: DatabaseInfo): DatabaseInfo {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function testEqualNames(a: string, b: string, opts: DbDiffOptions) {
|
function getNameWithoutDeletedPrefix(name: string, opts: DbDiffOptions, deletedPrefix?: string) {
|
||||||
|
if (deletedPrefix) {
|
||||||
|
if (opts.ignoreCase) {
|
||||||
|
if ((name || '').toLowerCase().startsWith(deletedPrefix.toLowerCase())) {
|
||||||
|
return name.slice(deletedPrefix.length);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((name || '').startsWith(deletedPrefix)) {
|
||||||
|
return name.slice(deletedPrefix.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasDeletedPrefix(name: string, opts: DbDiffOptions, deletedPrefix?: string) {
|
||||||
|
if (deletedPrefix) {
|
||||||
|
if (opts.ignoreCase) {
|
||||||
|
return (name || '').toLowerCase().startsWith(deletedPrefix.toLowerCase());
|
||||||
|
} else {
|
||||||
|
return (name || '').startsWith(deletedPrefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function testEqualNames(a: string, b: string, opts: DbDiffOptions, deletedPrefix?: string) {
|
||||||
|
a = getNameWithoutDeletedPrefix(a, opts, deletedPrefix);
|
||||||
|
b = getNameWithoutDeletedPrefix(b, opts, deletedPrefix);
|
||||||
if (opts.ignoreCase) return (a || '').toLowerCase() == (b || '').toLowerCase();
|
if (opts.ignoreCase) return (a || '').toLowerCase() == (b || '').toLowerCase();
|
||||||
return a == b;
|
return a == b;
|
||||||
}
|
}
|
||||||
@@ -157,9 +186,12 @@ function testEqualSchemas(lschema: string, rschema: string, opts: DbDiffOptions)
|
|||||||
return testEqualNames(lschema, rschema, opts);
|
return testEqualNames(lschema, rschema, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testEqualFullNames(lft: NamedObjectInfo, rgt: NamedObjectInfo, opts: DbDiffOptions) {
|
function testEqualFullNames(lft: NamedObjectInfo, rgt: NamedObjectInfo, opts: DbDiffOptions, deletedPrefix?: string) {
|
||||||
if (lft == null || rgt == null) return lft == rgt;
|
if (lft == null || rgt == null) return lft == rgt;
|
||||||
return testEqualSchemas(lft.schemaName, rgt.schemaName, opts) && testEqualNames(lft.pureName, rgt.pureName, opts);
|
return (
|
||||||
|
testEqualSchemas(lft.schemaName, rgt.schemaName, opts) &&
|
||||||
|
testEqualNames(lft.pureName, rgt.pureName, opts, deletedPrefix)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testEqualDefaultValues(value1: string | null | undefined, value2: string | null | undefined) {
|
function testEqualDefaultValues(value1: string | null | undefined, value2: string | null | undefined) {
|
||||||
@@ -428,7 +460,11 @@ function planAlterTable(plan: AlterPlan, oldTable: TableInfo, newTable: TableInf
|
|||||||
if (opts.deletedColumnPrefix) {
|
if (opts.deletedColumnPrefix) {
|
||||||
columnPairs
|
columnPairs
|
||||||
.filter(x => x[1] == null)
|
.filter(x => x[1] == null)
|
||||||
.forEach(x => plan.renameColumn(x[0], opts.deletedColumnPrefix + x[0].columnName));
|
.forEach(x => {
|
||||||
|
if (!hasDeletedPrefix(x[0].columnName, opts, opts.deletedColumnPrefix)) {
|
||||||
|
plan.renameColumn(x[0], opts.deletedColumnPrefix + x[0].columnName);
|
||||||
|
}
|
||||||
|
});
|
||||||
} else if (!opts.noDropColumn) {
|
} else if (!opts.noDropColumn) {
|
||||||
columnPairs.filter(x => x[1] == null).forEach(x => plan.dropColumn(x[0]));
|
columnPairs.filter(x => x[1] == null).forEach(x => plan.dropColumn(x[0]));
|
||||||
}
|
}
|
||||||
@@ -437,6 +473,10 @@ function planAlterTable(plan: AlterPlan, oldTable: TableInfo, newTable: TableInf
|
|||||||
plan.renameTable(oldTable, newTable.pureName);
|
plan.renameTable(oldTable, newTable.pureName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasDeletedPrefix(oldTable.pureName, opts, opts.deletedTablePrefix)) {
|
||||||
|
plan.renameTable(oldTable, newTable.pureName);
|
||||||
|
}
|
||||||
|
|
||||||
columnPairs.filter(x => x[0] == null).forEach(x => plan.createColumn(x[1]));
|
columnPairs.filter(x => x[0] == null).forEach(x => plan.createColumn(x[1]));
|
||||||
|
|
||||||
columnPairs
|
columnPairs
|
||||||
@@ -577,7 +617,7 @@ export function createAlterDatabasePlan(
|
|||||||
const newobj = (newDb[objectTypeField] || []).find(x => x.pairingId == oldobj.pairingId);
|
const newobj = (newDb[objectTypeField] || []).find(x => x.pairingId == oldobj.pairingId);
|
||||||
if (objectTypeField == 'tables') {
|
if (objectTypeField == 'tables') {
|
||||||
if (newobj == null) {
|
if (newobj == null) {
|
||||||
if (opts.deletedTablePrefix) {
|
if (opts.deletedTablePrefix && !hasDeletedPrefix(oldobj.pureName, opts, opts.deletedTablePrefix)) {
|
||||||
plan.renameTable(oldobj, opts.deletedTablePrefix + oldobj.pureName);
|
plan.renameTable(oldobj, opts.deletedTablePrefix + oldobj.pureName);
|
||||||
} else if (!opts.noDropTable) {
|
} else if (!opts.noDropTable) {
|
||||||
plan.dropTable(oldobj);
|
plan.dropTable(oldobj);
|
||||||
@@ -587,7 +627,11 @@ export function createAlterDatabasePlan(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (newobj == null) {
|
if (newobj == null) {
|
||||||
if (opts.deletedSqlObjectPrefix && driver.dialect.renameSqlObject) {
|
if (
|
||||||
|
opts.deletedSqlObjectPrefix &&
|
||||||
|
driver.dialect.renameSqlObject &&
|
||||||
|
!hasDeletedPrefix(oldobj.pureName, opts, opts.deletedSqlObjectPrefix)
|
||||||
|
) {
|
||||||
plan.renameSqlObject(oldobj, opts.deletedSqlObjectPrefix + oldobj.pureName);
|
plan.renameSqlObject(oldobj, opts.deletedSqlObjectPrefix + oldobj.pureName);
|
||||||
} else if (!opts.noDropSqlObject) {
|
} else if (!opts.noDropSqlObject) {
|
||||||
plan.dropSqlObject(oldobj);
|
plan.dropSqlObject(oldobj);
|
||||||
@@ -669,7 +713,14 @@ export function matchPairedObjects(db1: DatabaseInfo, db2: DatabaseInfo, opts: D
|
|||||||
|
|
||||||
for (const objectTypeField of ['tables', 'views', 'procedures', 'matviews', 'functions']) {
|
for (const objectTypeField of ['tables', 'views', 'procedures', 'matviews', 'functions']) {
|
||||||
for (const obj2 of res[objectTypeField] || []) {
|
for (const obj2 of res[objectTypeField] || []) {
|
||||||
const obj1 = db1[objectTypeField].find(x => testEqualFullNames(x, obj2, opts));
|
const obj1 = db1[objectTypeField].find(x =>
|
||||||
|
testEqualFullNames(
|
||||||
|
x,
|
||||||
|
obj2,
|
||||||
|
opts,
|
||||||
|
objectTypeField == 'tables' ? opts.deletedTablePrefix : opts.deletedSqlObjectPrefix
|
||||||
|
)
|
||||||
|
);
|
||||||
if (obj1) {
|
if (obj1) {
|
||||||
obj2.pairingId = obj1.pairingId;
|
obj2.pairingId = obj1.pairingId;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user