mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-30 18:15:39 +00:00
ALF-11518 and ALF-11519: unify separate validation/differences lists and move text generation to Result classes.
ALF-11518: Unify differences and validation results lists ALF-11519: Move validation/diff result text generation from SchemaBootstrap to result classes. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@32110 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
parent
50ad2d600c
commit
29dadc748a
@ -74,6 +74,7 @@ import org.alfresco.util.LogUtil;
|
||||
import org.alfresco.util.TempFileProvider;
|
||||
import org.alfresco.util.schemacomp.Difference;
|
||||
import org.alfresco.util.schemacomp.ExportDb;
|
||||
import org.alfresco.util.schemacomp.Result;
|
||||
import org.alfresco.util.schemacomp.Results;
|
||||
import org.alfresco.util.schemacomp.SchemaComparator;
|
||||
import org.alfresco.util.schemacomp.ValidationResult;
|
||||
@ -104,8 +105,6 @@ import org.hibernate.engine.ActionQueue;
|
||||
import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.core.Conventions;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
@ -1666,8 +1665,7 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
||||
|
||||
schemaComparator.validateAndCompare();
|
||||
|
||||
Results differences = schemaComparator.getDifferences();
|
||||
List<ValidationResult> validationResults = schemaComparator.getValidationResults();
|
||||
Results results = schemaComparator.getComparisonResults();
|
||||
|
||||
String outputFileName = MessageFormat.format(
|
||||
outputFileNameTemplate,
|
||||
@ -1675,8 +1673,6 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
||||
|
||||
File outputFile = TempFileProvider.createTempFile(outputFileName, ".txt");
|
||||
|
||||
|
||||
|
||||
PrintWriter pw = null;
|
||||
try
|
||||
{
|
||||
@ -1687,66 +1683,21 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
||||
throw new RuntimeException("Unable to open file for writing: " + outputFile);
|
||||
}
|
||||
|
||||
for (Difference difference : differences)
|
||||
// Populate the file with details of the comparison's results.
|
||||
for (Result result : results)
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(difference.getStrength())
|
||||
.append(" (diff): ")
|
||||
.append(difference.getWhere());
|
||||
|
||||
sb.append(" reference path:");
|
||||
if (difference.getLeft() != null)
|
||||
{
|
||||
sb.append(difference.getLeft().getPath());
|
||||
sb.append(" (value: ")
|
||||
.append(difference.getLeft().getPropertyValue())
|
||||
.append(")");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append("null");
|
||||
}
|
||||
|
||||
sb.append(" target path:");
|
||||
if (difference.getRight() != null)
|
||||
{
|
||||
sb.append(difference.getRight().getPath());
|
||||
sb.append(" (value: ")
|
||||
.append(difference.getRight().getPropertyValue())
|
||||
.append(")");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append("null");
|
||||
}
|
||||
|
||||
pw.println(sb);
|
||||
pw.println(result.describe());
|
||||
}
|
||||
|
||||
for (ValidationResult validationResult : validationResults)
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(validationResult.getStrength())
|
||||
.append(" (validation): ")
|
||||
.append("target path:")
|
||||
.append(validationResult.getDbProperty().getPath())
|
||||
.append(" (value: ")
|
||||
.append(validationResult.getValue())
|
||||
.append(")");
|
||||
|
||||
pw.println(sb);
|
||||
}
|
||||
|
||||
|
||||
pw.close();
|
||||
|
||||
if (validationResults.size() == 0 && differences.size() == 0)
|
||||
if (results.size() == 0)
|
||||
{
|
||||
logger.info("Compared database schema with reference schema (all OK): " + referenceResource);
|
||||
}
|
||||
else
|
||||
{
|
||||
int numProblems = validationResults.size() + differences.size();
|
||||
int numProblems = results.size();
|
||||
logger.warn("Schema validation found " + numProblems +
|
||||
" potential problems, results written to: "
|
||||
+ outputFile);
|
||||
|
@ -81,7 +81,7 @@ public class DefaultComparisonUtils implements ComparisonUtils
|
||||
ArrayList<? extends Object> leftList = new ArrayList<Object>(leftCollection);
|
||||
ArrayList<? extends Object> rightList = new ArrayList<Object>(rightCollection);
|
||||
|
||||
Results differences = ctx.getDifferences();
|
||||
Results differences = ctx.getComparisonResults();
|
||||
|
||||
for (int leftIndex = 0; leftIndex < leftList.size(); leftIndex++)
|
||||
{
|
||||
@ -144,7 +144,7 @@ public class DefaultComparisonUtils implements ComparisonUtils
|
||||
public void compareCollections(Collection<? extends DbObject> leftCollection,
|
||||
Collection<? extends DbObject> rightCollection, DiffContext ctx, Strength strength)
|
||||
{
|
||||
Results differences = ctx.getDifferences();
|
||||
Results differences = ctx.getComparisonResults();
|
||||
for (DbObject leftObj : leftCollection)
|
||||
{
|
||||
DbObject rightObj = findSameObjectAs(rightCollection, leftObj);
|
||||
@ -234,7 +234,7 @@ public class DefaultComparisonUtils implements ComparisonUtils
|
||||
}
|
||||
}
|
||||
|
||||
ctx.getDifferences().add(where, leftProperty, rightProperty, strength);
|
||||
ctx.getComparisonResults().add(where, leftProperty, rightProperty, strength);
|
||||
}
|
||||
|
||||
|
||||
|
@ -58,7 +58,7 @@ public class DefaultComparisonUtilsTest
|
||||
public void setUp()
|
||||
{
|
||||
comparisonUtils = new DefaultComparisonUtils();
|
||||
ctx = new DiffContext(dialect, differences, new ArrayList<ValidationResult>(), null, null);
|
||||
ctx = new DiffContext(dialect, differences, null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -18,8 +18,6 @@
|
||||
*/
|
||||
package org.alfresco.util.schemacomp;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.util.schemacomp.model.Schema;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
|
||||
@ -33,25 +31,39 @@ import org.hibernate.dialect.Dialect;
|
||||
public class DiffContext
|
||||
{
|
||||
private final Dialect dialect;
|
||||
private final Results differences;
|
||||
private final List<ValidationResult> validationResults;
|
||||
private final Results results;
|
||||
private final Schema referenceSchema;
|
||||
private final Schema targetSchema;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param dialect
|
||||
* @param differences
|
||||
* @param results
|
||||
* @param referenceSchema
|
||||
* @param targetSchema
|
||||
*/
|
||||
public DiffContext(Dialect dialect, Results differences, List<ValidationResult> validationResults,
|
||||
Schema referenceSchema, Schema targetSchema)
|
||||
public DiffContext(Dialect dialect, Results results, Schema referenceSchema, Schema targetSchema)
|
||||
{
|
||||
this.dialect = dialect;
|
||||
this.differences = differences;
|
||||
this.validationResults = validationResults;
|
||||
this.results = results;
|
||||
this.referenceSchema = referenceSchema;
|
||||
this.targetSchema = targetSchema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param dialect
|
||||
* @param referenceSchema
|
||||
* @param targetSchema
|
||||
*/
|
||||
public DiffContext(Dialect dialect, Schema referenceSchema, Schema targetSchema)
|
||||
{
|
||||
this(dialect, new Results(), referenceSchema, targetSchema);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the dialect
|
||||
*/
|
||||
@ -61,19 +73,11 @@ public class DiffContext
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the differences
|
||||
* @return the results of schema comparison: validation failures, differences etc.
|
||||
*/
|
||||
public Results getDifferences()
|
||||
public Results getComparisonResults()
|
||||
{
|
||||
return this.differences;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the validationResults
|
||||
*/
|
||||
public List<ValidationResult> getValidationResults()
|
||||
{
|
||||
return this.validationResults;
|
||||
return this.results;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,6 +71,43 @@ public final class Difference extends Result
|
||||
return this.right;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String describe()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("Difference: ")
|
||||
.append(getWhere());
|
||||
|
||||
sb.append(" reference path:");
|
||||
if (getLeft() != null)
|
||||
{
|
||||
sb.append(getLeft().getPath());
|
||||
sb.append(" (value: ")
|
||||
.append(getLeft().getPropertyValue())
|
||||
.append(")");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append("null");
|
||||
}
|
||||
|
||||
sb.append(" target path:");
|
||||
if (getRight() != null)
|
||||
{
|
||||
sb.append(getRight().getPath());
|
||||
sb.append(" (value: ")
|
||||
.append(getRight().getPropertyValue())
|
||||
.append(")");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append("null");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
51
source/java/org/alfresco/util/schemacomp/DifferenceTest.java
Normal file
51
source/java/org/alfresco/util/schemacomp/DifferenceTest.java
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.util.schemacomp;
|
||||
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.alfresco.util.schemacomp.Difference.Where;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests for the {@link Difference} class.
|
||||
*
|
||||
* @author Matt Ward
|
||||
*/
|
||||
public class DifferenceTest
|
||||
{
|
||||
@Test
|
||||
public void describe()
|
||||
{
|
||||
DbProperty refDbProp = mock(DbProperty.class);
|
||||
when(refDbProp.getPath()).thenReturn("alfresco.some_table.some_column.name");
|
||||
when(refDbProp.getPropertyValue()).thenReturn("node_ref");
|
||||
|
||||
DbProperty targetDbProp = mock(DbProperty.class);
|
||||
when(targetDbProp.getPath()).thenReturn("alfresco.some_table.some_column.name");
|
||||
when(targetDbProp.getPropertyValue()).thenReturn("nood_ref");
|
||||
Difference diff = new Difference(Where.ONLY_IN_LEFT, refDbProp, targetDbProp);
|
||||
|
||||
assertEquals("Difference: ONLY_IN_LEFT reference path:alfresco.some_table.some_column.name (value: node_ref) " +
|
||||
"target path:alfresco.some_table.some_column.name (value: nood_ref)", diff.describe());
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.util.schemacomp;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.util.schemacomp.model.DbObject;
|
||||
|
||||
/**
|
||||
* If more than one DB item in the target schema matches a reference DB item
|
||||
* then this result will be issued.
|
||||
*
|
||||
* @author Matt Ward
|
||||
*/
|
||||
public class RedundantDbObject extends Result
|
||||
{
|
||||
private final static int SHOW_MAX_MATCHES = 3;
|
||||
private DbObject dbObject;
|
||||
private List<DbObject> matches;
|
||||
|
||||
public RedundantDbObject(DbObject dbObject, List<DbObject> matches)
|
||||
{
|
||||
super(null);
|
||||
this.dbObject = dbObject;
|
||||
this.matches = matches;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String describe()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(matches.size())
|
||||
.append(" redundant items? reference: ")
|
||||
.append(dbObject)
|
||||
.append(", matches: ");
|
||||
|
||||
for (int i = 0; i < matches.size() && i < SHOW_MAX_MATCHES; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(matches.get(i));
|
||||
}
|
||||
|
||||
if (matches.size() > SHOW_MAX_MATCHES)
|
||||
{
|
||||
sb.append(" and ")
|
||||
.append(matches.size() - SHOW_MAX_MATCHES).append(" more...");
|
||||
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "RedundantDbObject [dbObject=" + this.dbObject + ", matches=" + this.matches + "]";
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.util.schemacomp;
|
||||
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.util.schemacomp.model.AbstractDbObject;
|
||||
import org.alfresco.util.schemacomp.model.DbObject;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests for the {@link RedundantDbObject} class.
|
||||
*
|
||||
* @author Matt Ward
|
||||
*/
|
||||
public class RedundantDbObjectTest
|
||||
{
|
||||
|
||||
@Test
|
||||
public void describe()
|
||||
{
|
||||
DbObject reference = new MyDbObject("reference");
|
||||
List<DbObject> matches = makeMatches(3);
|
||||
|
||||
RedundantDbObject redundantDBO = new RedundantDbObject(reference, matches);
|
||||
|
||||
assertEquals("3 redundant items? reference: MyDbObject[name=reference], " +
|
||||
"matches: MyDbObject[name=match1], MyDbObject[name=match2], MyDbObject[name=match3]",
|
||||
redundantDBO.describe());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void describeTooManyMatches()
|
||||
{
|
||||
DbObject reference = new MyDbObject("reference");
|
||||
List<DbObject> matches = makeMatches(4);
|
||||
|
||||
RedundantDbObject redundantDBO = new RedundantDbObject(reference, matches);
|
||||
|
||||
assertEquals("4 redundant items? reference: MyDbObject[name=reference], " +
|
||||
"matches: MyDbObject[name=match1], MyDbObject[name=match2], MyDbObject[name=match3] and 1 more...",
|
||||
redundantDBO.describe());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
private List<DbObject> makeMatches(int numMatches)
|
||||
{
|
||||
List<DbObject> matches = new ArrayList<DbObject>();
|
||||
for (int i = 0; i < numMatches; i++)
|
||||
{
|
||||
matches.add(new MyDbObject("match" + (i+1)));
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
|
||||
private static class MyDbObject extends AbstractDbObject
|
||||
{
|
||||
public MyDbObject(String name)
|
||||
{
|
||||
super(null, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(DbObjectVisitor visitor)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ package org.alfresco.util.schemacomp;
|
||||
*
|
||||
* @author Matt Ward
|
||||
*/
|
||||
public class Result
|
||||
public abstract class Result
|
||||
{
|
||||
public enum Strength { WARN, ERROR };
|
||||
protected final Strength strength;
|
||||
@ -43,4 +43,16 @@ public class Result
|
||||
{
|
||||
return this.strength;
|
||||
}
|
||||
|
||||
/**
|
||||
* A loggable message to describe the comparison result. Default implementation
|
||||
* delegates to toString() but this should generally be overridden as toString()
|
||||
* is used in a multitude of contexts.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String describe()
|
||||
{
|
||||
return toString();
|
||||
}
|
||||
}
|
||||
|
@ -30,9 +30,9 @@ import org.alfresco.util.schemacomp.Result.Strength;
|
||||
*
|
||||
* @author Matt Ward
|
||||
*/
|
||||
public class Results implements Iterable<Difference>
|
||||
public class Results implements Iterable<Result>
|
||||
{
|
||||
private final List<Difference> items = new ArrayList<Difference>();
|
||||
private final List<Result> items = new ArrayList<Result>();
|
||||
/** Temporary step during refactor - Where.IN_BOTH_NO_DIFFERENCE will be going altogether */
|
||||
private boolean reportNonDifferences = false;
|
||||
|
||||
@ -62,16 +62,32 @@ public class Results implements Iterable<Difference>
|
||||
}
|
||||
|
||||
|
||||
public void add(Result result)
|
||||
{
|
||||
items.add(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain an iterator for the top-level items held in this schema - since this is a hierarchical model,
|
||||
* deeper items are obtained by navigating through the top-level items.
|
||||
*/
|
||||
@Override
|
||||
public Iterator<Difference> iterator()
|
||||
public Iterator<Result> iterator()
|
||||
{
|
||||
return items.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ith result.
|
||||
*
|
||||
* @param i
|
||||
* @return Result
|
||||
*/
|
||||
public Result get(int i)
|
||||
{
|
||||
return items.get(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return How many top-level items are in the schema.
|
||||
*/
|
||||
|
@ -33,8 +33,11 @@ import org.junit.runners.Suite;
|
||||
DbPropertyTest.class,
|
||||
DbToXMLTest.class,
|
||||
DefaultComparisonUtilsTest.class,
|
||||
DifferenceTest.class,
|
||||
ExportDbTest.class,
|
||||
RedundantDbObjectTest.class,
|
||||
SchemaComparatorTest.class,
|
||||
ValidationResultTest.class,
|
||||
ValidatingVisitorTest.class,
|
||||
SchemaToXMLTest.class,
|
||||
XMLToSchemaTest.class
|
||||
|
@ -36,23 +36,30 @@ import org.apache.commons.lang.ArrayUtils;
|
||||
|
||||
public class SchemaCompTestingUtils
|
||||
{
|
||||
public static void dumpValidation(List<ValidationResult> validationResults)
|
||||
public static void dumpValidation(Results results)
|
||||
{
|
||||
System.out.println("Validation Results (" + validationResults.size() + ")");
|
||||
for (ValidationResult r : validationResults)
|
||||
System.out.println("Validation Results (" + results.size() + ")");
|
||||
for (Result r : results)
|
||||
{
|
||||
System.out.println(r);
|
||||
if (r instanceof ValidationResult)
|
||||
{
|
||||
System.out.println(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void dumpDiffs(Results differences, boolean showNonDifferences)
|
||||
{
|
||||
System.out.println("Differences (" + differences.size() + ")");
|
||||
for (Difference d : differences)
|
||||
for (Result d : differences)
|
||||
{
|
||||
if (d.getWhere() != Where.IN_BOTH_NO_DIFFERENCE || showNonDifferences)
|
||||
if (d instanceof Difference)
|
||||
{
|
||||
System.out.println(d);
|
||||
Difference diff = (Difference) d;
|
||||
if (diff.getWhere() != Where.IN_BOTH_NO_DIFFERENCE || showNonDifferences)
|
||||
{
|
||||
System.out.println(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,9 +18,6 @@
|
||||
*/
|
||||
package org.alfresco.util.schemacomp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.util.schemacomp.Result.Strength;
|
||||
import org.alfresco.util.schemacomp.model.Schema;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
@ -48,7 +45,7 @@ public class SchemaComparator
|
||||
{
|
||||
this.referenceSchema = referenceSchema;
|
||||
this.targetSchema = targetSchema;
|
||||
this.ctx = new DiffContext(dialect, new Results(), new ArrayList<ValidationResult>(), referenceSchema, targetSchema);
|
||||
this.ctx = new DiffContext(dialect, referenceSchema, targetSchema);
|
||||
}
|
||||
|
||||
|
||||
@ -79,19 +76,10 @@ public class SchemaComparator
|
||||
|
||||
|
||||
/**
|
||||
* @return the differences
|
||||
* @return the schema comparison results.
|
||||
*/
|
||||
public Results getDifferences()
|
||||
public Results getComparisonResults()
|
||||
{
|
||||
return ctx.getDifferences();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the validation results.
|
||||
*/
|
||||
public List<ValidationResult> getValidationResults()
|
||||
{
|
||||
return ctx.getValidationResults();
|
||||
return ctx.getComparisonResults();
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ import static org.alfresco.util.schemacomp.SchemaCompTestingUtils.pk;
|
||||
import static org.alfresco.util.schemacomp.SchemaCompTestingUtils.table;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
@ -57,8 +56,8 @@ public class SchemaComparatorTest
|
||||
@Before
|
||||
public void setup()
|
||||
{
|
||||
reference = new Schema("reference_schema");
|
||||
target = new Schema("target_schema");
|
||||
reference = new Schema("schema");
|
||||
target = new Schema("schema");
|
||||
dialect = new MySQL5InnoDBDialect();
|
||||
}
|
||||
|
||||
@ -87,67 +86,55 @@ public class SchemaComparatorTest
|
||||
comparator.validateAndCompare();
|
||||
|
||||
// See stdout for diagnostics dump...
|
||||
dumpDiffs(comparator.getDifferences(), false);
|
||||
dumpValidation(comparator.getValidationResults());
|
||||
dumpDiffs(comparator.getComparisonResults(), false);
|
||||
dumpValidation(comparator.getComparisonResults());
|
||||
|
||||
|
||||
Results differences = comparator.getDifferences();
|
||||
Results results = comparator.getComparisonResults();
|
||||
|
||||
Iterator<Difference> it = differences.iterator();
|
||||
|
||||
// Schema names are different ("reference_schema" vs "target_schema")
|
||||
Difference diff = it.next();
|
||||
assertEquals(Where.IN_BOTH_BUT_DIFFERENCE, diff.getWhere());
|
||||
assertEquals("reference_schema.name", diff.getLeft().getPath());
|
||||
assertEquals("target_schema.name", diff.getRight().getPath());
|
||||
assertSame(reference, diff.getLeft().getDbObject());
|
||||
assertSame(target, diff.getRight().getDbObject());
|
||||
assertEquals("name", diff.getLeft().getPropertyName());
|
||||
assertEquals("reference_schema", diff.getLeft().getPropertyValue());
|
||||
assertEquals("name", diff.getRight().getPropertyName());
|
||||
assertEquals("target_schema", diff.getRight().getPropertyValue());
|
||||
Iterator<Result> it = results.iterator();
|
||||
|
||||
// Table table_in_reference only appears in the reference schema
|
||||
diff = it.next();
|
||||
Difference diff = (Difference) it.next();
|
||||
assertEquals(Where.ONLY_IN_LEFT, diff.getWhere());
|
||||
assertEquals("reference_schema.table_in_reference", diff.getLeft().getPath());
|
||||
assertEquals("schema.table_in_reference", diff.getLeft().getPath());
|
||||
assertEquals(null, diff.getRight());
|
||||
assertEquals(null, diff.getLeft().getPropertyName());
|
||||
assertEquals(null, diff.getLeft().getPropertyValue());
|
||||
|
||||
// Table tbl_has_diff_pk has PK of "id" in reference and "nodeRef" in target
|
||||
diff = it.next();
|
||||
diff = (Difference) it.next();
|
||||
assertEquals(Where.ONLY_IN_LEFT, diff.getWhere());
|
||||
assertEquals("reference_schema.tbl_has_diff_pk.pk_is_diff.columnNames[0]", diff.getLeft().getPath());
|
||||
assertEquals("target_schema.tbl_has_diff_pk.pk_is_diff.columnNames", diff.getRight().getPath());
|
||||
assertEquals("schema.tbl_has_diff_pk.pk_is_diff.columnNames[0]", diff.getLeft().getPath());
|
||||
assertEquals("schema.tbl_has_diff_pk.pk_is_diff.columnNames", diff.getRight().getPath());
|
||||
assertEquals("columnNames[0]", diff.getLeft().getPropertyName());
|
||||
assertEquals("id", diff.getLeft().getPropertyValue());
|
||||
assertEquals("columnNames", diff.getRight().getPropertyName());
|
||||
assertEquals(Arrays.asList("nodeRef"), diff.getRight().getPropertyValue());
|
||||
|
||||
// Table tbl_has_diff_pk has PK of "id" in reference and "nodeRef" in target
|
||||
diff = it.next();
|
||||
diff = (Difference) it.next();
|
||||
assertEquals(Where.ONLY_IN_RIGHT, diff.getWhere());
|
||||
assertEquals("reference_schema.tbl_has_diff_pk.pk_is_diff.columnNames", diff.getLeft().getPath());
|
||||
assertEquals("target_schema.tbl_has_diff_pk.pk_is_diff.columnNames[0]", diff.getRight().getPath());
|
||||
assertEquals("schema.tbl_has_diff_pk.pk_is_diff.columnNames", diff.getLeft().getPath());
|
||||
assertEquals("schema.tbl_has_diff_pk.pk_is_diff.columnNames[0]", diff.getRight().getPath());
|
||||
assertEquals("columnNames", diff.getLeft().getPropertyName());
|
||||
assertEquals(Arrays.asList("id"), diff.getLeft().getPropertyValue());
|
||||
assertEquals("columnNames[0]", diff.getRight().getPropertyName());
|
||||
assertEquals("nodeRef", diff.getRight().getPropertyValue());
|
||||
|
||||
// idx_two is unique in the righ_schema but not in the reference
|
||||
diff = it.next();
|
||||
assertEquals("reference_schema.tbl_has_diff_pk.idx_two.unique", diff.getLeft().getPath());
|
||||
assertEquals("target_schema.tbl_has_diff_pk.idx_two.unique", diff.getRight().getPath());
|
||||
diff = (Difference) it.next();
|
||||
assertEquals("schema.tbl_has_diff_pk.idx_two.unique", diff.getLeft().getPath());
|
||||
assertEquals("schema.tbl_has_diff_pk.idx_two.unique", diff.getRight().getPath());
|
||||
assertEquals("unique", diff.getLeft().getPropertyName());
|
||||
assertEquals(false, diff.getLeft().getPropertyValue());
|
||||
assertEquals("unique", diff.getRight().getPropertyName());
|
||||
assertEquals(true, diff.getRight().getPropertyValue());
|
||||
|
||||
// Table table_in_target does not exist in the reference schema
|
||||
diff = it.next();
|
||||
diff = (Difference) it.next();
|
||||
assertEquals(Where.ONLY_IN_RIGHT, diff.getWhere());
|
||||
assertEquals("target_schema.table_in_target", diff.getRight().getPath());
|
||||
assertEquals("schema.table_in_target", diff.getRight().getPath());
|
||||
assertEquals(null, diff.getLeft());
|
||||
assertEquals(null, diff.getRight().getPropertyName());
|
||||
assertEquals(null, diff.getRight().getPropertyValue());
|
||||
|
@ -44,7 +44,10 @@ public class ValidatingVisitor implements DbObjectVisitor
|
||||
{
|
||||
List<DbObject> matches = comparisonUtils.findEquivalentObjects(ctx.getTargetSchema(), referenceObj);
|
||||
|
||||
// TODO: if matches.size() > 1 then warn of possible redundant database objects
|
||||
if (matches.size() > 1)
|
||||
{
|
||||
ctx.getComparisonResults().add(new RedundantDbObject(referenceObj, matches));
|
||||
}
|
||||
|
||||
// Validate each matching target object against the reference object
|
||||
// using each of the available validators for that reference object.
|
||||
|
@ -31,6 +31,7 @@ import org.alfresco.util.schemacomp.validator.DbValidator;
|
||||
import org.hibernate.dialect.MySQL5InnoDBDialect;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
/**
|
||||
@ -59,8 +60,7 @@ public class ValidatingVisitorTest
|
||||
{
|
||||
refTable = new Table("reference_table");
|
||||
refIndex = new Index(refTable, "index_name", Arrays.asList("a", "b", "c"));
|
||||
ctx = new DiffContext(new MySQL5InnoDBDialect(), new Results(),
|
||||
new ArrayList<ValidationResult>(), refSchema, targetSchema);
|
||||
ctx = new DiffContext(new MySQL5InnoDBDialect(), refSchema, targetSchema);
|
||||
visitor = new ValidatingVisitor(ctx);
|
||||
|
||||
validators = new ArrayList<DbValidator>();
|
||||
@ -97,4 +97,29 @@ public class ValidatingVisitorTest
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void redundantDbObjectsAreNoticed()
|
||||
{
|
||||
Mockito.when(comparisonUtils.findEquivalentObjects(refSchema, refIndex)).
|
||||
thenReturn(Arrays.asList((DbObject) targetIndex1, targetIndex2, targetIndex3));
|
||||
|
||||
// Validate all instances of the target schema's indexes that are equivalent to this index
|
||||
visitor.visit(refIndex);
|
||||
|
||||
assertEquals(1, ctx.getComparisonResults().size());
|
||||
assertEquals(RedundantDbObject.class, ctx.getComparisonResults().get(0).getClass());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void nonRedundantDbObjectsAreNoticed()
|
||||
{
|
||||
Mockito.when(comparisonUtils.findEquivalentObjects(refSchema, refIndex)).
|
||||
thenReturn(Arrays.asList((DbObject) targetIndex1));
|
||||
|
||||
// Validate all instances of the target schema's indexes that are equivalent to this index
|
||||
visitor.visit(refIndex);
|
||||
|
||||
assertEquals(0, ctx.getComparisonResults().size());
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,21 @@ public class ValidationResult extends Result
|
||||
this.dbProperty = dbProperty;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String describe()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("Validation ")
|
||||
.append("target path:")
|
||||
.append(getDbProperty().getPath())
|
||||
.append(" (value: ")
|
||||
.append(getValue())
|
||||
.append(")");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value that was rejected.
|
||||
*/
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.util.schemacomp;
|
||||
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
/**
|
||||
* Tests for the {@link ValidationResult} class.
|
||||
*
|
||||
* @author Matt Ward
|
||||
*/
|
||||
public class ValidationResultTest
|
||||
{
|
||||
@Test
|
||||
public void describe()
|
||||
{
|
||||
DbProperty targetDbProp = mock(DbProperty.class);
|
||||
when(targetDbProp.getPath()).thenReturn("alfresco.some_table.some_index.name");
|
||||
when(targetDbProp.getPropertyValue()).thenReturn("ibx_my_index");
|
||||
|
||||
ValidationResult validation = new ValidationResult(targetDbProp);
|
||||
|
||||
assertEquals("Validation target path:alfresco.some_table.some_index.name (value: ibx_my_index)",
|
||||
validation.describe());
|
||||
}
|
||||
}
|
@ -96,16 +96,35 @@ public abstract class AbstractDbObject implements DbObject
|
||||
@Override
|
||||
public boolean sameAs(DbObject other)
|
||||
{
|
||||
if (other == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this == other)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!this.getClass().equals(other.getClass()))
|
||||
{
|
||||
// Objects are not the same type, even if they have the same name and parent
|
||||
return false;
|
||||
}
|
||||
if (getName() != null && other != null && other.getName() != null)
|
||||
{
|
||||
return getName().equals(other.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only other way we can know if they are the same is if they are
|
||||
// the exact same object reference.
|
||||
return this == other;
|
||||
boolean sameParent = false;
|
||||
|
||||
if (getParent() == null && other.getParent() == null)
|
||||
{
|
||||
sameParent = true;
|
||||
}
|
||||
else if (getParent() != null && getParent().sameAs(other.getParent()))
|
||||
{
|
||||
sameParent = true;
|
||||
}
|
||||
return sameParent && getName().equals(other.getName());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -23,7 +23,6 @@ import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@ -33,7 +32,6 @@ import org.alfresco.util.schemacomp.DiffContext;
|
||||
import org.alfresco.util.schemacomp.Difference.Where;
|
||||
import org.alfresco.util.schemacomp.Result.Strength;
|
||||
import org.alfresco.util.schemacomp.Results;
|
||||
import org.alfresco.util.schemacomp.ValidationResult;
|
||||
import org.alfresco.util.schemacomp.validator.AbstractDbValidator;
|
||||
import org.alfresco.util.schemacomp.validator.DbValidator;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
@ -64,7 +62,7 @@ public class AbstractDbObjectTest
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
dbObject = new ConcreteDbObject("the_object");
|
||||
ctx = new DiffContext(dialect, differences, new ArrayList<ValidationResult>(), null, null);
|
||||
ctx = new DiffContext(dialect, differences, null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -83,7 +81,8 @@ public class AbstractDbObjectTest
|
||||
|
||||
dbObject.setName("the_name");
|
||||
assertFalse("Not the same.", dbObject.sameAs(null));
|
||||
assertFalse("Not the same.", dbObject.sameAs(new ConcreteDbObject("different_name")));
|
||||
assertFalse("Not the same.", dbObject.sameAs(new ConcreteDbObject("different_name")));
|
||||
assertFalse("Not the same type", dbObject.sameAs(new AnotherConcreteDbObject("the_name")));
|
||||
assertTrue("Logically the same object.", dbObject.sameAs(new ConcreteDbObject("the_name")));
|
||||
assertTrue("The very same object with non-null name", dbObject.sameAs(dbObject));
|
||||
}
|
||||
@ -146,7 +145,7 @@ public class AbstractDbObjectTest
|
||||
@Override
|
||||
protected void doDiff(DbObject right, DiffContext ctx, Strength strength)
|
||||
{
|
||||
Results differences = ctx.getDifferences();
|
||||
Results differences = ctx.getComparisonResults();
|
||||
differences.add(
|
||||
Where.IN_BOTH_BUT_DIFFERENCE,
|
||||
new DbProperty(this, "someProp"),
|
||||
@ -164,6 +163,19 @@ public class AbstractDbObjectTest
|
||||
}
|
||||
}
|
||||
|
||||
public static class AnotherConcreteDbObject extends AbstractDbObject
|
||||
{
|
||||
public AnotherConcreteDbObject(String name)
|
||||
{
|
||||
super(null, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(DbObjectVisitor visitor)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private List<DbValidator> validatorList(DbValidator... validators)
|
||||
{
|
||||
|
@ -131,4 +131,28 @@ public class Column extends AbstractDbObject
|
||||
{
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sameAs(DbObject other)
|
||||
{
|
||||
if (other == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this == other)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (getClass().equals(other.getClass()))
|
||||
{
|
||||
if (getName() != null && other.getName() != null)
|
||||
{
|
||||
if (getParent() != null && other.getParent() != null && getParent().sameAs(other.getParent()))
|
||||
{
|
||||
return getName().equals(other.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import org.alfresco.util.schemacomp.DbProperty;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Tests for the Column class.
|
||||
@ -73,5 +74,24 @@ public class ColumnTest extends DbObjectTestBase<Column>
|
||||
|
||||
verify(visitor).visit(thisColumn);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sameAs()
|
||||
{
|
||||
Table thisTable = new Table("the_table");
|
||||
thisColumn = new Column(thisTable, "this_column", "VARCHAR2(100)", false);
|
||||
|
||||
Table thatTable = new Table("the_table");
|
||||
thatColumn = new Column(thatTable, "this_column", "VARCHAR2(100)", false);
|
||||
|
||||
// This column, whilst having the same name as thisColumn, has a different
|
||||
// parent table - and so is not considered 'the same'.
|
||||
Table anotherTable = new Table("another_table");
|
||||
Column anotherColumn = new Column(anotherTable, "this_column", "VARCHAR2(100)", false);
|
||||
|
||||
assertTrue("Column should always be the same as itself", thisColumn.sameAs(thisColumn));
|
||||
assertTrue("Columns should be the same due to same parent table names", thisColumn.sameAs(thatColumn));
|
||||
assertFalse("Should NOT be the same due to different parent table names", thisColumn.sameAs(anotherColumn));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.alfresco.util.schemacomp.model;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -27,9 +27,8 @@ import org.alfresco.util.schemacomp.ComparisonUtils;
|
||||
import org.alfresco.util.schemacomp.DbObjectVisitor;
|
||||
import org.alfresco.util.schemacomp.DbProperty;
|
||||
import org.alfresco.util.schemacomp.DiffContext;
|
||||
import org.alfresco.util.schemacomp.Results;
|
||||
import org.alfresco.util.schemacomp.Result.Strength;
|
||||
import org.alfresco.util.schemacomp.ValidationResult;
|
||||
import org.alfresco.util.schemacomp.Results;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@ -61,7 +60,7 @@ public abstract class DbObjectTestBase<T extends AbstractDbObject>
|
||||
// Check that the correct calls happened in the correct order.
|
||||
List<Object> mocks = getMocksUsedInDiff();
|
||||
inOrder = inOrder(mocks.toArray());
|
||||
ctx = new DiffContext(dialect, differences, new ArrayList<ValidationResult>(), null, null);
|
||||
ctx = new DiffContext(dialect, differences, null, null);
|
||||
}
|
||||
|
||||
|
||||
|
@ -49,7 +49,7 @@ public class NameValidator implements DbValidator
|
||||
|
||||
if (pattern != null && !pattern.matcher(name).matches())
|
||||
{
|
||||
ctx.getValidationResults().add(result);
|
||||
ctx.getComparisonResults().add(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,6 @@ package org.alfresco.util.schemacomp.validator;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.alfresco.util.schemacomp.DiffContext;
|
||||
@ -43,14 +42,14 @@ public class NameValidatorTest
|
||||
{
|
||||
private NameValidator validator;
|
||||
private DiffContext ctx;
|
||||
private List<ValidationResult> validationResults;
|
||||
private Results validationResults;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
validator = new NameValidator();
|
||||
validationResults = new ArrayList<ValidationResult>();
|
||||
ctx = new DiffContext(new Oracle10gDialect(), new Results(), validationResults, null, null);
|
||||
validationResults = new Results();
|
||||
ctx = new DiffContext(new Oracle10gDialect(), validationResults, null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -63,8 +62,8 @@ public class NameValidatorTest
|
||||
validator.validate(null, indexForName("MY_INDEX"), ctx);
|
||||
|
||||
assertEquals(2, validationResults.size());
|
||||
assertEquals("SYS_", validationResults.get(0).getValue());
|
||||
assertEquals("MY_INDEX", validationResults.get(1).getValue());
|
||||
assertEquals("SYS_", ((ValidationResult) validationResults.get(0)).getValue());
|
||||
assertEquals("MY_INDEX", ((ValidationResult) validationResults.get(1)).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -76,7 +75,7 @@ public class NameValidatorTest
|
||||
validator.validate(null, indexForName("SYS_MYINDEX"), ctx);
|
||||
|
||||
assertEquals(1, validationResults.size());
|
||||
assertEquals("SYS_MYINDEX", validationResults.get(0).getValue());
|
||||
assertEquals("SYS_MYINDEX", ((ValidationResult) validationResults.get(0)).getValue());
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user