support for rename SQL object (mssql, postgres)

This commit is contained in:
Jan Prochazka 2024-10-31 10:48:32 +01:00
parent 2aed60390c
commit 81297383cb
12 changed files with 66 additions and 7 deletions

View File

@ -5,10 +5,12 @@ const { testWrapper } = require('../tools');
const engines = require('../engines');
const { getAlterDatabaseScript, extendDatabaseInfo, generateDbPairingId } = require('dbgate-tools');
function flatSource() {
const initSql = ['CREATE TABLE t1 (id int primary key)', 'CREATE TABLE t2 (id int primary key)'];
function flatSource(engineCond = x => !x.skipReferences) {
return _.flatten(
engines
.filter(x => !x.skipReferences)
.filter(engineCond)
.map(engine => (engine.objects || []).map(object => [engine.label, object.type, object, engine]))
);
}
@ -66,5 +68,24 @@ describe('Alter database', () => {
expect(db[type].length).toEqual(0);
})
);
});
test.each(flatSource(x => x.supportRenameSqlObject))(
'Rename object - %s - %s',
testWrapper(async (conn, driver, type, object, engine) => {
for (const sql of initSql) await driver.query(conn, sql, { discardResult: true });
await driver.query(conn, object.create1, { discardResult: true });
const structure = extendDatabaseInfo(await driver.analyseFull(conn));
const dmp = driver.createDumper();
dmp.renameSqlObject(structure[type][0], 'renamed1');
await driver.query(conn, dmp.s);
const structure2 = await driver.analyseFull(conn);
expect(structure2[type].length).toEqual(1);
expect(structure2[type][0].pureName).toEqual('renamed1');
})
);
});

View File

@ -96,6 +96,7 @@ const engines = [
},
],
supportSchemas: true,
supportRenameSqlObject: true,
defaultSchemaName: 'public',
dumpFile: 'data/chinook-postgre.sql',
dumpChecks: [
@ -129,6 +130,7 @@ const engines = [
},
],
supportSchemas: true,
supportRenameSqlObject: true,
defaultSchemaName: 'dbo',
// skipSeparateSchemas: true,
},
@ -184,9 +186,9 @@ const engines = [
const filterLocal = [
// filter local testing
'MySQL',
'-MySQL',
'-MariaDB',
'-PostgreSQL',
'PostgreSQL',
'-SQL Server',
'-SQLite',
'-CockroachDB',

View File

@ -588,6 +588,8 @@ export class SqlDumper implements AlterProcessor {
renameTable(obj: TableInfo, newname: string) {}
renameSqlObject(obj: SqlObjectInfo, newname: string) {}
beginTransaction() {
this.putCmd('^begin ^transaction');
}

View File

@ -39,6 +39,12 @@ interface AlterOperation_RenameTable {
newName: string;
}
interface AlterOperation_RenameSqlObject {
operationType: 'renameSqlObject';
object: SqlObjectInfo;
newName: string;
}
interface AlterOperation_CreateColumn {
operationType: 'createColumn';
newObject: ColumnInfo;
@ -120,7 +126,8 @@ type AlterOperation =
| AlterOperation_DropSqlObject
| AlterOperation_RecreateTable
| AlterOperation_FillPreloadedRows
| AlterOperation_SetTableOption;
| AlterOperation_SetTableOption
| AlterOperation_RenameSqlObject;
export class AlterPlan {
recreates = {
@ -217,6 +224,14 @@ export class AlterPlan {
});
}
renameSqlObject(table: TableInfo, newName: string) {
this.operations.push({
operationType: 'renameSqlObject',
object: table,
newName,
});
}
renameColumn(column: ColumnInfo, newName: string) {
this.operations.push({
operationType: 'renameColumn',
@ -595,6 +610,9 @@ export function runAlterOperation(op: AlterOperation, processor: AlterProcessor)
case 'renameTable':
processor.renameTable(op.object, op.newName);
break;
case 'renameSqlObject':
processor.renameSqlObject(op.object, op.newName);
break;
case 'renameConstraint':
processor.renameConstraint(op.object, op.newName);
break;

View File

@ -112,6 +112,11 @@ export class DatabaseInfoAlterProcessor {
this.db.tables.find(x => x.pureName == table.pureName && x.schemaName == table.schemaName).pureName = newName;
}
renameSqlObject(obj: SqlObjectInfo, newName: string) {
this.db[obj.objectTypeField].find(x => x.pureName == obj.pureName && x.schemaName == obj.schemaName).pureName =
newName;
}
renameColumn(column: ColumnInfo, newName: string) {
const table = this.db.tables.find(x => x.pureName == column.pureName && x.schemaName == column.schemaName);
table.columns.find(x => x.columnName == column.columnName).columnName = newName;

View File

@ -583,7 +583,9 @@ export function createAlterDatabasePlan(
}
} else {
if (newobj == null) {
if (!opts.noDropSqlObject) {
if (opts.allowSqlObjectMarkDropped) {
plan.renameSqlObject(oldobj, '_deleted_' + oldobj.pureName);
} else if (!opts.noDropSqlObject) {
plan.dropSqlObject(oldobj);
}
} else if (!testEqualSqlObjects(oldobj.createSql, newobj.createSql, opts)) {

View File

@ -10,6 +10,7 @@ export interface AlterProcessor {
changeConstraint(oldConstraint: ConstraintInfo, newConstraint: ConstraintInfo);
dropConstraint(constraint: ConstraintInfo);
renameTable(table: TableInfo, newName: string);
renameSqlObject(obj: SqlObjectInfo, newName: string);
renameColumn(column: ColumnInfo, newName: string);
renameConstraint(constraint: ConstraintInfo, newName: string);
recreateTable(oldTable: TableInfo, newTable: TableInfo);

View File

@ -34,6 +34,7 @@ export interface SqlDialect {
dropUnique?: boolean;
createCheck?: boolean;
dropCheck?: boolean;
renameSqlObject?: boolean;
specificNullabilityImplementation?: boolean;
omitForeignKeys?: boolean;

View File

@ -175,5 +175,6 @@ MsSqlDumper.prototype.changeTriggerSchema = MsSqlDumper.prototype.changeObjectSc
MsSqlDumper.prototype.renameTable = MsSqlDumper.prototype.renameObject;
MsSqlDumper.prototype.changeTableSchema = MsSqlDumper.prototype.changeObjectSchema;
MsSqlDumper.prototype.renameSqlObject = MsSqlDumper.prototype.renameObject;
module.exports = MsSqlDumper;

View File

@ -37,6 +37,7 @@ const dialect = {
dropUnique: true,
createCheck: true,
dropCheck: true,
renameSqlObject: true,
dropReferencesWhenDropTable: true,

View File

@ -38,6 +38,10 @@ class Dumper extends SqlDumper {
this.putCmd('^alter ^table %f ^rename ^to %i', obj, newname);
}
renameSqlObject(obj, newname) {
this.putCmd('^alter %k %f ^rename ^to %i', this.getSqlObjectSqlName(obj.objectTypeField), obj, newname);
}
renameColumn(column, newcol) {
this.putCmd('^alter ^table %f ^rename ^column %i ^to %i', column, column.columnName, newcol);
}

View File

@ -34,6 +34,7 @@ const dialect = {
createCheck: true,
dropCheck: true,
allowMultipleValuesInsert: true,
renameSqlObject: true,
dropReferencesWhenDropTable: true,
requireStandaloneSelectForScopeIdentity: true,