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 engines = require('../engines');
const { getAlterDatabaseScript, extendDatabaseInfo, generateDbPairingId } = require('dbgate-tools'); 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( return _.flatten(
engines engines
.filter(x => !x.skipReferences) .filter(engineCond)
.map(engine => (engine.objects || []).map(object => [engine.label, object.type, object, engine])) .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); 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, supportSchemas: true,
supportRenameSqlObject: true,
defaultSchemaName: 'public', defaultSchemaName: 'public',
dumpFile: 'data/chinook-postgre.sql', dumpFile: 'data/chinook-postgre.sql',
dumpChecks: [ dumpChecks: [
@@ -129,6 +130,7 @@ const engines = [
}, },
], ],
supportSchemas: true, supportSchemas: true,
supportRenameSqlObject: true,
defaultSchemaName: 'dbo', defaultSchemaName: 'dbo',
// skipSeparateSchemas: true, // skipSeparateSchemas: true,
}, },
@@ -184,9 +186,9 @@ const engines = [
const filterLocal = [ const filterLocal = [
// filter local testing // filter local testing
'MySQL', '-MySQL',
'-MariaDB', '-MariaDB',
'-PostgreSQL', 'PostgreSQL',
'-SQL Server', '-SQL Server',
'-SQLite', '-SQLite',
'-CockroachDB', '-CockroachDB',

View File

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

View File

@@ -39,6 +39,12 @@ interface AlterOperation_RenameTable {
newName: string; newName: string;
} }
interface AlterOperation_RenameSqlObject {
operationType: 'renameSqlObject';
object: SqlObjectInfo;
newName: string;
}
interface AlterOperation_CreateColumn { interface AlterOperation_CreateColumn {
operationType: 'createColumn'; operationType: 'createColumn';
newObject: ColumnInfo; newObject: ColumnInfo;
@@ -120,7 +126,8 @@ type AlterOperation =
| AlterOperation_DropSqlObject | AlterOperation_DropSqlObject
| AlterOperation_RecreateTable | AlterOperation_RecreateTable
| AlterOperation_FillPreloadedRows | AlterOperation_FillPreloadedRows
| AlterOperation_SetTableOption; | AlterOperation_SetTableOption
| AlterOperation_RenameSqlObject;
export class AlterPlan { export class AlterPlan {
recreates = { 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) { renameColumn(column: ColumnInfo, newName: string) {
this.operations.push({ this.operations.push({
operationType: 'renameColumn', operationType: 'renameColumn',
@@ -595,6 +610,9 @@ export function runAlterOperation(op: AlterOperation, processor: AlterProcessor)
case 'renameTable': case 'renameTable':
processor.renameTable(op.object, op.newName); processor.renameTable(op.object, op.newName);
break; break;
case 'renameSqlObject':
processor.renameSqlObject(op.object, op.newName);
break;
case 'renameConstraint': case 'renameConstraint':
processor.renameConstraint(op.object, op.newName); processor.renameConstraint(op.object, op.newName);
break; 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; 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) { renameColumn(column: ColumnInfo, newName: string) {
const table = this.db.tables.find(x => x.pureName == column.pureName && x.schemaName == column.schemaName); 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; table.columns.find(x => x.columnName == column.columnName).columnName = newName;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -38,6 +38,10 @@ class Dumper extends SqlDumper {
this.putCmd('^alter ^table %f ^rename ^to %i', obj, newname); 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) { renameColumn(column, newcol) {
this.putCmd('^alter ^table %f ^rename ^column %i ^to %i', column, column.columnName, 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, createCheck: true,
dropCheck: true, dropCheck: true,
allowMultipleValuesInsert: true, allowMultipleValuesInsert: true,
renameSqlObject: true,
dropReferencesWhenDropTable: true, dropReferencesWhenDropTable: true,
requireStandaloneSelectForScopeIdentity: true, requireStandaloneSelectForScopeIdentity: true,