Search in sources :

Example 1 with DataType

use of liquibase.structure.core.DataType in project liquibase by liquibase.

the class DefaultDatabaseObjectComparator method findDifferences.

@Override
public ObjectDifferences findDifferences(DatabaseObject databaseObject1, DatabaseObject databaseObject2, Database accordingTo, CompareControl compareControl, DatabaseObjectComparatorChain chain, Set<String> exclude) {
    Set<String> attributes = new HashSet<String>();
    attributes.addAll(databaseObject1.getAttributes());
    attributes.addAll(databaseObject2.getAttributes());
    ObjectDifferences differences = new ObjectDifferences(compareControl);
    exclude.add("schema");
    exclude.add("catalog");
    for (String attribute : attributes) {
        if (exclude.contains(attribute)) {
            continue;
        }
        Object attribute1 = databaseObject1.getAttribute(attribute, Object.class);
        Object attribute2 = databaseObject2.getAttribute(attribute, Object.class);
        attribute1 = undoCollection(attribute1, attribute2);
        attribute2 = undoCollection(attribute2, attribute1);
        ObjectDifferences.CompareFunction compareFunction;
        if (attribute1 instanceof DatabaseObject || attribute2 instanceof DatabaseObject) {
            Class<? extends DatabaseObject> type;
            if (attribute1 != null) {
                type = (Class<? extends DatabaseObject>) attribute1.getClass();
            } else {
                type = (Class<? extends DatabaseObject>) attribute2.getClass();
            }
            compareFunction = new ObjectDifferences.DatabaseObjectNameCompareFunction(type, accordingTo);
        } else if (attribute1 instanceof DataType || attribute2 instanceof DataType) {
            compareFunction = new ObjectDifferences.ToStringCompareFunction(false);
        } else if (attribute1 instanceof Column.AutoIncrementInformation || attribute2 instanceof Column.AutoIncrementInformation) {
            compareFunction = new ObjectDifferences.ToStringCompareFunction(false);
        } else if (attribute1 instanceof Collection || attribute2 instanceof Collection) {
            compareFunction = new ObjectDifferences.OrderedCollectionCompareFunction(new ObjectDifferences.StandardCompareFunction(chain.getSchemaComparisons(), accordingTo));
        } else {
            compareFunction = new ObjectDifferences.StandardCompareFunction(chain.getSchemaComparisons(), accordingTo);
        }
        differences.compare(attribute, databaseObject1, databaseObject2, compareFunction);
    }
    return differences;
}
Also used : ObjectDifferences(liquibase.diff.ObjectDifferences) Column(liquibase.structure.core.Column) DatabaseObject(liquibase.structure.DatabaseObject) DataType(liquibase.structure.core.DataType) Collection(java.util.Collection) DatabaseObject(liquibase.structure.DatabaseObject) HashSet(java.util.HashSet)

Example 2 with DataType

use of liquibase.structure.core.DataType in project liquibase by liquibase.

the class StandardChangeLogHistoryService method init.

public void init() throws DatabaseException {
    if (serviceInitialized) {
        return;
    }
    Database database = getDatabase();
    Executor executor = ExecutorService.getInstance().getExecutor(database);
    Table changeLogTable = null;
    try {
        changeLogTable = SnapshotGeneratorFactory.getInstance().getDatabaseChangeLogTable(new SnapshotControl(database, false, Table.class, Column.class), database);
    } catch (LiquibaseException e) {
        throw new UnexpectedLiquibaseException(e);
    }
    List<SqlStatement> statementsToExecute = new ArrayList<SqlStatement>();
    boolean changeLogCreateAttempted = false;
    if (changeLogTable != null) {
        boolean hasDescription = changeLogTable.getColumn("DESCRIPTION") != null;
        boolean hasComments = changeLogTable.getColumn("COMMENTS") != null;
        boolean hasTag = changeLogTable.getColumn("TAG") != null;
        boolean hasLiquibase = changeLogTable.getColumn("LIQUIBASE") != null;
        boolean hasContexts = changeLogTable.getColumn("CONTEXTS") != null;
        boolean hasLabels = changeLogTable.getColumn("LABELS") != null;
        boolean liquibaseColumnNotRightSize = false;
        if (!(this.getDatabase() instanceof SQLiteDatabase)) {
            DataType type = changeLogTable.getColumn("LIQUIBASE").getType();
            if (type.getTypeName().toLowerCase().startsWith("varchar")) {
                Integer columnSize = type.getColumnSize();
                liquibaseColumnNotRightSize = columnSize != null && columnSize < 20;
            } else {
                liquibaseColumnNotRightSize = false;
            }
        }
        boolean hasOrderExecuted = changeLogTable.getColumn("ORDEREXECUTED") != null;
        boolean checksumNotRightSize = false;
        if (!(this.getDatabase() instanceof SQLiteDatabase)) {
            DataType type = changeLogTable.getColumn("MD5SUM").getType();
            if (type.getTypeName().toLowerCase().startsWith("varchar")) {
                Integer columnSize = type.getColumnSize();
                checksumNotRightSize = columnSize != null && columnSize < 35;
            } else {
                liquibaseColumnNotRightSize = false;
            }
        }
        boolean hasExecTypeColumn = changeLogTable.getColumn("EXECTYPE") != null;
        String charTypeName = getCharTypeName();
        boolean hasDeploymentIdColumn = changeLogTable.getColumn("DEPLOYMENT_ID") != null;
        if (!hasDescription) {
            executor.comment("Adding missing databasechangelog.description column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "DESCRIPTION", charTypeName + "(255)", null));
        }
        if (!hasTag) {
            executor.comment("Adding missing databasechangelog.tag column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "TAG", charTypeName + "(255)", null));
        }
        if (!hasComments) {
            executor.comment("Adding missing databasechangelog.comments column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "COMMENTS", charTypeName + "(255)", null));
        }
        if (!hasLiquibase) {
            executor.comment("Adding missing databasechangelog.liquibase column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "LIQUIBASE", charTypeName + "(20)", null));
        }
        if (!hasOrderExecuted) {
            executor.comment("Adding missing databasechangelog.orderexecuted column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "ORDEREXECUTED", "int", null));
            statementsToExecute.add(new UpdateStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()).addNewColumnValue("ORDEREXECUTED", -1));
            statementsToExecute.add(new SetNullableStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "ORDEREXECUTED", "int", false));
        }
        if (checksumNotRightSize) {
            executor.comment("Modifying size of databasechangelog.md5sum column");
            statementsToExecute.add(new ModifyDataTypeStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "MD5SUM", charTypeName + "(35)"));
        }
        if (liquibaseColumnNotRightSize) {
            executor.comment("Modifying size of databasechangelog.liquibase column");
            statementsToExecute.add(new ModifyDataTypeStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "LIQUIBASE", charTypeName + "(20)"));
        }
        if (!hasExecTypeColumn) {
            executor.comment("Adding missing databasechangelog.exectype column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "EXECTYPE", charTypeName + "(10)", null));
            statementsToExecute.add(new UpdateStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()).addNewColumnValue("EXECTYPE", "EXECUTED"));
            statementsToExecute.add(new SetNullableStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "EXECTYPE", charTypeName + "(10)", false));
        }
        if (hasContexts) {
            Integer columnSize = changeLogTable.getColumn("CONTEXTS").getType().getColumnSize();
            if (columnSize != null && columnSize < Integer.parseInt(getContextsSize())) {
                executor.comment("Modifying size of databasechangelog.contexts column");
                statementsToExecute.add(new ModifyDataTypeStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "CONTEXTS", charTypeName + "(" + getContextsSize() + ")"));
            }
        } else {
            executor.comment("Adding missing databasechangelog.contexts column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "CONTEXTS", charTypeName + "(" + getContextsSize() + ")", null));
        }
        if (hasLabels) {
            Integer columnSize = changeLogTable.getColumn("LABELS").getType().getColumnSize();
            if (columnSize != null && columnSize < Integer.parseInt(getLabelsSize())) {
                executor.comment("Modifying size of databasechangelog.labels column");
                statementsToExecute.add(new ModifyDataTypeStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "LABELS", charTypeName + "(" + getLabelsSize() + ")"));
            }
        } else {
            executor.comment("Adding missing databasechangelog.labels column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "LABELS", charTypeName + "(" + getLabelsSize() + ")", null));
        }
        if (!hasDeploymentIdColumn) {
            executor.comment("Adding missing databasechangelog.deployment_id column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "DEPLOYMENT_ID", "VARCHAR(10)", null));
            if (database instanceof DB2Database) {
                statementsToExecute.add(new ReorganizeTableStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()));
            }
        }
        List<Map<String, ?>> md5sumRS = ExecutorService.getInstance().getExecutor(database).queryForList(new SelectFromDatabaseChangeLogStatement(new SelectFromDatabaseChangeLogStatement.ByNotNullCheckSum(), new ColumnConfig().setName("MD5SUM")).setLimit(1));
        if (md5sumRS.size() > 0) {
            String md5sum = md5sumRS.get(0).get("MD5SUM").toString();
            if (!md5sum.startsWith(CheckSum.getCurrentVersion() + ":")) {
                executor.comment("DatabaseChangeLog checksums are an incompatible version.  Setting them to null so they will be updated on next database update");
                databaseChecksumsCompatible = false;
                statementsToExecute.add(new RawSqlStatement("UPDATE " + getDatabase().escapeTableName(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()) + " " + "SET " + getDatabase().escapeObjectName("MD5SUM", Column.class) + " = NULL"));
            }
        }
    } else if (!changeLogCreateAttempted) {
        executor.comment("Create Database Change Log Table");
        SqlStatement createTableStatement = new CreateDatabaseChangeLogTableStatement();
        if (!canCreateChangeLogTable()) {
            throw new DatabaseException("Cannot create " + getDatabase().escapeTableName(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()) + " table for your getDatabase().\n\n" + "Please construct it manually using the following SQL as a base and re-run Liquibase:\n\n" + createTableStatement);
        }
        // If there is no table in the database for recording change history create one.
        statementsToExecute.add(createTableStatement);
        LogFactory.getLogger().info("Creating database history table with name: " + getDatabase().escapeTableName(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()));
    }
    for (SqlStatement sql : statementsToExecute) {
        if (SqlGeneratorFactory.getInstance().supports(sql, database)) {
            executor.execute(sql);
            getDatabase().commit();
        } else {
            LogFactory.getLogger().info("Cannot run " + sql.getClass().getSimpleName() + " on " + getDatabase().getShortName() + " when checking databasechangelog table");
        }
    }
    serviceInitialized = true;
}
Also used : DB2Database(liquibase.database.core.DB2Database) ColumnConfig(liquibase.change.ColumnConfig) SqlStatement(liquibase.statement.SqlStatement) Executor(liquibase.executor.Executor) SQLiteDatabase(liquibase.database.core.SQLiteDatabase) DB2Database(liquibase.database.core.DB2Database) MSSQLDatabase(liquibase.database.core.MSSQLDatabase) Database(liquibase.database.Database) DataType(liquibase.structure.core.DataType) SnapshotControl(liquibase.snapshot.SnapshotControl) Table(liquibase.structure.core.Table) SQLiteDatabase(liquibase.database.core.SQLiteDatabase) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException) LiquibaseException(liquibase.exception.LiquibaseException) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException) DatabaseException(liquibase.exception.DatabaseException)

Example 3 with DataType

use of liquibase.structure.core.DataType in project liquibase by liquibase.

the class YamlSerializer method toMap.

protected Object toMap(LiquibaseSerializable object) {
    Comparator<String> comparator;
    comparator = getComparator(object);
    Map<String, Object> objectMap = new TreeMap<String, Object>(comparator);
    for (String field : object.getSerializableFields()) {
        Object value = object.getSerializableFieldValue(field);
        if (value != null) {
            if (value instanceof DataType) {
                value = ((Map) toMap((DataType) value)).values().iterator().next();
            }
            if (value instanceof Column.AutoIncrementInformation) {
                value = ((Map) toMap((Column.AutoIncrementInformation) value)).values().iterator().next();
            }
            if (value instanceof ConstraintsConfig) {
                value = ((Map) toMap((ConstraintsConfig) value)).values().iterator().next();
            }
            if (value instanceof LiquibaseSerializable) {
                value = toMap((LiquibaseSerializable) value);
            }
            if (value instanceof Collection) {
                List valueAsList = new ArrayList((Collection) value);
                if (valueAsList.size() == 0) {
                    continue;
                }
                for (int i = 0; i < valueAsList.size(); i++) {
                    if (valueAsList.get(i) instanceof LiquibaseSerializable) {
                        valueAsList.set(i, toMap((LiquibaseSerializable) valueAsList.get(i)));
                    }
                }
                value = valueAsList;
            }
            if (value instanceof Map) {
                if (((Map) value).size() == 0) {
                    continue;
                }
                for (Object key : ((Map) value).keySet()) {
                    Object mapValue = ((Map) value).get(key);
                    if (mapValue instanceof LiquibaseSerializable) {
                        ((Map) value).put(key, toMap((LiquibaseSerializable) mapValue));
                    } else if (mapValue instanceof Collection) {
                        List valueAsList = new ArrayList((Collection) mapValue);
                        if (valueAsList.size() == 0) {
                            continue;
                        }
                        for (int i = 0; i < valueAsList.size(); i++) {
                            if (valueAsList.get(i) instanceof LiquibaseSerializable) {
                                valueAsList.set(i, toMap((LiquibaseSerializable) valueAsList.get(i)));
                            }
                        }
                        ((Map) value).put(key, valueAsList);
                    }
                }
            }
            objectMap.put(field, value);
        }
    }
    Map<String, Object> containerMap = new HashMap<String, Object>();
    containerMap.put(object.getSerializedObjectName(), objectMap);
    return containerMap;
}
Also used : ColumnConstraint(liquibase.statement.ColumnConstraint) Column(liquibase.structure.core.Column) ConstraintsConfig(liquibase.change.ConstraintsConfig) DataType(liquibase.structure.core.DataType) LiquibaseSerializable(liquibase.serializer.LiquibaseSerializable)

Aggregations

DataType (liquibase.structure.core.DataType)3 Column (liquibase.structure.core.Column)2 Collection (java.util.Collection)1 HashSet (java.util.HashSet)1 ColumnConfig (liquibase.change.ColumnConfig)1 ConstraintsConfig (liquibase.change.ConstraintsConfig)1 Database (liquibase.database.Database)1 DB2Database (liquibase.database.core.DB2Database)1 MSSQLDatabase (liquibase.database.core.MSSQLDatabase)1 SQLiteDatabase (liquibase.database.core.SQLiteDatabase)1 ObjectDifferences (liquibase.diff.ObjectDifferences)1 DatabaseException (liquibase.exception.DatabaseException)1 LiquibaseException (liquibase.exception.LiquibaseException)1 UnexpectedLiquibaseException (liquibase.exception.UnexpectedLiquibaseException)1 Executor (liquibase.executor.Executor)1 LiquibaseSerializable (liquibase.serializer.LiquibaseSerializable)1 SnapshotControl (liquibase.snapshot.SnapshotControl)1 ColumnConstraint (liquibase.statement.ColumnConstraint)1 SqlStatement (liquibase.statement.SqlStatement)1 DatabaseObject (liquibase.structure.DatabaseObject)1