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;
}
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);
}
}
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);
}
}
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;
}
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());
}
Aggregations