Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
tbrugz.sqldiff.RenameDetector Maven / Gradle / Ivy
package tbrugz.sqldiff;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import tbrugz.sqldiff.model.ChangeType;
import tbrugz.sqldiff.model.ColumnDiff;
import tbrugz.sqldiff.model.DBIdentifiableDiff;
import tbrugz.sqldiff.model.Diff;
import tbrugz.sqldiff.model.TableDiff;
import tbrugz.sqldiff.util.SimilarityCalculator;
import tbrugz.sqldump.dbmodel.Constraint;
import tbrugz.sqldump.dbmodel.DBIdentifiable;
import tbrugz.sqldump.dbmodel.DBObjectType;
import tbrugz.sqldump.dbmodel.Index;
import tbrugz.sqldump.dbmodel.Table;
class RenameTuple {
Diff add;
Diff drop;
double similarity;
public RenameTuple(Diff add, Diff drop, double similarity) {
this.add = add;
this.drop = drop;
this.similarity = similarity;
}
@Override
public String toString() {
return "RenameTuple[ add="+add+" ; drop="+drop+" ]";
}
}
public class RenameDetector {
static final Log log = LogFactory.getLog(RenameDetector.class);
public static final DBObjectType[] RENAME_TYPES = {
DBObjectType.TABLE, DBObjectType.COLUMN, DBObjectType.INDEX, DBObjectType.CONSTRAINT
};
static List detectTableRenames(Collection tableDiffs, double minSimilarity) {
List ltadd = getDiffsOfType(tableDiffs, ChangeType.ADD);
List ltdrop = getDiffsOfType(tableDiffs, ChangeType.DROP);
log.debug("ltadd-size: '"+ltadd.size()+"' ; ltdrop-size: '"+ltdrop.size()+"'");
if(ltadd.size()==0 || ltdrop.size()==0) {
return new ArrayList();
}
//if multiple renames, return ok if all that sim > minSim
List renames = new ArrayList();
for(TableDiff tadd: ltadd) {
for(TableDiff tdrop: ltdrop) {
double similarity = SimilarityCalculator.instance().similarity(tadd.getTable(), tdrop.getTable());
log.debug("t-add: '"+tadd.getNamedObject()+"' ; t-drop: '"+tdrop.getNamedObject()+"' ; sim: "+similarity);
if(similarity>=minSimilarity) {
renames.add(new RenameTuple(tadd, tdrop, similarity));
}
}
}
return renames;
}
static List detectColumnRenames(Collection columnDiffs, double minSimilarity) {
List lcadd = getDiffsOfType(columnDiffs, ChangeType.ADD);
List lcdrop = getDiffsOfType(columnDiffs, ChangeType.DROP);
log.debug("lcadd-size: '"+lcadd.size()+"' ; lcdrop-size: '"+lcdrop.size()+"'");
if(lcadd.size()==0 || lcdrop.size()==0) {
return new ArrayList();
}
Set colsAdded = new HashSet();
Set colsDropped = new HashSet();
List renames = new ArrayList();
for(int i=0;i=minSimilarity) {
log.debug("renamed; c-add: '"+cadd+"' ; c-drop: '"+cdrop+"' ; sim: "+similarity);
String cAddId = cadd.getNamedObject().getSchemaName()+"."+cadd.getNamedObject().getName()+"."+cadd.getColumn().getName();
String cDropId = cdrop.getNamedObject().getSchemaName()+"."+cdrop.getNamedObject().getName()+"."+cdrop.getPreviousColumn().getName();
if(!colsDropped.add(cDropId)) {
log.warn("column '"+cDropId+"' \"renamed-from\" multiple times");
}
if(!colsAdded.add(cAddId)) {
log.warn("column '"+cAddId+"' \"renamed-to\" multiple times");
}
renames.add(new RenameTuple(cadd, cdrop, similarity));
}
}
}
return renames;
}
static List detectDbIdRenames(Collection dbidDiffs, DBObjectType dbotype, double minSimilarity) {
List lIdAdd = getDiffsOfType(dbidDiffs, ChangeType.ADD);
List lIdDrop = getDiffsOfType(dbidDiffs, ChangeType.DROP);
log.debug("lIdAdd-size: '"+lIdAdd.size()+"' ; lIdDrop-size: '"+lIdDrop.size()+"'");
if(lIdAdd.size()==0 || lIdDrop.size()==0) {
return new ArrayList();
}
List renames = new ArrayList();
for(int i=0;i*/ diffs, List renames) {
for(RenameTuple rt: renames) {
boolean added = false;
int removedCount = 0;
if(rt.add instanceof TableDiff) {
TableDiff tdrename = new TableDiff(ChangeType.RENAME, (Table) rt.add.getNamedObject(), rt.drop.getNamedObject().getSchemaName(), rt.drop.getNamedObject().getName(), null);
added = diffs.add(tdrename);
//TODO add & drop columns!
}
else if(rt.add instanceof ColumnDiff) {
ColumnDiff cdrename = new ColumnDiff(ChangeType.RENAME, rt.add.getNamedObject(), ((ColumnDiff)rt.drop).getPreviousColumn(), ((ColumnDiff)rt.add).getColumn());
added = diffs.add(cdrename);
}
else if(rt.add instanceof DBIdentifiableDiff) {
DBIdentifiableDiff dff = (DBIdentifiableDiff) rt.add;
DBIdentifiableDiff idrename = new DBIdentifiableDiff(ChangeType.RENAME, (DBIdentifiable) rt.drop.getNamedObject(), (DBIdentifiable) rt.add.getNamedObject(), dff.getOwnerTableName());
added = diffs.add(idrename);
}
if(!added) { throw new RuntimeException("could not add rename: "+rt); }
removedCount += diffs.remove(rt.add)?1:0;
removedCount += diffs.remove(rt.drop)?1:0;
if(removedCount!=2) { throw new RuntimeException("could not remove add/drop diffs: "+rt); }
}
}
static void validateConflictingRenames(List renames) {
Set stadd = new HashSet();
Set stdrop = new HashSet();
for(RenameTuple rt: renames) {
//throw UndecidableRenameException ?
if(! stadd.add(rt.add)) {
throw new ConflictingChangesException("a table can't be renamed more than once [add table = '"+rt.add+"'; similarity = "+rt.similarity+"]");
}
if(! stdrop.add(rt.drop)) {
throw new ConflictingChangesException("a table can't be renamed more than once [drop table = '"+rt.drop+"'; similarity = "+rt.similarity+"]");
}
}
}
public static int detectAndDoTableRenames(Collection tableDiffs, double minSimilarity) {
//get renames
List renames = detectTableRenames(tableDiffs, minSimilarity);
//validate & do renames
return validateAndDoRenames(tableDiffs, renames, "table");
}
public static int detectAndDoColumnRenames(Collection columnDiffs, double minSimilarity) {
//get renames
List renames = detectColumnRenames(columnDiffs, minSimilarity);
//validate & do renames
return validateAndDoRenames(columnDiffs, renames, "column");
}
public static int detectAndDoIndexRenames(Collection dbIdDiffs, double minSimilarity) {
//get renames
List renames = detectDbIdRenames(dbIdDiffs, DBObjectType.INDEX, minSimilarity);
//validate & do renames
return validateAndDoRenames(dbIdDiffs, renames, "index");
}
public static int detectAndDoConstraintRenames(Collection dbIdDiffs, double minSimilarity) {
//get renames
List renames = detectDbIdRenames(dbIdDiffs, DBObjectType.CONSTRAINT, minSimilarity);
//validate & do renames
return validateAndDoRenames(dbIdDiffs, renames, "constraint");
}
static int validateAndDoRenames(Collection diffs, List renames, String diffType) {
if(renames.size()==0) {
log.info("no "+diffType+" renames detected");
}
else {
log.info(renames.size()+" "+diffType+" renames detected");
//validate renames
validateConflictingRenames(renames);
//do renames
doRenames(diffs, renames);
}
return renames.size();
}
static List getDiffsOfType(Collection difflist, ChangeType type) {
List ret = new ArrayList();
for(T d: difflist) {
if(d.getChangeType().equals(type)) {
ret.add(d);
}
}
return ret;
}
static boolean equalsApartFromName(DBIdentifiable o1, DBIdentifiable o2) {
if(o1 instanceof Index && o2 instanceof Index) {
Index i1 = (Index) o1;
Index i2 = (Index) o2;
if(i1.getColumns().equals(i2.getColumns())
&& i1.getLocal()==i2.getLocal()
&& i1.getReverse()==i2.getReverse()
&& i1.getIndexType()==i2.getIndexType()
&& i1.getTableName().equals(i2.getTableName())
&& ( (i1.getType()==null && i2.getType()==null) || i1.getType().equals(i2.getType()) )
&& i1.isUnique() == i2.isUnique()
) {
return true;
}
}
else if(o1 instanceof Constraint && o2 instanceof Constraint) {
Constraint c1 = (Constraint) o1;
Constraint c2 = (Constraint) o2;
if(c1.getType()==c2.getType()
&& c1.getUniqueColumns().equals(c2.getUniqueColumns())
&& ( (c1.getCheckDescription()==null && c2.getCheckDescription()==null) || c1.getCheckDescription().equals(c2.getCheckDescription()) )
) {
return true;
}
}
else if(DBIdentifiable.getType(o1)==DBIdentifiable.getType(o2)) {
log.warn("equalsApartFromName: unknown type: "+DBIdentifiable.getType(o1));
}
else {
log.debug("equalsApartFromName: incompatible types: "+DBIdentifiable.getType(o1)+", "+DBIdentifiable.getType(o2));
}
return false;
}
}