use of liquibase.exception.DatabaseException in project liquibase by liquibase.
the class DiffToChangeLog method sortObjects.
private List<DatabaseObject> sortObjects(final String type, Collection<DatabaseObject> objects, Database database) {
if (diffOutputControl.getSchemaComparisons() != null && objects.size() > 0 && supportsSortingObjects(database) && database.getConnection() != null && !(database.getConnection() instanceof OfflineConnection)) {
List<String> schemas = new ArrayList<String>();
CompareControl.SchemaComparison[] schemaComparisons = this.diffOutputControl.getSchemaComparisons();
if (schemaComparisons != null) {
for (CompareControl.SchemaComparison comparison : schemaComparisons) {
String schemaName = comparison.getReferenceSchema().getSchemaName();
if (schemaName == null) {
schemaName = database.getDefaultSchemaName();
}
schemas.add(schemaName);
}
}
if (schemas.size() == 0) {
schemas.add(database.getDefaultSchemaName());
}
try {
final List<String> dependencyOrder = new ArrayList<String>();
DependencyUtil.NodeValueListener<String> nameListener = new DependencyUtil.NodeValueListener<String>() {
@Override
public void evaluating(String nodeValue) {
dependencyOrder.add(nodeValue);
}
};
DependencyUtil.DependencyGraph graph = new DependencyUtil.DependencyGraph(nameListener);
addDependencies(graph, schemas, objects, database);
graph.computeDependencies();
if (dependencyOrder.size() > 0) {
final List<DatabaseObject> toSort = new ArrayList<DatabaseObject>();
final List<DatabaseObject> toNotSort = new ArrayList<DatabaseObject>();
for (DatabaseObject obj : objects) {
if (!(obj instanceof Column)) {
String schemaName = null;
if (obj.getSchema() != null) {
schemaName = obj.getSchema().getName();
}
String name = schemaName + "." + obj.getName();
if (dependencyOrder.contains(name)) {
toSort.add(obj);
} else {
toNotSort.add(obj);
}
} else {
toNotSort.add(obj);
}
}
Collections.sort(toSort, new Comparator<DatabaseObject>() {
@Override
public int compare(DatabaseObject o1, DatabaseObject o2) {
String o1Schema = null;
if (o1.getSchema() != null) {
o1Schema = o1.getSchema().getName();
}
String o2Schema = null;
if (o2.getSchema() != null) {
o2Schema = o2.getSchema().getName();
}
Integer o1Order = dependencyOrder.indexOf(o1Schema + "." + o1.getName());
int o2Order = dependencyOrder.indexOf(o2Schema + "." + o2.getName());
int order = o1Order.compareTo(o2Order);
if (type.equals("unexpected")) {
order = order * -1;
}
return order;
}
});
toSort.addAll(toNotSort);
return toSort;
}
} catch (DatabaseException e) {
LogFactory.getInstance().getLog().debug("Cannot get object dependencies: " + e.getMessage());
}
}
return new ArrayList<DatabaseObject>(objects);
}
use of liquibase.exception.DatabaseException in project liquibase by liquibase.
the class DateTimeType method toDatabaseDataType.
@Override
public DatabaseDataType toDatabaseDataType(Database database) {
String originalDefinition = StringUtils.trimToEmpty(getRawDefinition());
boolean allowFractional = supportsFractionalDigits(database);
if (database instanceof DerbyDatabase || database instanceof FirebirdDatabase || database instanceof H2Database || database instanceof HsqlDatabase) {
return new DatabaseDataType("TIMESTAMP");
}
if (database instanceof DB2Database || database instanceof OracleDatabase) {
return new DatabaseDataType("TIMESTAMP", getParameters());
}
if (database instanceof MSSQLDatabase) {
Object[] parameters = getParameters();
if (originalDefinition.toLowerCase().startsWith("smalldatetime") || originalDefinition.toLowerCase().startsWith("[smalldatetime")) {
return new DatabaseDataType(database.escapeDataTypeName("smalldatetime"));
} else if (originalDefinition.equalsIgnoreCase("datetime2") || originalDefinition.equals("[datetime2]") || originalDefinition.matches("(?i)datetime2\\s*\\(.+") || originalDefinition.matches("\\[datetime2\\]\\s*\\(.+")) {
try {
if (database.getDatabaseMajorVersion() <= 9) {
//2005 or earlier
return new DatabaseDataType(database.escapeDataTypeName("datetime"));
}
}//assuming it is a newer version
catch (DatabaseException ignore) {
}
if (parameters.length == 0) {
parameters = new Object[] { 7 };
} else if (parameters.length > 1) {
parameters = new Object[] { parameters[1] };
}
return new DatabaseDataType(database.escapeDataTypeName("datetime2"), parameters);
}
return new DatabaseDataType(database.escapeDataTypeName("datetime"));
}
if (database instanceof InformixDatabase) {
// From database to changelog
if (getAdditionalInformation() == null || getAdditionalInformation().length() == 0) {
if (getParameters() != null && getParameters().length > 0) {
String parameter = String.valueOf(getParameters()[0]);
if ("4365".equals(parameter)) {
return new DatabaseDataType("DATETIME YEAR TO FRACTION(3)");
}
if ("3594".equals(parameter)) {
return new DatabaseDataType("DATETIME YEAR TO SECOND");
}
if ("3080".equals(parameter)) {
return new DatabaseDataType("DATETIME YEAR TO MINUTE");
}
if ("2052".equals(parameter)) {
return new DatabaseDataType("DATETIME YEAR TO DAY");
}
}
}
// From changelog to the database
if (getAdditionalInformation() != null && getAdditionalInformation().length() > 0) {
return new DatabaseDataType(originalDefinition);
}
return new DatabaseDataType("DATETIME YEAR TO FRACTION", 5);
}
if (database instanceof PostgresDatabase) {
String rawDefinition = originalDefinition.toLowerCase();
Object[] params = getParameters();
if (rawDefinition.contains("tz") || rawDefinition.contains("with time zone")) {
if (params.length == 0 || !allowFractional) {
return new DatabaseDataType("TIMESTAMP WITH TIME ZONE");
} else {
Object param = params[0];
if (params.length == 2) {
param = params[1];
}
return new DatabaseDataType("TIMESTAMP(" + param + ") WITH TIME ZONE");
}
} else {
if (params.length == 0 || !allowFractional) {
return new DatabaseDataType("TIMESTAMP WITHOUT TIME ZONE");
} else {
Object param = params[0];
if (params.length == 2) {
param = params[1];
}
return new DatabaseDataType("TIMESTAMP(" + param + ") WITHOUT TIME ZONE");
}
}
}
if (database instanceof SQLiteDatabase) {
return new DatabaseDataType("TEXT");
}
if (database instanceof MySQLDatabase) {
if (getParameters().length == 0 || !allowFractional) {
// fast out...
return new DatabaseDataType(getName());
}
Object[] params = getParameters();
Integer precision = Integer.valueOf(params[0].toString());
if (precision > 6) {
LogFactory.getInstance().getLog().warning("MySQL does not support a timestamp precision" + " of '" + precision + "' - resetting to" + " the maximum of '6'");
params = new Object[] { 6 };
}
return new DatabaseDataType(getName(), params);
}
return new DatabaseDataType(getName());
}
use of liquibase.exception.DatabaseException in project liquibase by liquibase.
the class SnapshotGeneratorFactory method has.
public boolean has(DatabaseObject example, Database database) throws DatabaseException, InvalidExampleException {
List<Class<? extends DatabaseObject>> types = new ArrayList<Class<? extends DatabaseObject>>(getContainerTypes(example.getClass(), database));
types.add(example.getClass());
//workaround for common check for databasechangelog/lock table to not snapshot the whole database like we have to in order to handle case issues
if (example instanceof Table && (example.getName().equals(database.getDatabaseChangeLogTableName()) || example.getName().equals(database.getDatabaseChangeLogLockTableName()))) {
try {
ExecutorService.getInstance().getExecutor(database).queryForInt(new RawSqlStatement("select count(*) from " + database.escapeObjectName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), example.getName(), Table.class)));
return true;
} catch (DatabaseException e) {
if (database instanceof PostgresDatabase) {
//throws "current transaction is aborted" unless we roll back the connection
database.rollback();
}
return false;
}
}
if (createSnapshot(example, database, new SnapshotControl(database, false, types.toArray(new Class[types.size()]))) != null) {
return true;
}
CatalogAndSchema catalogAndSchema;
if (example.getSchema() == null) {
catalogAndSchema = database.getDefaultSchema();
} else {
catalogAndSchema = example.getSchema().toCatalogAndSchema();
}
DatabaseSnapshot snapshot = createSnapshot(catalogAndSchema, database, new SnapshotControl(database, false, example.getClass()));
for (DatabaseObject obj : snapshot.get(example.getClass())) {
if (DatabaseObjectComparatorFactory.getInstance().isSameObject(example, obj, null, database)) {
return true;
}
}
return false;
}
use of liquibase.exception.DatabaseException in project liquibase by liquibase.
the class ColumnSnapshotGenerator method addTo.
@Override
protected void addTo(DatabaseObject foundObject, DatabaseSnapshot snapshot) throws DatabaseException, InvalidExampleException {
if (!snapshot.getSnapshotControl().shouldInclude(Column.class)) {
return;
}
if (foundObject instanceof Relation) {
Database database = snapshot.getDatabase();
Relation relation = (Relation) foundObject;
List<CachedRow> allColumnsMetadataRs = null;
try {
JdbcDatabaseSnapshot.CachingDatabaseMetaData databaseMetaData = ((JdbcDatabaseSnapshot) snapshot).getMetaData();
Schema schema;
schema = relation.getSchema();
allColumnsMetadataRs = databaseMetaData.getColumns(((AbstractJdbcDatabase) database).getJdbcCatalogName(schema), ((AbstractJdbcDatabase) database).getJdbcSchemaName(schema), relation.getName(), null);
for (CachedRow row : allColumnsMetadataRs) {
Column column = readColumn(row, relation, database);
setAutoIncrementDetails(column, database, snapshot);
column.setAttribute(LIQUIBASE_COMPLETE, true);
relation.getColumns().add(column);
}
} catch (Exception e) {
throw new DatabaseException(e);
}
}
}
use of liquibase.exception.DatabaseException in project liquibase by liquibase.
the class ColumnSnapshotGenerator method readDataType.
protected DataType readDataType(CachedRow columnMetadataResultSet, Column column, Database database) throws SQLException {
if (database instanceof OracleDatabase) {
String dataType = columnMetadataResultSet.getString("DATA_TYPE_NAME");
dataType = dataType.replace("VARCHAR2", "VARCHAR");
dataType = dataType.replace("NVARCHAR2", "NVARCHAR");
DataType type = new DataType(dataType);
type.setDataTypeId(columnMetadataResultSet.getInt("DATA_TYPE"));
if (dataType.equalsIgnoreCase("NUMBER")) {
type.setColumnSize(columnMetadataResultSet.getInt("DATA_PRECISION"));
// if (type.getColumnSize() == null) {
// type.setColumnSize(38);
// }
type.setDecimalDigits(columnMetadataResultSet.getInt("DATA_SCALE"));
// if (type.getDecimalDigits() == null) {
// type.setDecimalDigits(0);
// }
// type.setRadix(10);
} else {
type.setColumnSize(columnMetadataResultSet.getInt("DATA_LENGTH"));
if (dataType.equalsIgnoreCase("NCLOB") || dataType.equalsIgnoreCase("BLOB") || dataType.equalsIgnoreCase("CLOB")) {
type.setColumnSize(null);
} else if (dataType.equalsIgnoreCase("NVARCHAR") || dataType.equalsIgnoreCase("NCHAR")) {
type.setColumnSize(columnMetadataResultSet.getInt("CHAR_LENGTH"));
type.setColumnSizeUnit(DataType.ColumnSizeUnit.CHAR);
} else {
String charUsed = columnMetadataResultSet.getString("CHAR_USED");
DataType.ColumnSizeUnit unit = null;
if ("C".equals(charUsed)) {
unit = DataType.ColumnSizeUnit.CHAR;
type.setColumnSize(columnMetadataResultSet.getInt("CHAR_LENGTH"));
} else if ("B".equals(charUsed)) {
unit = DataType.ColumnSizeUnit.BYTE;
}
type.setColumnSizeUnit(unit);
}
}
return type;
}
String columnTypeName = (String) columnMetadataResultSet.get("TYPE_NAME");
if (database instanceof MSSQLDatabase) {
if (columnTypeName.equalsIgnoreCase("numeric() identity")) {
columnTypeName = "numeric";
} else if (columnTypeName.equalsIgnoreCase("decimal() identity")) {
columnTypeName = "decimal";
} else if (columnTypeName.equalsIgnoreCase("xml")) {
columnMetadataResultSet.set("COLUMN_SIZE", null);
columnMetadataResultSet.set("DECIMAL_DIGITS", null);
} else if (columnTypeName.equalsIgnoreCase("datetimeoffset")) {
columnMetadataResultSet.set("COLUMN_SIZE", columnMetadataResultSet.getInt("DECIMAL_DIGITS"));
columnMetadataResultSet.set("DECIMAL_DIGITS", null);
} else if (columnTypeName.equalsIgnoreCase("time")) {
columnMetadataResultSet.set("COLUMN_SIZE", columnMetadataResultSet.getInt("DECIMAL_DIGITS"));
columnMetadataResultSet.set("DECIMAL_DIGITS", null);
}
}
if (database instanceof FirebirdDatabase) {
if (columnTypeName.equals("BLOB SUB_TYPE 0")) {
columnTypeName = "BLOB";
}
if (columnTypeName.equals("BLOB SUB_TYPE 1")) {
columnTypeName = "CLOB";
}
}
if (database instanceof MySQLDatabase && (columnTypeName.equalsIgnoreCase("ENUM") || columnTypeName.equalsIgnoreCase("SET"))) {
try {
String boilerLength;
if (columnTypeName.equalsIgnoreCase("ENUM"))
boilerLength = "7";
else
// SET
boilerLength = "6";
List<String> enumValues = ExecutorService.getInstance().getExecutor(database).queryForList(new RawSqlStatement("SELECT DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING(COLUMN_TYPE, " + boilerLength + ", LENGTH(COLUMN_TYPE) - " + boilerLength + " - 1 ), \"','\", 1 + units.i + tens.i * 10) , \"','\", -1)\n" + "FROM INFORMATION_SCHEMA.COLUMNS\n" + "CROSS JOIN (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) units\n" + "CROSS JOIN (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) tens\n" + "WHERE TABLE_NAME = '" + column.getRelation().getName() + "' \n" + "AND COLUMN_NAME = '" + column.getName() + "'"), String.class);
String enumClause = "";
for (String enumValue : enumValues) {
enumClause += "'" + enumValue + "', ";
}
enumClause = enumClause.replaceFirst(", $", "");
return new DataType(columnTypeName + "(" + enumClause + ")");
} catch (DatabaseException e) {
LogFactory.getLogger().warning("Error fetching enum values", e);
}
}
DataType.ColumnSizeUnit columnSizeUnit = DataType.ColumnSizeUnit.BYTE;
int dataType = columnMetadataResultSet.getInt("DATA_TYPE");
Integer columnSize = null;
Integer decimalDigits = null;
if (!database.dataTypeIsNotModifiable(columnTypeName)) {
// don't set size for types like int4, int8 etc
columnSize = columnMetadataResultSet.getInt("COLUMN_SIZE");
decimalDigits = columnMetadataResultSet.getInt("DECIMAL_DIGITS");
if (decimalDigits != null && decimalDigits.equals(0)) {
decimalDigits = null;
}
}
Integer radix = columnMetadataResultSet.getInt("NUM_PREC_RADIX");
Integer characterOctetLength = columnMetadataResultSet.getInt("CHAR_OCTET_LENGTH");
if (database instanceof DB2Database) {
String typeName = columnMetadataResultSet.getString("TYPE_NAME");
if (typeName.equalsIgnoreCase("DBCLOB") || typeName.equalsIgnoreCase("GRAPHIC") || typeName.equalsIgnoreCase("VARGRAPHIC")) {
if (columnSize != null) {
//Stored as double length chars
columnSize = columnSize / 2;
}
}
if (columnTypeName.equalsIgnoreCase("TIMESTAMP") && decimalDigits == null) {
//actually a date
columnTypeName = "DATE";
dataType = Types.DATE;
}
}
if (database instanceof PostgresDatabase && columnSize != null && columnSize.equals(Integer.MAX_VALUE)) {
columnSize = null;
}
DataType type = new DataType(columnTypeName);
type.setDataTypeId(dataType);
type.setColumnSize(columnSize);
type.setDecimalDigits(decimalDigits);
type.setRadix(radix);
type.setCharacterOctetLength(characterOctetLength);
type.setColumnSizeUnit(columnSizeUnit);
return type;
}
Aggregations