package liquibase.diff.compare.core; import liquibase.CatalogAndSchema; import liquibase.database.Database; import liquibase.diff.ObjectDifferences; import liquibase.diff.compare.CompareControl; import liquibase.diff.compare.DatabaseObjectComparator; import liquibase.diff.compare.DatabaseObjectComparatorChain; import liquibase.structure.DatabaseObject; import liquibase.structure.core.Schema; import liquibase.util.StringUtils; import java.util.*; public class SchemaComparator implements DatabaseObjectComparator { @Override public int getPriority(Class<? extends DatabaseObject> objectType, Database database) { if (Schema.class.isAssignableFrom(objectType)) { return PRIORITY_TYPE; } return PRIORITY_NONE; } @Override public String[] hash(DatabaseObject databaseObject, Database accordingTo, DatabaseObjectComparatorChain chain) { return null; } @Override public boolean isSameObject(DatabaseObject databaseObject1, DatabaseObject databaseObject2, Database accordingTo, DatabaseObjectComparatorChain chain) { if (!(databaseObject1 instanceof Schema && databaseObject2 instanceof Schema)) { return false; } String schemaName1 = null; String schemaName2 = null; if (accordingTo.supportsSchemas()) { schemaName1 = databaseObject1.getName(); schemaName2 = databaseObject2.getName(); } else if (accordingTo.supportsCatalogs()) { schemaName1 = ((Schema) databaseObject1).getCatalogName(); schemaName2 = ((Schema) databaseObject2).getCatalogName(); } if (StringUtils.trimToEmpty(schemaName1).equalsIgnoreCase(StringUtils.trimToEmpty(schemaName2))) { return true; } //switch off default names and then compare again if (schemaName1 == null) { if (accordingTo.supportsSchemas()) { schemaName1 = accordingTo.getDefaultSchemaName(); } else if (accordingTo.supportsCatalogs()) { schemaName1 = accordingTo.getDefaultCatalogName(); } } if (schemaName2 == null) { if (accordingTo.supportsSchemas()) { schemaName2 = accordingTo.getDefaultSchemaName(); } else if (accordingTo.supportsCatalogs()) { schemaName2 = accordingTo.getDefaultCatalogName(); } } if (StringUtils.trimToEmpty(schemaName1).equalsIgnoreCase(StringUtils.trimToEmpty(schemaName2))) { return true; } //check with schemaComparisons if (chain.getSchemaComparisons() != null && chain.getSchemaComparisons().length > 0) { for (CompareControl.SchemaComparison comparison : chain.getSchemaComparisons()) { String comparisonSchema1; String comparisonSchema2; if (accordingTo.supportsSchemas()) { comparisonSchema1 = comparison.getComparisonSchema().getSchemaName(); comparisonSchema2 = comparison.getReferenceSchema().getSchemaName(); } else if (accordingTo.supportsCatalogs()) { comparisonSchema1 = comparison.getComparisonSchema().getCatalogName(); comparisonSchema2 = comparison.getReferenceSchema().getCatalogName(); } else { break; } String finalSchema1 = schemaName1; String finalSchema2 = schemaName2; if (comparisonSchema1 != null && comparisonSchema1.equalsIgnoreCase(schemaName1)) { finalSchema1 = comparisonSchema2; } else if (comparisonSchema2 != null && comparisonSchema2.equalsIgnoreCase(schemaName1)) { finalSchema1 = comparisonSchema1; } if (StringUtils.trimToEmpty(finalSchema1).equalsIgnoreCase(StringUtils.trimToEmpty(finalSchema2))) { return true; } if (comparisonSchema1 != null && comparisonSchema1.equalsIgnoreCase(schemaName2)) { finalSchema2 = comparisonSchema2; } else if (comparisonSchema2 != null && comparisonSchema2.equalsIgnoreCase(schemaName2)) { finalSchema2 = comparisonSchema1; } if (StringUtils.trimToEmpty(finalSchema1).equalsIgnoreCase(StringUtils.trimToEmpty(finalSchema2))) { return true; } } } schemaName1 = ((Schema) databaseObject1).toCatalogAndSchema().standardize(accordingTo).getSchemaName(); schemaName2 = ((Schema) databaseObject2).toCatalogAndSchema().standardize(accordingTo).getSchemaName(); return StringUtils.trimToEmpty(schemaName1).equalsIgnoreCase(StringUtils.trimToEmpty(schemaName2)); } @Override public ObjectDifferences findDifferences(DatabaseObject databaseObject1, DatabaseObject databaseObject2, Database accordingTo, CompareControl compareControl, DatabaseObjectComparatorChain chain, Set<String> exclude) { ObjectDifferences differences = new ObjectDifferences(compareControl); differences.compare("name", databaseObject1, databaseObject2, new ObjectDifferences.DatabaseObjectNameCompareFunction(Schema.class, accordingTo)); return differences; } }