001: /*
002: * IndexDiff.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.db.diff;
013:
014: import java.util.Collection;
015: import java.util.Collections;
016: import java.util.LinkedList;
017: import java.util.List;
018: import workbench.db.IndexDefinition;
019: import workbench.db.report.IndexReporter;
020: import workbench.db.report.TagWriter;
021: import workbench.util.StrBuffer;
022:
023: /**
024: * Compare two index definitions and create an XML
025: * representation of the differences.
026: *
027: * @author support@sql-workbench.net
028: */
029: public class IndexDiff {
030: public static final String TAG_MODIFY_INDEX = "modify-index";
031: public static final String TAG_ADD_INDEX = "add-index";
032: public static final String TAG_DROP_INDEX = "drop-index";
033:
034: private Collection<IndexDefinition> reference = Collections
035: .emptyList();
036: private Collection<IndexDefinition> target = Collections
037: .emptyList();
038: private TagWriter writer;
039: private StrBuffer indent;
040:
041: public IndexDiff(Collection<IndexDefinition> ref,
042: Collection<IndexDefinition> targ) {
043: if (ref != null)
044: this .reference = ref;
045: if (targ != null)
046: this .target = targ;
047: }
048:
049: public void setTagWriter(TagWriter w) {
050: this .writer = w;
051: }
052:
053: public void setIndent(StrBuffer ind) {
054: this .indent = ind;
055: }
056:
057: public StrBuffer getMigrateTargetXml() {
058: if (this .writer == null)
059: this .writer = new TagWriter();
060: StrBuffer result = new StrBuffer();
061: List<IndexDefinition> indexToAdd = new LinkedList<IndexDefinition>();
062: List<IndexDefinition> indexToDrop = new LinkedList<IndexDefinition>();
063: int count = this .reference.size();
064:
065: StrBuffer myindent = new StrBuffer(indent);
066: myindent.append(" ");
067:
068: StrBuffer idxIndent = new StrBuffer(myindent);
069: idxIndent.append(" ");
070:
071: for (IndexDefinition refIndex : reference) {
072: IndexDefinition ind = this .findIndexInTarget(refIndex
073: .getExpression());
074: if (ind == null) {
075: indexToAdd.add(refIndex);
076: } else {
077: boolean uniqueDiff = ind.isUnique() != refIndex
078: .isUnique();
079: boolean pkDiff = ind.isPrimaryKeyIndex() != refIndex
080: .isPrimaryKeyIndex();
081: boolean typeDiff = !(ind.getIndexType().equals(refIndex
082: .getIndexType()));
083:
084: if (uniqueDiff || pkDiff || typeDiff) {
085: writer.appendOpenTag(result, myindent,
086: TAG_MODIFY_INDEX, "name", ind.getName());
087: result.append('\n');
088: if (uniqueDiff) {
089: writer.appendTag(result, idxIndent,
090: IndexReporter.TAG_INDEX_UNIQUE,
091: refIndex.isUnique());
092: }
093: if (pkDiff) {
094: writer.appendTag(result, idxIndent,
095: IndexReporter.TAG_INDEX_PK, refIndex
096: .isPrimaryKeyIndex());
097: }
098: if (pkDiff) {
099: writer.appendTag(result, idxIndent,
100: IndexReporter.TAG_INDEX_TYPE, refIndex
101: .getIndexType());
102: }
103: writer.appendCloseTag(result, myindent,
104: TAG_MODIFY_INDEX);
105: }
106: }
107: }
108:
109: for (IndexDefinition targetIndex : target) {
110: String expr = targetIndex.getExpression();
111: IndexDefinition ind = this .findIndexInReference(expr);
112: if (ind == null) {
113: indexToDrop.add(targetIndex);
114: }
115: }
116:
117: if (indexToAdd.size() > 0) {
118: writer.appendOpenTag(result, myindent, TAG_ADD_INDEX);
119: result.append('\n');
120: for (IndexDefinition idx : indexToAdd) {
121: IndexReporter rep = new IndexReporter(idx);
122: rep.appendXml(result, idxIndent);
123: }
124: writer.appendCloseTag(result, myindent, TAG_ADD_INDEX);
125: }
126:
127: if (indexToDrop.size() > 0) {
128: for (IndexDefinition idx : indexToDrop) {
129: writer.appendTag(result, myindent, TAG_DROP_INDEX, idx
130: .getName());
131: }
132: }
133: return result;
134: }
135:
136: private IndexDefinition findIndexInTarget(String expr) {
137: return findIndex(target, expr);
138: }
139:
140: private IndexDefinition findIndexInReference(String expr) {
141: return findIndex(reference, expr);
142: }
143:
144: private IndexDefinition findIndex(Collection<IndexDefinition> defs,
145: String expr) {
146: for (IndexDefinition idx : defs) {
147: if (idx.equals(expr))
148: return idx;
149: }
150: return null;
151: }
152: }
|