Skip to content

Commit

Permalink
0000713: Automate upgrade from 2.x to 3.x for sql server
Browse files Browse the repository at this point in the history
  • Loading branch information
chenson42 committed Jul 22, 2012
1 parent b2791ae commit 5e4a3de
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 110 deletions.
Expand Up @@ -434,7 +434,7 @@ public boolean createOrAlterTablesIfNecessary() {

String alterSql = builder.alterDatabase(modelFromDatabase, modelFromXml);

log.info("Alter SQL Generated: {}", alterSql);
log.info("Alter SQL generated: {}", alterSql);

new SqlScript(alterSql, getPlatform().getSqlTemplate(), true, delimiter, null)
.execute(platform.getDatabaseInfo().isRequiresAutoCommitForDdl());
Expand Down
Expand Up @@ -26,8 +26,6 @@

/**
* Represents the addition of an index to a table.
*
* @version $Revision: $
*/
public class AddIndexChange extends TableChangeImplBase
{
Expand Down
Expand Up @@ -58,7 +58,7 @@ public boolean hasColumn(Column column) {
for (int idx = 0; idx < columns.size(); idx++) {
IndexColumn curColumn = getColumn(idx);

if (column.equals(curColumn.getColumn())) {
if (column.getName().equals(curColumn.getName())) {
return true;
}
}
Expand Down
Expand Up @@ -1648,11 +1648,8 @@ protected void writeColumns(Table table, StringBuilder ddl) {
protected String getColumnName(Column column) {
return shortenName(column.getName(), databaseInfo.getMaxColumnNameLength());
}

/**
* Outputs the DDL for the specified column.
*/
protected void writeColumn(Table table, Column column, StringBuilder ddl) {

protected void writeColumnTypeDefaultRequired(Table table, Column column, StringBuilder ddl) {
// see comments in columnsDiffer about null/"" defaults
printIdentifier(getColumnName(column), ddl);
ddl.append(" ");
Expand All @@ -1665,8 +1662,14 @@ protected void writeColumn(Table table, Column column, StringBuilder ddl) {
&& databaseInfo.hasNullDefault(column.getMappedTypeCode())) {
ddl.append(" ");
writeColumnNullableStmt(ddl);
}
}
}

/**
* Outputs the DDL for the specified column.
*/
protected void writeColumn(Table table, Column column, StringBuilder ddl) {
writeColumnTypeDefaultRequired(table, column, ddl);
if (column.isPrimaryKey() && databaseInfo.isPrimaryKeyEmbedded()) {
writeColumnEmbeddedPrimaryKey(table, column, ddl);
}
Expand Down
Expand Up @@ -94,16 +94,15 @@ public MsSqlDdlBuilder() {
databaseInfo.setDefaultSize(Types.BINARY, 254);
databaseInfo.setDefaultSize(Types.VARBINARY, 254);


databaseInfo.setDateOverridesToTimestamp(true);
databaseInfo.setNonBlankCharColumnSpacePadded(true);
databaseInfo.setBlankCharColumnSpacePadded(true);
databaseInfo.setCharColumnSpaceTrimmed(false);
databaseInfo.setEmptyStringNulled(false);
databaseInfo.setAutoIncrementUpdateAllowed(false);

addEscapedCharSequence("'", "''");
}
}

@Override
public void createTable(Table table, StringBuilder ddl) {
Expand Down Expand Up @@ -172,41 +171,41 @@ protected String getValueAsString(Column column, Object value) {
StringBuffer result = new StringBuffer();

switch (column.getMappedTypeCode()) {
case Types.REAL:
case Types.NUMERIC:
case Types.FLOAT:
case Types.DOUBLE:
case Types.DECIMAL:
// SQL Server does not want quotes around the value
if (!(value instanceof String) && (getValueNumberFormat() != null)) {
result.append(getValueNumberFormat().format(value));
} else {
case Types.REAL:
case Types.NUMERIC:
case Types.FLOAT:
case Types.DOUBLE:
case Types.DECIMAL:
// SQL Server does not want quotes around the value
if (!(value instanceof String) && (getValueNumberFormat() != null)) {
result.append(getValueNumberFormat().format(value));
} else {
result.append(value.toString());
}
break;
case Types.DATE:
result.append("CAST(");
result.append(databaseInfo.getValueQuoteToken());
result.append(value instanceof String ? (String) value : getValueDateFormat()
.format(value));
result.append(databaseInfo.getValueQuoteToken());
result.append(" AS datetime)");
break;
case Types.TIME:
result.append("CAST(");
result.append(databaseInfo.getValueQuoteToken());
result.append(value instanceof String ? (String) value : getValueTimeFormat()
.format(value));
result.append(databaseInfo.getValueQuoteToken());
result.append(" AS datetime)");
break;
case Types.TIMESTAMP:
result.append("CAST(");
result.append(databaseInfo.getValueQuoteToken());
result.append(value.toString());
}
break;
case Types.DATE:
result.append("CAST(");
result.append(databaseInfo.getValueQuoteToken());
result.append(value instanceof String ? (String) value : getValueDateFormat().format(
value));
result.append(databaseInfo.getValueQuoteToken());
result.append(" AS datetime)");
break;
case Types.TIME:
result.append("CAST(");
result.append(databaseInfo.getValueQuoteToken());
result.append(value instanceof String ? (String) value : getValueTimeFormat().format(
value));
result.append(databaseInfo.getValueQuoteToken());
result.append(" AS datetime)");
break;
case Types.TIMESTAMP:
result.append("CAST(");
result.append(databaseInfo.getValueQuoteToken());
result.append(value.toString());
result.append(databaseInfo.getValueQuoteToken());
result.append(" AS datetime)");
break;
result.append(databaseInfo.getValueQuoteToken());
result.append(" AS datetime)");
break;
}
return super.getValueAsString(column, value);
}
Expand All @@ -217,8 +216,8 @@ protected String getNativeDefaultValue(Column column) {
if ((column.getMappedTypeCode() == Types.BIT)
|| (PlatformUtils.supportsJava14JdbcTypes() && (column.getMappedTypeCode() == PlatformUtils
.determineBooleanTypeCode()))) {
return getDefaultValueHelper().convert(column.getDefaultValue(), column.getMappedTypeCode(),
Types.SMALLINT).toString();
return getDefaultValueHelper().convert(column.getDefaultValue(),
column.getMappedTypeCode(), Types.SMALLINT).toString();
} else {
return super.getNativeDefaultValue(column);
}
Expand Down Expand Up @@ -262,8 +261,7 @@ protected void writeExternalForeignKeyDropStmt(Table table, ForeignKey foreignKe
*/
private String getQuotationOnStatement() {
if (delimitedIdentifierModeOn) {
return "SET quoted_identifier on" + databaseInfo.getSqlCommandDelimiter()
+ "\n";
return "SET quoted_identifier on" + databaseInfo.getSqlCommandDelimiter() + "\n";
} else {
return "";
}
Expand Down Expand Up @@ -341,20 +339,19 @@ protected void processChanges(Database currentModel, Database desiredModel,
if (!changes.isEmpty()) {
writeQuotationOnStatement(ddl);
}
// For column data type and size changes, we need to drop and then
// re-create indexes
// and foreign keys using the column, as well as any primary keys
// containg
// these columns
// However, if the index/foreign key/primary key is already slated for
// removal or
// change, then we don't want to generate change duplication
HashSet removedIndexes = new HashSet();
HashSet removedForeignKeys = new HashSet();
HashSet removedPKs = new HashSet();

for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) {
Object change = changeIt.next();
/*
* For column data type and size changes, we need to drop and then
* re-create indexes and foreign keys using the column, as well as any
* primary keys containg these columns However, if the index/foreign
* key/primary key is already slated for removal or change, then we
* don't want to generate change duplication
*/
HashSet<IIndex> removedIndexes = new HashSet<IIndex>();
HashSet<ForeignKey> removedForeignKeys = new HashSet<ForeignKey>();
HashSet<Table> removedPKs = new HashSet<Table>();

for (Iterator<IModelChange> changeIt = changes.iterator(); changeIt.hasNext();) {
IModelChange change = changeIt.next();

if (change instanceof RemoveIndexChange) {
removedIndexes.add(((RemoveIndexChange) change).getIndex());
Expand All @@ -365,10 +362,10 @@ protected void processChanges(Database currentModel, Database desiredModel,
}
}

ArrayList additionalChanges = new ArrayList();
ArrayList<TableChange> additionalChanges = new ArrayList<TableChange>();

for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) {
Object change = changeIt.next();
for (Iterator<IModelChange> changeIt = changes.iterator(); changeIt.hasNext();) {
IModelChange change = changeIt.next();

if ((change instanceof ColumnDataTypeChange) || (change instanceof ColumnSizeChange)) {
Column column = ((ColumnChange) change).getChangedColumn();
Expand Down Expand Up @@ -413,6 +410,19 @@ protected void processChanges(Database currentModel, Database desiredModel,
@Override
protected void processTableStructureChanges(Database currentModel, Database desiredModel,
Table sourceTable, Table targetTable, List<TableChange> changes, StringBuilder ddl) {

for (Iterator<TableChange> changeIt = changes.iterator(); changeIt.hasNext();) {
TableChange change = changeIt.next();
if (change instanceof ColumnAutoIncrementChange) {
/*
* Sql Server has no way of adding or removing an IDENTITY
* constraint thus we have to rebuild the table anyway and can
* ignore all the other column changes
*/
return;
}
}

// First we drop primary keys as necessary
for (Iterator<TableChange> changeIt = changes.iterator(); changeIt.hasNext();) {
TableChange change = changeIt.next();
Expand All @@ -428,43 +438,33 @@ protected void processTableStructureChanges(Database currentModel, Database desi
processChange(currentModel, desiredModel, removePkChange, ddl);
}
}

ArrayList columnChanges = new ArrayList();
ArrayList<ColumnChange> columnChanges = new ArrayList<ColumnChange>();

// Next we add/remove columns
for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) {
TableChange change = (TableChange) changeIt.next();
for (Iterator<TableChange> changeIt = changes.iterator(); changeIt.hasNext();) {
TableChange change = changeIt.next();

if (change instanceof AddColumnChange) {
AddColumnChange addColumnChange = (AddColumnChange) change;

// Sql Server can only add not insert columns
if (addColumnChange.isAtEnd()) {
processChange(currentModel, desiredModel, addColumnChange, ddl);
changeIt.remove();
}
processChange(currentModel, desiredModel, addColumnChange, ddl);
changeIt.remove();
} else if (change instanceof RemoveColumnChange) {
processChange(currentModel, desiredModel, (RemoveColumnChange) change, ddl);
changeIt.remove();
} else if (change instanceof ColumnAutoIncrementChange) {
// Sql Server has no way of adding or removing an IDENTITY
// constraint
// Thus we have to rebuild the table anyway and can ignore all
// the other
// column changes
columnChanges = null;
} else if ((change instanceof ColumnChange) && (columnChanges != null)) {
// we gather all changed columns because we can use the ALTER
// TABLE ALTER COLUMN
// statement for them
columnChanges.add(change);
/*
* We gather all changed columns because we can use the ALTER
* TABLE ALTER COLUMN statement for them
*/
columnChanges.add((ColumnChange) change);
}
}
if (columnChanges != null) {
HashSet processedColumns = new HashSet();
HashSet<Column> processedColumns = new HashSet<Column>();

for (Iterator changeIt = columnChanges.iterator(); changeIt.hasNext();) {
ColumnChange change = (ColumnChange) changeIt.next();
for (Iterator<ColumnChange> changeIt = columnChanges.iterator(); changeIt.hasNext();) {
ColumnChange change = changeIt.next();
Column sourceColumn = change.getChangedColumn();
Column targetColumn = targetTable.findColumn(sourceColumn.getName(),
delimitedIdentifierModeOn);
Expand All @@ -480,8 +480,8 @@ protected void processTableStructureChanges(Database currentModel, Database desi
}
}
// Finally we add primary keys
for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) {
TableChange change = (TableChange) changeIt.next();
for (Iterator<TableChange> changeIt = changes.iterator(); changeIt.hasNext();) {
TableChange change = changeIt.next();

if (change instanceof AddPrimaryKeyChange) {
processChange(currentModel, desiredModel, (AddPrimaryKeyChange) change, ddl);
Expand Down Expand Up @@ -570,9 +570,11 @@ protected void processColumnChange(Table sourceTable, Table targetTable, Column
boolean shallHaveDefault = targetColumn.getParsedDefaultValue() != null;
String newDefault = targetColumn.getDefaultValue();

// Sql Server does not like it if there is a default spec in the ALTER
// TABLE ALTER COLUMN
// statement; thus we have to change the default manually
/*
* Sql Server does not like it if there is a default spec in the ALTER
* TABLE ALTER COLUMN statement; thus we have to change the default
* manually
*/
if (newDefault != null) {
targetColumn.setDefaultValue(null);
}
Expand Down Expand Up @@ -619,20 +621,16 @@ protected void processColumnChange(Table sourceTable, Table targetTable, Column
printlnIdentifier(getTableName(sourceTable.getName()), ddl);
printIndent(ddl);
ddl.append("ALTER COLUMN ");
if (typeChange) {
printIdentifier(getColumnName(targetColumn), ddl);
ddl.append(" ");
ddl.append(getSqlType(targetColumn));
} else {
writeColumn(sourceTable, targetColumn, ddl);
}
writeColumnTypeDefaultRequired(sourceTable, targetColumn, ddl);
printEndOfStatement(ddl);

if (shallHaveDefault) {
targetColumn.setDefaultValue(newDefault);

// if the column shall have a default, then we have to add it as a
// constraint
/*
* if the column shall have a default, then we have to add it as a
* constraint
*/
ddl.append("ALTER TABLE ");
printlnIdentifier(getTableName(sourceTable.getName()), ddl);
printIndent(ddl);
Expand All @@ -644,7 +642,7 @@ protected void processColumnChange(Table sourceTable, Table targetTable, Column
printEndOfStatement(ddl);
}
}

/**
* Creates a reasonably unique identifier only consisting of hexadecimal
* characters and underscores. It looks like
Expand Down
6 changes: 3 additions & 3 deletions symmetric-jdbc/src/test/resources/db-test.properties
@@ -1,4 +1,4 @@
test.root=h2
test.root=mssql
test.client=h2

mysql.db.driver=com.mysql.jdbc.Driver
Expand Down Expand Up @@ -35,8 +35,8 @@ h2.root.db.url=jdbc:h2:file:target/rootdbs/root
mssql.db.driver=net.sourceforge.jtds.jdbc.Driver
mssql.db.user=sa
mssql.db.password=symmetric
mssql.client.db.url=jdbc:jtds:sqlserver://hudson/SymmetricClient
mssql.root.db.url=jdbc:jtds:sqlserver://hudson/SymmetricRoot
mssql.client.db.url=jdbc:jtds:sqlserver://localhost:55557/SymmetricClient
mssql.root.db.url=jdbc:jtds:sqlserver://localhost:55557/SymmetricRoot

sqlserver.db.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
sqlserver.db.user=sa
Expand Down

0 comments on commit 5e4a3de

Please sign in to comment.