Search in sources :

Example 11 with DatabaseException

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);
}
Also used : OfflineConnection(liquibase.database.OfflineConnection) DependencyUtil(liquibase.util.DependencyUtil) Column(liquibase.structure.core.Column) CompareControl(liquibase.diff.compare.CompareControl) DatabaseObject(liquibase.structure.DatabaseObject) DatabaseException(liquibase.exception.DatabaseException)

Example 12 with DatabaseException

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());
}
Also used : DatabaseDataType(liquibase.datatype.DatabaseDataType) DatabaseException(liquibase.exception.DatabaseException)

Example 13 with DatabaseException

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;
}
Also used : RawSqlStatement(liquibase.statement.core.RawSqlStatement) PostgresDatabase(liquibase.database.core.PostgresDatabase) Table(liquibase.structure.core.Table) DatabaseObject(liquibase.structure.DatabaseObject) CatalogAndSchema(liquibase.CatalogAndSchema) DatabaseException(liquibase.exception.DatabaseException)

Example 14 with DatabaseException

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);
        }
    }
}
Also used : Database(liquibase.database.Database) AbstractJdbcDatabase(liquibase.database.AbstractJdbcDatabase) AbstractJdbcDatabase(liquibase.database.AbstractJdbcDatabase) DatabaseException(liquibase.exception.DatabaseException) DatabaseException(liquibase.exception.DatabaseException) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException)

Example 15 with DatabaseException

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;
}
Also used : RawSqlStatement(liquibase.statement.core.RawSqlStatement) DatabaseException(liquibase.exception.DatabaseException)

Aggregations

DatabaseException (liquibase.exception.DatabaseException)73 SQLException (java.sql.SQLException)25 Database (liquibase.database.Database)24 UnexpectedLiquibaseException (liquibase.exception.UnexpectedLiquibaseException)16 AbstractJdbcDatabase (liquibase.database.AbstractJdbcDatabase)14 CatalogAndSchema (liquibase.CatalogAndSchema)13 LiquibaseException (liquibase.exception.LiquibaseException)13 MSSQLDatabase (liquibase.database.core.MSSQLDatabase)12 JdbcConnection (liquibase.database.jvm.JdbcConnection)12 CachedRow (liquibase.snapshot.CachedRow)10 InvalidExampleException (liquibase.snapshot.InvalidExampleException)10 JdbcDatabaseSnapshot (liquibase.snapshot.JdbcDatabaseSnapshot)10 Executor (liquibase.executor.Executor)9 DatabaseConnection (liquibase.database.DatabaseConnection)7 OfflineConnection (liquibase.database.OfflineConnection)7 Connection (java.sql.Connection)6 Statement (java.sql.Statement)6 SQLiteDatabase (liquibase.database.core.SQLiteDatabase)6 RawSqlStatement (liquibase.statement.core.RawSqlStatement)6 IOException (java.io.IOException)5