Permalink
Browse files

CORE-1215 Unable to 'update' or 'generateChangeLog' in MS SQL Server …

…'08 or '12 due to SQLServerException

Made sure sql2008 was running tests correctly
  • Loading branch information...
1 parent 4af092b commit 1144d44b99456408926b368dd6a27d4234fb86d7 @nvoxland nvoxland committed Oct 17, 2012
@@ -246,11 +246,7 @@ public boolean supportsRestrictForeignKeys() {
@Override
public boolean supportsDropTableCascadeConstraints() {
- try {
- return this.getDatabaseMajorVersion() >= 10;
- } catch (DatabaseException e) {
- return true;
- }
+ return false;
}
@Override
@@ -2,6 +2,8 @@
import liquibase.database.Database;
import liquibase.database.structure.DataType;
+import liquibase.datatype.core.BigIntType;
+import liquibase.datatype.core.IntType;
import liquibase.datatype.core.UnknownType;
import liquibase.exception.UnexpectedLiquibaseException;
import liquibase.servicelocator.ServiceLocator;
@@ -88,6 +90,11 @@ public LiquibaseDataType fromDescription(String dataTypeDefinition) {
if (dataTypeName.matches(".+\\{.*")) {
dataTypeName = dataTypeDefinition.replaceFirst("\\s*\\{.*", "");
}
+ boolean primaryKey = false;
+ if (dataTypeName.endsWith(" identity")) {
+ dataTypeName = dataTypeName.replaceFirst(" identity$", "");
+ primaryKey = true;
+ }
SortedSet<Class<? extends LiquibaseDataType>> classes = registry.get(dataTypeName.toLowerCase());
@@ -141,6 +148,13 @@ public LiquibaseDataType fromDescription(String dataTypeDefinition) {
}
}
+ if (primaryKey && liquibaseDataType instanceof IntType) {
+ ((IntType) liquibaseDataType).setAutoIncrement(true);
+ }
+ if (primaryKey && liquibaseDataType instanceof BigIntType) {
+ ((BigIntType) liquibaseDataType).setAutoIncrement(true);
+ }
+
return liquibaseDataType;
}
@@ -31,7 +31,7 @@ public DatabaseDataType toDatabaseDataType(Database database) {
if (database instanceof OracleDatabase) {
return new DatabaseDataType("NUMBER", 38,0);
}
- if (database instanceof DB2Database || database instanceof DerbyDatabase) {
+ if (database instanceof DB2Database || database instanceof DerbyDatabase || database instanceof MSSQLDatabase) {
return new DatabaseDataType("BIGINT");
}
if (database instanceof PostgresDatabase) {
@@ -6,7 +6,7 @@
import liquibase.datatype.DatabaseDataType;
import liquibase.datatype.LiquibaseDataType;
-@DataTypeInfo(name="blob", aliases = {"longblob", "longvarbinary", "java.sql.Types.BLOB", "java.sql.Types.LONGBLOB", "java.sql.Types.LONGVARBINARY"}, minParameters = 0, maxParameters = 0, priority = LiquibaseDataType.PRIORITY_DEFAULT)
+@DataTypeInfo(name="blob", aliases = {"longblob", "longvarbinary", "java.sql.Types.BLOB", "java.sql.Types.LONGBLOB", "java.sql.Types.LONGVARBINARY", "varbinary"}, minParameters = 0, maxParameters = 0, priority = LiquibaseDataType.PRIORITY_DEFAULT)
public class BlobType extends LiquibaseDataType {
@Override
public DatabaseDataType toDatabaseDataType(Database database) {
@@ -6,8 +6,9 @@
import liquibase.datatype.DatabaseDataType;
import liquibase.datatype.LiquibaseDataType;
import liquibase.exception.UnexpectedLiquibaseException;
+import liquibase.statement.DatabaseFunction;
-@DataTypeInfo(name = "boolean", aliases = {"java.sql.Types.BOOLEAN", "java.lang.Boolean"}, minParameters = 0, maxParameters = 0, priority = LiquibaseDataType.PRIORITY_DEFAULT)
+@DataTypeInfo(name = "boolean", aliases = {"java.sql.Types.BOOLEAN", "java.lang.Boolean", "bit"}, minParameters = 0, maxParameters = 0, priority = LiquibaseDataType.PRIORITY_DEFAULT)
public class BooleanType extends LiquibaseDataType {
@Override
@@ -52,6 +53,8 @@ public String objectToSql(Object value, Database database) {
} else {
returnValue = this.getFalseBooleanValue(database);
}
+ } else if (value instanceof DatabaseFunction) {
+ return ((DatabaseFunction) value).toString();
} else if (((Boolean) value)) {
returnValue = this.getTrueBooleanValue(database);
} else {
@@ -10,7 +10,7 @@
import liquibase.statement.DatabaseFunction;
import liquibase.database.Database;
-@DataTypeInfo(name="date", aliases = {"java.sql.Types.DATE", "java.sql.Date"}, minParameters = 0, maxParameters = 0, priority = LiquibaseDataType.PRIORITY_DEFAULT)
+@DataTypeInfo(name="date", aliases = {"java.sql.Types.DATE", "java.sql.Date", "smalldatetime"}, minParameters = 0, maxParameters = 0, priority = LiquibaseDataType.PRIORITY_DEFAULT)
public class DateType extends LiquibaseDataType {
@Override
public DatabaseDataType toDatabaseDataType(Database database) {
@@ -36,6 +36,9 @@ public DatabaseDataType toDatabaseDataType(Database database) {
return new DatabaseDataType("SERIAL");
}
}
+ if (database instanceof MSSQLDatabase) {
+ return new DatabaseDataType("INT");
+ }
return super.toDatabaseDataType(database);
//sqllite
@@ -2,6 +2,7 @@
import liquibase.database.Database;
import liquibase.database.core.HsqlDatabase;
+import liquibase.database.core.MSSQLDatabase;
import liquibase.database.core.OracleDatabase;
import liquibase.datatype.DataTypeInfo;
import liquibase.datatype.DatabaseDataType;
@@ -18,6 +19,12 @@ public DatabaseDataType toDatabaseDataType(Database database) {
if (database instanceof OracleDatabase) {
return new DatabaseDataType("NVARCHAR2", getParameters());
}
+ if (database instanceof MSSQLDatabase) {
+ if (getParameters() != null && getParameters().length > 0 && getParameters()[0].equals("2147483647")) {
+ return new DatabaseDataType("NVARCHAR", "MAX");
+ }
+ return new DatabaseDataType("NVARCHAR", getParameters());
+ }
return super.toDatabaseDataType(database);
}
@@ -2,6 +2,7 @@
import liquibase.database.Database;
import liquibase.database.core.DerbyDatabase;
+import liquibase.database.core.MSSQLDatabase;
import liquibase.database.core.OracleDatabase;
import liquibase.database.core.PostgresDatabase;
import liquibase.datatype.DataTypeInfo;
@@ -27,6 +28,9 @@ public DatabaseDataType toDatabaseDataType(Database database) {
if (database instanceof DerbyDatabase || database instanceof PostgresDatabase) {
return new DatabaseDataType("SMALLINT");
}
+ if (database instanceof MSSQLDatabase) {
+ return new DatabaseDataType("TINYINT");
+ }
if (database instanceof OracleDatabase) {
return new DatabaseDataType("NUMBER",3);
}
@@ -7,7 +7,7 @@
import liquibase.datatype.LiquibaseDataType;
import liquibase.exception.DatabaseException;
-@DataTypeInfo(name="uuid", minParameters = 0, maxParameters = 0, priority = LiquibaseDataType.PRIORITY_DEFAULT)
+@DataTypeInfo(name="uuid", aliases = {"uniqueidentifier"}, minParameters = 0, maxParameters = 0, priority = LiquibaseDataType.PRIORITY_DEFAULT)
public class UUIDType extends LiquibaseDataType {
@Override
public DatabaseDataType toDatabaseDataType(Database database) {
@@ -1,6 +1,7 @@
package liquibase.snapshot.jvm;
import liquibase.database.Database;
+import liquibase.database.core.MSSQLDatabase;
import liquibase.database.jvm.JdbcConnection;
import liquibase.database.core.InformixDatabase;
import liquibase.database.core.OracleDatabase;
@@ -152,7 +153,7 @@ public Column getColumn(Schema schema, String tableName, String columnName, Data
Table table = new Table(database.correctObjectName(tableName, Table.class));
table.setSchema(schema);
- return readColumn(convertResultSetToMap(rs), table, database);
+ return readColumn(convertResultSetToMap(rs, database), table, database);
} catch (Exception e) {
throw new DatabaseException(e);
} finally {
@@ -184,7 +185,7 @@ protected Table readTable(ResultSet tableMetadataResultSet, Database database, b
ResultSet columnMetadataResultSet = getMetaData(database).getColumns(getJdbcCatalogName(rawSchema), getJdbcSchemaName(rawSchema), rawTableName, null);
try {
while (columnMetadataResultSet.next()) {
- table.getColumns().add(readColumn(convertResultSetToMap(columnMetadataResultSet), table, database));
+ table.getColumns().add(readColumn(convertResultSetToMap(columnMetadataResultSet, database), table, database));
}
} finally {
columnMetadataResultSet.close();
@@ -251,7 +252,9 @@ protected Column readColumn(Map<String, Object> columnMetadataResultSet, Relatio
if (table instanceof Table) {
if (columnMetadataResultSet.containsKey("IS_AUTOINCREMENT")) {
String isAutoincrement = (String) columnMetadataResultSet.get("IS_AUTOINCREMENT");
- if (isAutoincrement.equals("YES")) {
+ if (isAutoincrement == null) {
+ column.setAutoIncrement(false);
+ } else if (isAutoincrement.equals("YES")) {
column.setAutoIncrement(true);
} else if (isAutoincrement.equals("NO")) {
column.setAutoIncrement(false);
@@ -425,7 +428,7 @@ protected void readColumns(DatabaseSnapshot snapshot, Schema schema, DatabaseMet
try {
allColumnsMetadataRs = databaseMetaData.getColumns(getJdbcCatalogName(schema), getJdbcSchemaName(schema), null, null);
while (allColumnsMetadataRs.next()) {
- Map<String, Object> data = convertResultSetToMap(allColumnsMetadataRs);
+ Map<String, Object> data = convertResultSetToMap(allColumnsMetadataRs, database);
String tableOrViewName = cleanObjectNameFromDatabase((String) data.get("TABLE_NAME"));
Relation relation = snapshot.getDatabaseObject(schema, tableOrViewName, Table.class);
if (relation == null) {
@@ -460,7 +463,7 @@ protected void readColumns(DatabaseSnapshot snapshot, Schema schema, DatabaseMet
}
}
- private Map<String, Object> convertResultSetToMap(ResultSet rs) throws SQLException {
+ private Map<String, Object> convertResultSetToMap(ResultSet rs, Database database) throws SQLException {
Class[] types = new Class[]{ //matches tableMetadata.getColumns() types. Ugly, but otherwise get wrong types
null, //no zero index
String.class,
@@ -485,20 +488,51 @@ protected void readColumns(DatabaseSnapshot snapshot, Schema schema, DatabaseMet
String.class,
String.class,
short.class,
- String.class,
String.class
};
+// TABLE_CAT String => table catalog (may be null)
+// TABLE_SCHEM String => table schema (may be null)
+// TABLE_NAME String => table name
+// COLUMN_NAME String => column name
+// DATA_TYPE int => SQL type from java.sql.Types
+// TYPE_NAME String => Data source dependent type name, for a UDT the type name is fully qualified
+// COLUMN_SIZE int => column size.
+// BUFFER_LENGTH is not used.
+// DECIMAL_DIGITS int => the number of fractional digits. Null is returned for data types where DECIMAL_DIGITS is not applicable.
+// NUM_PREC_RADIX int => Radix (typically either 10 or 2)
+// NULLABLE int => is NULL allowed.
+// columnNoNulls - might not allow NULL values
+// columnNullable - definitely allows NULL values
+// columnNullableUnknown - nullability unknown
+// REMARKS String => comment describing column (may be null)
+// COLUMN_DEF String => default value for the column, which should be interpreted as a string when the value is enclosed in single quotes (may be null)
+// SQL_DATA_TYPE int => unused
+// SQL_DATETIME_SUB int => unused
+// CHAR_OCTET_LENGTH int => for char types the maximum number of bytes in the column
+// ORDINAL_POSITION int => index of column in table (starting at 1)
+// IS_NULLABLE String => ISO rules are used to determine the nullability for a column.
+// YES --- if the parameter can include NULLs
+// NO --- if the parameter cannot include NULLs
+// empty string --- if the nullability for the parameter is unknown
+// SCOPE_CATLOG String => catalog of table that is the scope of a reference attribute (null if DATA_TYPE isn't REF)
+// SCOPE_SCHEMA String => schema of table that is the scope of a reference attribute (null if the DATA_TYPE isn't REF)
+// SCOPE_TABLE String => table name that this the scope of a reference attribure (null if the DATA_TYPE isn't REF)
+// SOURCE_DATA_TYPE short => source type of a distinct type or user-generated Ref type, SQL type from java.sql.Types (null if DATA_TYPE isn't DISTINCT or user-generated REF)
+// IS_AUTOINCREMENT String => Indicates whether this column is auto incremented
+// YES --- if the column is auto incremented
+// NO --- if the column is not auto incremented
+// empty string --- if it cannot be determined whether the column is auto incremented parameter is unknown
Map<String, Object> data = new HashMap<String, Object>();
- for (int i=1; i<= rs.getMetaData().getColumnCount(); i++) {
+ for (int i=1; i< types.length; i++) {
Class classType = types[i];
Object value;
if (classType.equals(String.class)) {
value = rs.getString(i);
} else if (classType.equals(int.class)) {
value = rs.getInt(i);
} else if (classType.equals(short.class)) {
- value = rs.getShort(i);
+ value = null; //SOURCE_DATA_TYPE is not used and causes problems on sqlserver jdbc 3.0
} else {
value = rs.getObject(i);
}
@@ -2,9 +2,13 @@
import liquibase.database.Database;
import liquibase.database.core.MSSQLDatabase;
+import liquibase.database.structure.Column;
import liquibase.database.structure.ForeignKeyConstraintType;
import liquibase.exception.DatabaseException;
+import java.sql.SQLException;
+import java.util.Map;
+
public class MSSQLDatabaseSnapshotGenerator extends JdbcDatabaseSnapshotGenerator {
public boolean supports(Database database) {
return database instanceof MSSQLDatabase;
@@ -34,4 +38,17 @@ protected ForeignKeyConstraintType convertToForeignKeyConstraintType(int jdbcTyp
}
}
+ @Override
+ protected Object readDefaultValue(Map<String, Object> columnMetadataResultSet, Column columnInfo, Database database) throws SQLException, DatabaseException {
+ Object defaultValue = columnMetadataResultSet.get("COLUMN_DEF");
+
+ if (defaultValue != null && defaultValue instanceof String) {
+ String newValue = null;
+ if (defaultValue.equals("(NULL)")) {
+ newValue = null;
+ }
+ columnMetadataResultSet.put("COLUMN_DEF", newValue);
+ }
+ return super.readDefaultValue(columnMetadataResultSet, columnInfo, database);
+ }
}
@@ -43,7 +43,7 @@ public ValidationErrors validate(DropIndexStatement statement, Database database
if (database instanceof MySQLDatabase) {
return new Sql[] {new UnparsedSql("DROP INDEX " + database.escapeIndexName(null, null, statement.getIndexName()) + " ON " + database.escapeTableName(statement.getTableCatalogName(), schemaName, statement.getTableName())) };
} else if (database instanceof MSSQLDatabase) {
- return new Sql[] {new UnparsedSql("DROP INDEX " + database.escapeTableName(statement.getTableCatalogName(), schemaName, statement.getTableName()) + "." + database.escapeIndexName(null, null, statement.getIndexName())) };
+ return new Sql[] {new UnparsedSql("DROP INDEX " + database.escapeTableName(null, schemaName, statement.getTableName()) + "." + database.escapeIndexName(null, null, statement.getIndexName())) };
} else if (database instanceof PostgresDatabase) {
return new Sql[]{new UnparsedSql("DROP INDEX " + database.escapeIndexName(statement.getTableCatalogName(),schemaName, statement.getIndexName()))};
}
@@ -43,15 +43,15 @@ public void smartDataLoad() throws Exception {
}
}
- @Override
- //Mssql has problems with insert data in autoincrement tables. Because diff detects the id of that inserts and when it is ran the diff
- //it tries to insert values in identity columns that isn't allowed in mssql
- @Test(expected = MigrationFailedException.class)
- public void testRerunDiffChangeLog() throws Exception {
- if (getDatabase() == null) {
- throw new MigrationFailedException();
- }
- super.testRerunDiffChangeLog();
- }
+// @Override
+// //Mssql has problems with insert data in autoincrement tables. Because diff detects the id of that inserts and when it is ran the diff
+// //it tries to insert values in identity columns that isn't allowed in mssql
+// @Test(expected = MigrationFailedException.class)
+// public void testRerunDiffChangeLog() throws Exception {
+// if (getDatabase() == null) {
+// throw new MigrationFailedException();
+// }
+// super.testRerunDiffChangeLog();
+// }
}

0 comments on commit 1144d44

Please sign in to comment.