Skip to content

Commit

Permalink
0005717: SQL Server DDL Builder needs to handle objects in different
Browse files Browse the repository at this point in the history
databases
  • Loading branch information
Philip Marzullo committed Mar 2, 2023
1 parent 00e0991 commit 3cbb2c9
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 37 deletions.
Expand Up @@ -49,6 +49,7 @@
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.jumpmind.db.alter.AddColumnChange;
import org.jumpmind.db.alter.AddForeignKeyChange;
import org.jumpmind.db.alter.AddIndexChange;
Expand Down Expand Up @@ -135,35 +136,58 @@ protected void createTable(Table table, StringBuilder ddl, boolean temporary, bo
@Override
protected void dropTable(Table table, StringBuilder ddl, boolean temporary, boolean recreate) {
String tableName = getTableName(table.getName());
String catalog = table.getCatalog();
String schema = table.getSchema();
String tableNameVar = "tn" + createUniqueIdentifier();
String constraintNameVar = "cn" + createUniqueIdentifier();
writeQuotationOnStatement(ddl);
ddl.append("IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = ");
ddl.append("IF EXISTS (SELECT 1 FROM ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
ddl.append("dbo.sysobjects WHERE type = 'U' AND name = ");
printAlwaysSingleQuotedIdentifier(tableName, ddl);
println(")", ddl);
println("BEGIN", ddl);
println(" DECLARE @" + tableNameVar + " nvarchar(256), @" + constraintNameVar
+ " nvarchar(256)", ddl);
println(" DECLARE refcursor CURSOR FOR", ddl);
println(" SELECT object_name(objs.parent_obj) tablename, objs.name constraintname", ddl);
println(" FROM sysobjects objs", ddl);
ddl.append(" FROM ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
ddl.append("dbo.sysobjects objs");
ddl.append(" WHERE objs.xtype in ('C','D','F','UQ') AND object_name(objs.parent_obj) = ");
printAlwaysSingleQuotedIdentifier(tableName, ddl);
println("", ddl);
println(" OPEN refcursor", ddl);
println(" FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @" + constraintNameVar,
ddl);
println(" WHILE @@FETCH_STATUS = 0", ddl);
println(" BEGIN", ddl);
println(" EXEC ('ALTER TABLE '+@" + tableNameVar + "+' DROP CONSTRAINT '+@"
+ constraintNameVar + ")", ddl);
ddl.append(" EXEC ('ALTER TABLE ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
if (StringUtils.isNotBlank(schema)) {
printIdentifier(schema, ddl);
ddl.append(".");
}
ddl.append("'+@" + tableNameVar + "+' DROP CONSTRAINT '+@" + constraintNameVar + ")");
println("", ddl);
println(" FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @" + constraintNameVar,
ddl);
println(" END", ddl);
println(" CLOSE refcursor", ddl);
println(" DEALLOCATE refcursor", ddl);
ddl.append(" DROP TABLE ");
printlnIdentifier(tableName, ddl);
ddl.append("END");
ddl.append(getFullyQualifiedTableNameShorten(table));
println("", ddl);
println("END", ddl);
printEndOfStatement(ddl);
}

Expand Down Expand Up @@ -259,7 +283,13 @@ protected void writeColumnAutoIncrementStmt(Table table, Column column, StringBu
protected void writeExternalForeignKeyDropStmt(Table table, ForeignKey foreignKey,
StringBuilder ddl) {
String constraintName = getForeignKeyName(table, foreignKey);
ddl.append("IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'F' AND name = ");
String catalog = table.getCatalog();
ddl.append("IF EXISTS (SELECT 1 FROM ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
ddl.append("sys.sysobjects WHERE type = 'F' AND name = ");
printAlwaysSingleQuotedIdentifier(constraintName, ddl);
println(")", ddl);
printIndent(ddl);
Expand Down Expand Up @@ -514,7 +544,7 @@ protected void processChange(Database currentModel, Database desiredModel,
RemoveColumnChange change, StringBuilder ddl) {
boolean hasDefault = change.getColumn().getParsedDefaultValue() != null;
if (hasDefault) {
dropDefaultConstraint(change.getChangedTable().getName(), change.getColumn().getName(), ddl);
dropDefaultConstraint(change.getChangedTable(), change.getColumn().getName(), ddl);
}
ddl.append("ALTER TABLE ");
ddl.append(getFullyQualifiedTableNameShorten(change.getChangedTable()));
Expand All @@ -532,24 +562,48 @@ protected void processChange(Database currentModel, Database desiredModel,
RemovePrimaryKeyChange change, StringBuilder ddl) {
// TODO: this would be easier when named primary keys are supported
// because then we can use ALTER TABLE DROP
String catalog = change.getChangedTable().getCatalog();
String schema = change.getChangedTable().getSchema();
String tableName = getTableName(change.getChangedTable().getName());
String tableNameVar = "tn" + createUniqueIdentifier();
String constraintNameVar = "cn" + createUniqueIdentifier();
println("BEGIN", ddl);
println(" DECLARE @" + tableNameVar + " nvarchar(256), @" + constraintNameVar
+ " nvarchar(256)", ddl);
println(" DECLARE refcursor CURSOR FOR", ddl);
println(" SELECT object_name(objs.parent_obj) tablename, objs.name constraintname", ddl);
println(" FROM sysobjects objs", ddl);
ddl.append(" WHERE objs.xtype = 'PK' AND object_name(objs.parent_obj) = ");
println(" SELECT parentobjs.name tablename, objs.name constraintname", ddl);
ddl.append(" FROM ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
println("dbo.sysobjects objs", ddl);
ddl.append(" JOIN ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
println("dbo.sysobjects parentobjs on objs.parent_obj=parentobjs.id", ddl);
ddl.append(" WHERE objs.xtype = 'PK' AND parentobjs.name = ");
printAlwaysSingleQuotedIdentifier(tableName, ddl);
println("", ddl);
println(" OPEN refcursor", ddl);
println(" FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @" + constraintNameVar,
ddl);
println(" WHILE @@FETCH_STATUS = 0", ddl);
println(" BEGIN", ddl);
println(" EXEC ('ALTER TABLE '+@" + tableNameVar + "+' DROP CONSTRAINT '+@"
+ constraintNameVar + ")", ddl);

ddl.append(" EXEC ('ALTER TABLE ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
if (StringUtils.isNotBlank(schema)) {
printIdentifier(schema, ddl);
ddl.append(".");
}
ddl.append("'+@" + tableNameVar + "+' DROP CONSTRAINT '+@" + constraintNameVar + ")");
println("", ddl);
println(" FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @" + constraintNameVar,
ddl);
println(" END", ddl);
Expand All @@ -560,17 +614,17 @@ protected void processChange(Database currentModel, Database desiredModel,
change.apply(currentModel, delimitedIdentifierModeOn);
}

protected void dropDefaultConstraint(String tableName, String columnName, StringBuilder ddl) {
protected void dropDefaultConstraint(Table table, String columnName, StringBuilder ddl) {
println("BEGIN ", ddl);
println("DECLARE @sql NVARCHAR(2000) ", ddl);
println(String.format("SELECT TOP 1 @sql = N'alter table \"%s\" drop constraint ['+objs.NAME+N']' ", tableName), ddl);
println(String.format("SELECT TOP 1 @sql = N'alter table \"%s\" drop constraint ['+objs.NAME+N']' ", table.getName()), ddl);
println("FROM dbo.sysconstraints dc ", ddl);
println("JOIN dbo.sysobjects objs ", ddl);
println(" ON objs.id = dc.constid ", ddl);
println("JOIN sys.columns c ", ddl);
println(" ON c.default_object_id = dc.colid ", ddl);
println("WHERE ", ddl);
println(String.format(" dc.id = OBJECT_ID('%s') ", tableName), ddl);
println(String.format(" dc.id = OBJECT_ID('%s') ", table.getName()), ddl);
println(String.format("AND c.name = N'%s' ", columnName), ddl);
println("IF @@ROWCOUNT > 0 ", ddl);
println(" EXEC (@sql) ", ddl);
Expand Down
Expand Up @@ -22,6 +22,7 @@

import java.sql.Types;

import org.apache.commons.lang3.StringUtils;
import org.jumpmind.db.model.Column;
import org.jumpmind.db.model.Table;
import org.jumpmind.db.platform.DatabaseNamesConstants;
Expand All @@ -34,19 +35,50 @@ public MsSql2005DdlBuilder() {
databaseInfo.addNativeTypeMapping(Types.SQLXML, "XML", Types.SQLXML);
}

protected void dropDefaultConstraint(String tableName, String columnName, StringBuilder ddl) {
println("BEGIN ", ddl);
println("DECLARE @sql NVARCHAR(2000) ", ddl);
println(String.format("SELECT TOP 1 @sql = N'alter table \"%s\" drop constraint ['+dc.NAME+N']' ", tableName), ddl);
println("FROM sys.default_constraints dc ", ddl);
println("JOIN sys.columns c ", ddl);
println(" ON c.default_object_id = dc.object_id ", ddl);
println("WHERE ", ddl);
println(String.format(" dc.parent_object_id = OBJECT_ID('%s') ", tableName), ddl);
println(String.format("AND c.name = N'%s' ", columnName), ddl);
println("IF @@ROWCOUNT > 0 ", ddl);
println(" EXEC (@sql) ", ddl);
println("END ", ddl);
protected void dropDefaultConstraint(Table table, String columnName, StringBuilder ddl) {
String catalog = table.getCatalog();
String schema = table.getSchema();
println("BEGIN", ddl);
println("DECLARE @sql NVARCHAR(2000)", ddl);
ddl.append("SELECT @sql = N'alter table ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
if (StringUtils.isNotBlank(schema)) {
printIdentifier(schema, ddl);
ddl.append(".");
}
printIdentifier(table.getName(), ddl);
println(" drop constraint ['+cons.NAME+N']'", ddl);
ddl.append("from ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
println("sys.default_constraints cons", ddl);
ddl.append("join ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
println("sys.syscolumns cols on cons.parent_object_id = cols.id and cons.parent_column_id = cols.colid", ddl);
ddl.append("join ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
println("sys.sysobjects objs on objs.id=cons.parent_object_id", ddl);
ddl.append("join ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
println("sys.schemas sch on sch.schema_id = objs.uid", ddl);
println("WHERE cols.name='"+columnName+"' and objs.name='"+table.getName()+"' and sch.name='"+schema+"'", ddl);
println("IF @@ROWCOUNT > 0", ddl);
println(" EXEC (@sql)", ddl);
println("END", ddl);
printEndOfStatement(ddl);
}

Expand All @@ -56,26 +88,81 @@ protected void dropColumnChangeDefaults(Table sourceTable, Column sourceColumn,
String columnName = getColumnName(sourceColumn);
String tableNameVar = "tn" + createUniqueIdentifier();
String constraintNameVar = "cn" + createUniqueIdentifier();
String catalog = sourceTable.getCatalog();
String schema = sourceTable.getSchema();
println("BEGIN", ddl);
println(" DECLARE @" + tableNameVar + " nvarchar(256), @" + constraintNameVar
+ " nvarchar(256)", ddl);
println(" DECLARE refcursor CURSOR FOR", ddl);
println(" SELECT object_name(cons.parent_object_id) tablename, cons.name constraintname FROM sys.default_constraints cons ",
ddl);
println(" WHERE cons.parent_column_id = (SELECT colid FROM syscolumns WHERE id = object_id(", ddl);
println(" select objs.name tablename, cons.name constraintname ", ddl);
ddl.append(" from ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
println("sys.default_constraints cons", ddl);
ddl.append("join ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
println("sys.sysobjects objs on cons.parent_object_id=objs.id", ddl);
ddl.append("join ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
println("sys.schemas sch on objs.uid=sch.schema_id", ddl);
println(" where cons.parent_column_id=(", ddl);
println(" SELECT colid", ddl);
ddl.append(" FROM ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
println("sys.syscolumns cols", ddl);
ddl.append(" JOIN ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
println("sys.sysobjects objs on objs.id=cols.id", ddl);
ddl.append(" JOIN ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
println("sys.schemas sch on sch.schema_id=objs.uid", ddl);
ddl.append("WHERE objs.name = ");
printAlwaysSingleQuotedIdentifier(tableName, ddl);
ddl.append(") AND name = ");
ddl.append(" and cols.name = ");
printAlwaysSingleQuotedIdentifier(columnName, ddl);
println(") AND", ddl);
ddl.append(" object_name(cons.parent_object_id) = ");
if (StringUtils.isNotBlank(schema)) {
ddl.append(" AND sch.name=");
printAlwaysSingleQuotedIdentifier(schema, ddl);
}
println(")", ddl);
ddl.append(" AND objs.name=");
printAlwaysSingleQuotedIdentifier(tableName, ddl);
ddl.append(" AND sch.name=");
printAlwaysSingleQuotedIdentifier(schema, ddl);
println("", ddl);
println(" OPEN refcursor", ddl);
println(" FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @" + constraintNameVar,
ddl);
println(" WHILE @@FETCH_STATUS = 0", ddl);
println(" BEGIN", ddl);
println(" EXEC ('ALTER TABLE '+@" + tableNameVar + "+' DROP CONSTRAINT '+@"
+ constraintNameVar + ")", ddl);
ddl.append(" EXEC ('ALTER TABLE ");
if (StringUtils.isNotBlank(catalog)) {
printIdentifier(catalog, ddl);
ddl.append(".");
}
if (StringUtils.isNotBlank(schema)) {
printIdentifier(schema, ddl);
ddl.append(".");
}
ddl.append("'+@" + tableNameVar + "+' DROP CONSTRAINT '+@" + constraintNameVar + ")");
println("", ddl);
println(" FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @"
+ constraintNameVar, ddl);
println(" END", ddl);
Expand Down

0 comments on commit 3cbb2c9

Please sign in to comment.