Search in sources :

Example 31 with DatabaseObject

use of liquibase.structure.DatabaseObject in project liquibase by liquibase.

the class DatabaseSnapshot method include.

/**
 * Include the object described by the passed example object in this snapshot. Returns the object snapshot or null
 * if the object does not exist in the database. If the same object was returned by an earlier include() call,
 * the same object instance will be returned.
 */
protected <T extends DatabaseObject> T include(T example) throws DatabaseException, InvalidExampleException {
    if (example == null) {
        return null;
    }
    if (database.isSystemObject(example)) {
        return null;
    }
    if ((example instanceof Schema) && (example.getName() == null) && ((((Schema) example).getCatalog() == null) || (((Schema) example).getCatalogName() == null))) {
        CatalogAndSchema catalogAndSchema = ((Schema) example).toCatalogAndSchema().customize(database);
        example = (T) new Schema(catalogAndSchema.getCatalogName(), catalogAndSchema.getSchemaName());
    }
    if (!snapshotControl.shouldInclude(example)) {
        LOGGER.fine("Excluding " + example);
        return example;
    }
    T existing = get(example);
    if (existing != null) {
        return existing;
    }
    if (isKnownNull(example)) {
        return null;
    }
    SnapshotListener snapshotListener = snapshotControl.getSnapshotListener();
    SnapshotGeneratorChain chain = createGeneratorChain(example.getClass(), database);
    if (snapshotListener != null) {
        snapshotListener.willSnapshot(example, database);
    }
    T object = chain.snapshot(example, this);
    if (object == null) {
        Set<DatabaseObject> collection = knownNull.get(example.getClass());
        if (collection == null) {
            collection = new HashSet<>();
            knownNull.put(example.getClass(), collection);
        }
        collection.add(example);
        if (example instanceof Schema) {
            if (snapshotControl.isWarnIfObjectNotFound())
                Scope.getCurrentScope().getLog(getClass()).warning("Did not find schema '" + example + "' to snapshot");
        }
        if (example instanceof Catalog) {
            if (snapshotControl.isWarnIfObjectNotFound())
                Scope.getCurrentScope().getLog(getClass()).warning("Did not find catalog '" + example + "' to snapshot");
        }
    } else {
        allFound.add(object);
        try {
            includeNestedObjects(object);
        } catch (ReflectiveOperationException e) {
            throw new UnexpectedLiquibaseException(e);
        }
    }
    if (snapshotListener != null) {
        snapshotListener.finishedSnapshot(example, object, database);
    }
    return object;
}
Also used : CatalogAndSchema(liquibase.CatalogAndSchema) DatabaseObject(liquibase.structure.DatabaseObject) CatalogAndSchema(liquibase.CatalogAndSchema) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException)

Example 32 with DatabaseObject

use of liquibase.structure.DatabaseObject in project liquibase by liquibase.

the class DatabaseSnapshot method load.

@Override
public void load(ParsedNode parsedNode, ResourceAccessor resourceAccessor) throws ParsedNodeException {
    try {
        Map<String, DatabaseObject> referencedObjects = new HashMap<>();
        Map<String, DatabaseObject> objects = new HashMap<>();
        Map<String, DatabaseObject> allObjects = new HashMap<>();
        ParsedNode databaseNode = parsedNode.getChild(null, "database");
        DatabaseConnection connection = getDatabase().getConnection();
        if ((databaseNode != null) && (connection instanceof OfflineConnection)) {
            ((OfflineConnection) connection).setDatabaseMajorVersion(databaseNode.getChildValue(null, "majorVersion", Integer.class));
            ((OfflineConnection) connection).setDatabaseMinorVersion(databaseNode.getChildValue(null, "minorVersion", Integer.class));
            ((OfflineConnection) connection).setProductVersion(databaseNode.getChildValue(null, "productVersion", String.class));
            ((OfflineConnection) connection).setConnectionUserName(databaseNode.getChildValue(null, "user", String.class));
        }
        loadObjects(referencedObjects, allObjects, parsedNode.getChild(null, "referencedObjects"), resourceAccessor);
        loadObjects(objects, allObjects, parsedNode.getChild(null, "objects"), resourceAccessor);
        for (DatabaseObject object : allObjects.values()) {
            for (String attr : new ArrayList<>(object.getAttributes())) {
                Object value = object.getAttribute(attr, Object.class);
                if ((value instanceof String) && allObjects.containsKey(value)) {
                    if (ObjectUtil.hasProperty(object, attr)) {
                        ObjectUtil.setProperty(object, attr, allObjects.get(value));
                    } else {
                        object.setAttribute(attr, allObjects.get(value));
                    }
                } else if ((value instanceof Collection) && !((Collection) value).isEmpty() && allObjects.containsKey(((Collection) value).iterator().next())) {
                    List<DatabaseObject> newList = new ArrayList<DatabaseObject>();
                    for (String element : (Collection<String>) value) {
                        newList.add(allObjects.get(element));
                    }
                    if (ObjectUtil.hasProperty(object, attr)) {
                        ObjectUtil.setProperty(object, attr, newList);
                    } else {
                        object.setAttribute(attr, newList);
                    }
                } else {
                    if ((value != null) && ObjectUtil.hasProperty(object, attr)) {
                        if ((value instanceof byte[]) && ObjectUtil.getPropertyType(object, attr).equals(String.class)) {
                            value = new String((byte[]) value, GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue());
                        }
                        object.setAttribute(attr, null);
                        ObjectUtil.setProperty(object, attr, value);
                    }
                }
            }
        }
        for (DatabaseObject object : objects.values()) {
            this.allFound.add(object);
        }
        for (DatabaseObject object : referencedObjects.values()) {
            this.referencedObjects.add(object);
        }
    } catch (Exception e) {
        throw new ParsedNodeException(e);
    }
}
Also used : ParsedNode(liquibase.parser.core.ParsedNode) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) OfflineConnection(liquibase.database.OfflineConnection) ParsedNodeException(liquibase.parser.core.ParsedNodeException) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException) DatabaseException(liquibase.exception.DatabaseException) ParsedNodeException(liquibase.parser.core.ParsedNodeException) DatabaseObject(liquibase.structure.DatabaseObject) DatabaseObjectCollection(liquibase.structure.DatabaseObjectCollection) DatabaseConnection(liquibase.database.DatabaseConnection) DatabaseObject(liquibase.structure.DatabaseObject) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList)

Example 33 with DatabaseObject

use of liquibase.structure.DatabaseObject in project liquibase by liquibase.

the class DatabaseSnapshot method clone.

/**
 * Searches the current snapshot content for the given examples. Returns a new DatabaseSnapshot
 * containing a clone of every object from the examples array that was found.
 *
 * @param examples The array of snapshot objects to search and clone
 * @return a new DatabaseSnapshot object with the clones of the desired objects. If no object is
 * found, an empty DatabaseSnapshot will be returned.
 */
public DatabaseSnapshot clone(DatabaseObject[] examples) {
    try {
        DatabaseSnapshot returnSnapshot = new RestoredDatabaseSnapshot(this.database);
        for (DatabaseObject example : examples) {
            DatabaseObject existingObject = this.get(example);
            if (existingObject == null) {
                continue;
            }
            if (example instanceof Schema) {
                for (Class<? extends DatabaseObject> type : this.snapshotControl.getTypesToInclude()) {
                    for (DatabaseObject object : this.get(type)) {
                        if (object.getSchema() == null) {
                            if (object instanceof Catalog) {
                                if (DatabaseObjectComparatorFactory.getInstance().isSameObject(object, ((Schema) example).getCatalog(), null, database)) {
                                    returnSnapshot.allFound.add(object);
                                }
                            } else {
                                returnSnapshot.allFound.add(object);
                            }
                        } else {
                            if (DatabaseObjectComparatorFactory.getInstance().isSameObject(object.getSchema(), example, null, database)) {
                                returnSnapshot.allFound.add(object);
                            } else {
                                if (object.getClass().getName().contains("Synonym") && !object.getAttribute("private", false)) {
                                    Schema objectSchema = object.getAttribute("objectSchema", Schema.class);
                                    if (DatabaseObjectComparatorFactory.getInstance().isSameObject(objectSchema, example, null, database)) {
                                        returnSnapshot.allFound.add(object);
                                    }
                                }
                            }
                        }
                    }
                }
            } else {
                returnSnapshot.allFound.add(existingObject);
            }
        }
        returnSnapshot.getMetadata().putAll(this.getMetadata());
        return returnSnapshot;
    } catch (Exception e) {
        throw new UnexpectedLiquibaseException(e);
    }
}
Also used : CatalogAndSchema(liquibase.CatalogAndSchema) DatabaseObject(liquibase.structure.DatabaseObject) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException) ParsedNodeException(liquibase.parser.core.ParsedNodeException) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException) DatabaseException(liquibase.exception.DatabaseException)

Example 34 with DatabaseObject

use of liquibase.structure.DatabaseObject in project liquibase by liquibase.

the class DatabaseSnapshot method replaceObject.

private Object replaceObject(Object fieldValue) throws DatabaseException, InvalidExampleException, ReflectiveOperationException {
    if (fieldValue == null) {
        return null;
    }
    if (fieldValue instanceof DatabaseObject) {
        if (((DatabaseObject) fieldValue).getSnapshotId() != null) {
            // already been replaced
            return fieldValue;
        }
        if (!snapshotControl.shouldInclude(((DatabaseObject) fieldValue).getClass())) {
            return fieldValue;
        }
        if (!(fieldValue instanceof Catalog) && isWrongSchema(((DatabaseObject) fieldValue))) {
            DatabaseObject savedFieldValue = referencedObjects.get((DatabaseObject) fieldValue, schemaComparisons);
            if (savedFieldValue == null) {
                savedFieldValue = (DatabaseObject) fieldValue;
                savedFieldValue.setSnapshotId(SnapshotIdService.getInstance().generateId());
                includeNestedObjects(savedFieldValue);
                referencedObjects.add(savedFieldValue);
            }
            return savedFieldValue;
        }
        if ((fieldValue instanceof Catalog) && isWrongCatalog(((DatabaseObject) fieldValue))) {
            DatabaseObject savedFieldValue = referencedObjects.get((DatabaseObject) fieldValue, schemaComparisons);
            if (savedFieldValue == null) {
                savedFieldValue = (DatabaseObject) fieldValue;
                savedFieldValue.setSnapshotId(SnapshotIdService.getInstance().generateId());
                referencedObjects.add(savedFieldValue);
            }
            return savedFieldValue;
        }
        if (((DatabaseObject) fieldValue).getSnapshotId() == null) {
            return include((DatabaseObject) fieldValue);
        } else {
            return fieldValue;
        }
    // } else if (Set.class.isAssignableFrom(field.getType())) {
    // field.setAccessible(true);
    // Set fieldValue = field.get(object);
    // for (Object val : fieldValue) {
    // 
    // }
    } else if (fieldValue instanceof Collection) {
        Iterator fieldValueIterator = new CopyOnWriteArrayList((Collection) fieldValue).iterator();
        List<Object> newValues = new ArrayList<>();
        while (fieldValueIterator.hasNext()) {
            Object obj = fieldValueIterator.next();
            if ((fieldValue instanceof DatabaseObject) && !snapshotControl.shouldInclude(((DatabaseObject) fieldValue).getClass())) {
                return fieldValue;
            }
            if ((obj instanceof DatabaseObject) && (((DatabaseObject) obj).getSnapshotId() == null)) {
                obj = include((DatabaseObject) obj);
            }
            if (obj != null) {
                newValues.add(obj);
            }
        }
        Collection<Object> newCollection = null;
        try {
            Class<?> collectionClass = fieldValue.getClass();
            if (List.class.isAssignableFrom(collectionClass)) {
                collectionClass = ArrayList.class;
            }
            newCollection = (Collection<Object>) collectionClass.getConstructor().newInstance();
        } catch (InstantiationException e) {
            throw e;
        }
        newCollection.addAll(newValues);
        return newCollection;
    } else if (fieldValue instanceof Map) {
        Map newMap = (Map) fieldValue.getClass().getConstructor().newInstance();
        for (Map.Entry entry : new HashSet<>((Set<Map.Entry>) ((Map) fieldValue).entrySet())) {
            Object key = replaceObject(entry.getKey());
            Object value = replaceObject(entry.getValue());
            if (key != null) {
                newMap.put(key, value);
            }
        }
        return newMap;
    }
    return fieldValue;
}
Also used : CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) DatabaseObject(liquibase.structure.DatabaseObject) DatabaseObjectCollection(liquibase.structure.DatabaseObjectCollection) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) DatabaseObject(liquibase.structure.DatabaseObject) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList)

Example 35 with DatabaseObject

use of liquibase.structure.DatabaseObject in project liquibase by liquibase.

the class DatabaseSnapshot method isWrongCatalog.

protected boolean isWrongCatalog(DatabaseObject fieldValue) {
    String fieldCatalog;
    if (fieldValue instanceof Catalog) {
        fieldCatalog = fieldValue.getName();
    } else if (fieldValue instanceof Schema) {
        fieldCatalog = ((Schema) fieldValue).getCatalogName();
    } else {
        Schema fieldSchema = fieldValue.getSchema();
        if (fieldSchema == null) {
            return false;
        }
        fieldCatalog = fieldSchema.getCatalogName();
    }
    if (fieldCatalog == null) {
        return false;
    }
    Set<String> catalogNames = new HashSet<>();
    for (DatabaseObject obj : originalExamples) {
        String catalogName = null;
        if (obj instanceof Schema) {
            catalogName = ((Schema) obj).getCatalogName();
        } else if (obj instanceof Catalog) {
            catalogName = obj.getName();
        }
        if (catalogName != null) {
            if (CatalogAndSchema.CatalogAndSchemaCase.ORIGINAL_CASE.equals(database.getSchemaAndCatalogCase())) {
                catalogNames.add(catalogName);
            } else {
                catalogNames.add(catalogName.toLowerCase());
            }
        }
    }
    if (CatalogAndSchema.CatalogAndSchemaCase.ORIGINAL_CASE.equals(database.getSchemaAndCatalogCase())) {
        return !catalogNames.contains(fieldCatalog);
    }
    return !catalogNames.contains(fieldCatalog.toLowerCase());
}
Also used : CatalogAndSchema(liquibase.CatalogAndSchema) DatabaseObject(liquibase.structure.DatabaseObject)

Aggregations

DatabaseObject (liquibase.structure.DatabaseObject)47 UnexpectedLiquibaseException (liquibase.exception.UnexpectedLiquibaseException)14 CompareControl (liquibase.diff.compare.CompareControl)10 Change (liquibase.change.Change)9 Database (liquibase.database.Database)9 CatalogAndSchema (liquibase.CatalogAndSchema)7 DiffResult (liquibase.diff.DiffResult)6 ObjectDifferences (liquibase.diff.ObjectDifferences)6 ArrayList (java.util.ArrayList)5 EmptyDatabaseSnapshot (liquibase.snapshot.EmptyDatabaseSnapshot)5 Column (liquibase.structure.core.Column)5 Table (liquibase.structure.core.Table)5 HashSet (java.util.HashSet)4 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)4 DiffOutputControl (liquibase.diff.output.DiffOutputControl)4 DatabaseException (liquibase.exception.DatabaseException)4 InvalidExampleException (liquibase.snapshot.InvalidExampleException)4 SnapshotControl (liquibase.snapshot.SnapshotControl)4 DatabaseObjectCollection (liquibase.structure.DatabaseObjectCollection)4 List (java.util.List)3