Skip to content

Commit

Permalink
More H2Platform changes to support automatic column alters
Browse files Browse the repository at this point in the history
  • Loading branch information
chenson42 committed Sep 29, 2009
1 parent 6f4327f commit 16b0224
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 21 deletions.
60 changes: 47 additions & 13 deletions symmetric/src/main/java/org/jumpmind/symmetric/db/h2/H2Builder.java
Expand Up @@ -35,6 +35,9 @@
import org.apache.ddlutils.Platform;
import org.apache.ddlutils.alteration.AddColumnChange;
import org.apache.ddlutils.alteration.ColumnChange;
import org.apache.ddlutils.alteration.ColumnDataTypeChange;
import org.apache.ddlutils.alteration.ColumnRequiredChange;
import org.apache.ddlutils.alteration.ColumnSizeChange;
import org.apache.ddlutils.alteration.RemoveColumnChange;
import org.apache.ddlutils.alteration.TableChange;
import org.apache.ddlutils.model.Column;
Expand All @@ -47,8 +50,10 @@
import org.apache.ddlutils.platform.SqlBuilder;

/**
* The SQL Builder for the H2 database.
* From patch <a href="https://issues.apache.org/jira/browse/DDLUTILS-185">https://issues.apache.org/jira/browse/DDLUTILS-185</a>
* The SQL Builder for the H2 database. From patch <a
* href="https://issues.apache.org/jira/browse/DDLUTILS-185"
* >https://issues.apache.org/jira/browse/DDLUTILS-185</a>
*
* @author knaas@users.sourceforge.net
* @version $Revision: 518485 $
*/
Expand Down Expand Up @@ -77,8 +82,8 @@ public void writeExternalIndexDropStmt(Table table, Index index) throws IOExcept
print("DROP INDEX IF EXISTS ");
printIdentifier(getIndexName(index));
printEndOfStatement();
}
}

@Override
@SuppressWarnings("unchecked")
protected void processTableStructureChanges(Database currentModel, Database desiredModel,
Expand Down Expand Up @@ -106,7 +111,7 @@ protected void processTableStructureChanges(Database currentModel, Database desi
changeIt.remove();
}
}

for (ListIterator changeIt = addColumnChanges.listIterator(addColumnChanges.size()); changeIt.hasPrevious();) {
AddColumnChange addColumnChange = (AddColumnChange) changeIt.previous();
processChange(currentModel, desiredModel, addColumnChange);
Expand All @@ -119,30 +124,59 @@ protected void processTableStructureChanges(Database currentModel, Database desi
RemoveColumnChange removeColumnChange = (RemoveColumnChange) change;
processChange(currentModel, desiredModel, removeColumnChange);
changeIt.remove();
}
}
}

for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) {
TableChange change = (TableChange) changeIt.next();
if (change instanceof ColumnChange) {
processAlterColumn(currentModel, (ColumnChange)change);
if (change instanceof ColumnChange) {
boolean needsAlter = true;
if (change instanceof ColumnDataTypeChange) {
ColumnDataTypeChange dataTypeChange = (ColumnDataTypeChange) change;
if (dataTypeChange.getChangedColumn().getTypeCode() == Types.DECIMAL
&& dataTypeChange.getNewTypeCode() == Types.NUMERIC) {
needsAlter = false;
}
if (dataTypeChange.getChangedColumn().getTypeCode() == Types.SMALLINT
&& dataTypeChange.getNewTypeCode() == Types.TINYINT) {
needsAlter = false;
}
if (dataTypeChange.getChangedColumn().getTypeCode() == Types.VARCHAR
&& dataTypeChange.getNewTypeCode() == Types.LONGVARCHAR) {
needsAlter = false;
}
}
if (change instanceof ColumnRequiredChange) {
needsAlter = false;
}
if (change instanceof ColumnSizeChange) {
ColumnSizeChange sizeChange = (ColumnSizeChange) change;
if (sizeChange.getNewScale() == 0 && sizeChange.getNewSize() == 0) {
needsAlter = false;
} else if (sizeChange.getNewSize() == sizeChange.getChangedColumn().getSizeAsInt()
&& sizeChange.getNewScale() == sizeChange.getChangedColumn().getScale()) {
needsAlter = false;
}
}
if (needsAlter) {
processAlterColumn(currentModel, (ColumnChange) change);
}
changeIt.remove();
}
}
}

}


protected void processAlterColumn(Database currentModel, ColumnChange columnChange) throws IOException {
columnChange.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn());
columnChange.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn());
print("ALTER TABLE ");
printlnIdentifier(getTableName(columnChange.getChangedTable()));
printIndent();
print("ALTER COLUMN ");
writeColumn(columnChange.getChangedTable(), columnChange.getChangedColumn());
printEndOfStatement();
printEndOfStatement();
}

/**
* Processes the addition of a column to a table.
*
Expand Down
Expand Up @@ -19,7 +19,10 @@
* under the License.
*/

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.ddlutils.Platform;
Expand All @@ -30,13 +33,19 @@
import org.apache.ddlutils.model.TypeMap;
import org.apache.ddlutils.platform.DatabaseMetaDataWrapper;
import org.apache.ddlutils.platform.JdbcModelReader;
import org.apache.ddlutils.platform.MetaDataColumnDescriptor;
import org.jumpmind.symmetric.common.logging.ILog;
import org.jumpmind.symmetric.common.logging.LogFactory;

/**
* Reads a database model from a H2 database. From patch <a
* href="https://issues.apache.org/jira/browse/DDLUTILS-185"
* >https://issues.apache.org/jira/browse/DDLUTILS-185</a>
*/
public class H2ModelReader extends JdbcModelReader {

final ILog logger = LogFactory.getLog(getClass());

/**
* Creates a new model reader for H2 databases.
*
Expand All @@ -48,16 +57,57 @@ public H2ModelReader(Platform platform) {
setDefaultCatalogPattern(null);
setDefaultSchemaPattern(null);
}


@SuppressWarnings("unchecked")
@Override
protected Map readColumns(ResultSet resultSet, List columnDescriptors) throws SQLException {
//if (logger.isDebugEnabled())
{
int count = resultSet.getMetaData().getColumnCount();
for (int i = 1 ; i <= count; i++) {
logger.info(resultSet.getMetaData().getColumnName(i) + "=" + resultSet.getString(i));
}
}
return super.readColumns(resultSet, columnDescriptors);
}

@Override
@SuppressWarnings("unchecked")
protected Column readColumn(DatabaseMetaDataWrapper metaData, Map values) throws SQLException {
Column column = super.readColumn(metaData, values);
if (values.get("CHARACTER_MAXIMUM_LENGTH") != null) {
column.setSize(values.get("CHARACTER_MAXIMUM_LENGTH").toString());
}
if (values.get("COLUMN_DEFAULT") != null) {
column.setDefaultValue(values.get("COLUMN_DEFAULT").toString());
}
if (values.get("NUMERIC_SCALE") != null) {
column.setScale((Integer)values.get("NUMERIC_SCALE"));
}
if (TypeMap.isTextType(column.getTypeCode()) && (column.getDefaultValue() != null)) {
column.setDefaultValue(unescape(column.getDefaultValue(), "'", "''"));
}
return column;
}

@SuppressWarnings("unchecked")
@Override
protected List initColumnsForColumn() {
List result = new ArrayList();
result.add(new MetaDataColumnDescriptor("COLUMN_DEF", 12));
result.add(new MetaDataColumnDescriptor("COLUMN_DEFAULT", 12));
result.add(new MetaDataColumnDescriptor("TABLE_NAME", 12));
result.add(new MetaDataColumnDescriptor("COLUMN_NAME", 12));
result.add(new MetaDataColumnDescriptor("DATA_TYPE", 4, new Integer(1111)));
result.add(new MetaDataColumnDescriptor("NUM_PREC_RADIX", 4, new Integer(10)));
result.add(new MetaDataColumnDescriptor("DECIMAL_DIGITS", 4, new Integer(0)));
result.add(new MetaDataColumnDescriptor("NUMERIC_SCALE", 4, new Integer(0)));
result.add(new MetaDataColumnDescriptor("COLUMN_SIZE", 12));
result.add(new MetaDataColumnDescriptor("CHARACTER_MAXIMUM_LENGTH", 12));
result.add(new MetaDataColumnDescriptor("IS_NULLABLE", 12, "YES"));
result.add(new MetaDataColumnDescriptor("REMARKS", 12));
return result;
}

@Override
protected boolean isInternalForeignKeyIndex(DatabaseMetaDataWrapper metaData, Table table, ForeignKey fk,
Expand Down
Expand Up @@ -19,27 +19,59 @@ public class H2PlatformUnitTest {

private static final String H2 = "H2";


@Test
public void testColumnSizeChange() throws Exception {
public void testColumnSizeChangeToVarchar() throws Exception {
Platform pf = getPlatform();
Database db = new Database();
Table table = new Table();
table.setName("TEST_TABLE");
table.setName("TEST_TABLE_VARCHAR");
Column column1 = new Column();
column1.setName("COLUMN_1");
column1.setType("VARCHAR");
column1.setSize("20");
table.addColumn(column1);
db.addTable(table);
pf.createTables(db, true, true);
pf.createTables(db, false, false);

SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(pf.getDataSource());
Assert.assertEquals(0, jdbcTemplate.queryForInt("select count(*) from TEST_TABLE"));
Assert.assertEquals(20, jdbcTemplate.queryForInt("select NUMERIC_PRECISION from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='TEST_TABLE' and COLUMN_NAME='COLUMN_1'"));
Assert.assertEquals(0, jdbcTemplate.queryForInt("select count(*) from TEST_TABLE_VARCHAR"));
Assert.assertEquals(20, jdbcTemplate.queryForInt("select NUMERIC_PRECISION from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='TEST_TABLE_VARCHAR' and COLUMN_NAME='COLUMN_1'"));

Database readDb = pf.readModelFromDatabase(null);
Table[] tables = readDb.getTables();
for (Table t : tables) {
if (t.getName().equals("TEST_TABLE_VARCHAR")) {
Assert.assertEquals(20, t.getColumn(0).getSizeAsInt());
}
}

column1.setSize("50");
pf.alterTables(db, true);
Assert.assertEquals(50, jdbcTemplate.queryForInt("select NUMERIC_PRECISION from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='TEST_TABLE' and COLUMN_NAME='COLUMN_1'"));
pf.alterTables(null, null, null, db, false);
Assert.assertEquals(50, jdbcTemplate.queryForInt("select NUMERIC_PRECISION from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='TEST_TABLE_VARCHAR' and COLUMN_NAME='COLUMN_1'"));
}

@Test
public void testColumnSizeChangeToNumeric() throws Exception {
Platform pf = getPlatform();
Database db = new Database();
Table table = new Table();
table.setName("TEST_TABLE_NUMERIC");
Column column1 = new Column();
column1.setName("COLUMN_1");
column1.setType("NUMERIC");
column1.setSize("15");
table.addColumn(column1);
db.addTable(table);
pf.createTables(db, false, false);

SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(pf.getDataSource());
Assert.assertEquals(0, jdbcTemplate.queryForInt("select count(*) from TEST_TABLE_NUMERIC"));
Assert.assertEquals(15, jdbcTemplate.queryForInt("select NUMERIC_PRECISION from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='TEST_TABLE_NUMERIC' and COLUMN_NAME='COLUMN_1'"));

column1.setSize("200");
pf.alterTables(null, null, null, db, false);
Assert.assertEquals(200, jdbcTemplate.queryForInt("select NUMERIC_PRECISION from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='TEST_TABLE_NUMERIC' and COLUMN_NAME='COLUMN_1'"));
}

protected Platform getPlatform() throws Exception {
Expand Down

0 comments on commit 16b0224

Please sign in to comment.