You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ddlutils-dev@db.apache.org by to...@apache.org on 2006/03/02 23:46:17 UTC
svn commit: r382539 - in /db/ddlutils/trunk/src/java/org/apache/ddlutils:
model/ForeignKey.java model/Reference.java model/Table.java
platform/SqlBuilder.java
Author: tomdz
Date: Thu Mar 2 14:46:16 2006
New Revision: 382539
URL: http://svn.apache.org/viewcvs?rev=382539&view=rev
Log:
Enhanced foreign key change detection when altering tables
Modified:
db/ddlutils/trunk/src/java/org/apache/ddlutils/model/ForeignKey.java
db/ddlutils/trunk/src/java/org/apache/ddlutils/model/Reference.java
db/ddlutils/trunk/src/java/org/apache/ddlutils/model/Table.java
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/SqlBuilder.java
Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/model/ForeignKey.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/model/ForeignKey.java?rev=382539&r1=382538&r2=382539&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/model/ForeignKey.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/model/ForeignKey.java Thu Mar 2 14:46:16 2006
@@ -16,6 +16,7 @@
* limitations under the License.
*/
+import java.util.HashSet;
import java.util.Iterator;
import org.apache.commons.collections.set.ListOrderedSet;
@@ -247,6 +248,48 @@
.append(_foreignTableName, other._foreignTableName)
.append(_references, other._references)
.isEquals();
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Compares this foreign key to the given one while ignoring the case of identifiers.
+ *
+ * @param otherFk The other foreign key
+ */
+ public boolean equalsIgnoreCase(ForeignKey otherFk)
+ {
+ if (_name.equalsIgnoreCase(otherFk._name) &&
+ _foreignTableName.equalsIgnoreCase(otherFk._foreignTableName))
+ {
+ HashSet otherRefs = new HashSet();
+
+ otherRefs.addAll(otherFk._references);
+ for (Iterator it = _references.iterator(); it.hasNext();)
+ {
+ Reference curLocalRef = (Reference)it.next();
+ boolean found = false;
+
+ for (Iterator otherIt = otherRefs.iterator(); otherIt.hasNext();)
+ {
+ Reference curOtherRef = (Reference)otherIt.next();
+
+ if (curLocalRef.equalsIgnoreCase(curOtherRef))
+ {
+ otherIt.remove();
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ {
+ return false;
+ }
+ }
+ return otherRefs.isEmpty();
}
else
{
Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/model/Reference.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/model/Reference.java?rev=382539&r1=382538&r2=382539&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/model/Reference.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/model/Reference.java Thu Mar 2 14:46:16 2006
@@ -208,6 +208,18 @@
}
/**
+ * Compares this reference to the given one while ignoring the case of identifiers.
+ *
+ * @param otherRef The other reference
+ */
+ public boolean equalsIgnoreCase(Reference otherRef)
+ {
+ return (otherRef != null) &&
+ _localColumnName.equalsIgnoreCase(otherRef._localColumnName) &&
+ _foreignColumnName.equalsIgnoreCase(otherRef._foreignColumnName);
+ }
+
+ /**
* {@inheritDoc}
*/
public int hashCode()
Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/model/Table.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/model/Table.java?rev=382539&r1=382538&r2=382539&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/model/Table.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/model/Table.java Thu Mar 2 14:46:16 2006
@@ -604,6 +604,28 @@
}
/**
+ * Finds the foreign key in this table that is equal to the supplied foreign key.
+ *
+ * @param key The foreign key to search for
+ * @param caseSensitive Whether case matters for the names
+ * @return The found foreign key
+ */
+ public ForeignKey findForeignKey(ForeignKey key, boolean caseSensitive)
+ {
+ for (int idx = 0; idx < getForeignKeyCount(); idx++)
+ {
+ ForeignKey fk = getForeignKey(idx);
+
+ if ((caseSensitive && fk.equals(key)) ||
+ (!caseSensitive && fk.equalsIgnoreCase(key)))
+ {
+ return fk;
+ }
+ }
+ return null;
+ }
+
+ /**
* Returns the primary key columns of this table.
*
* @return The primary key columns
Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/SqlBuilder.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/SqlBuilder.java?rev=382539&r1=382538&r2=382539&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/SqlBuilder.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/SqlBuilder.java Thu Mar 2 14:46:16 2006
@@ -26,6 +26,7 @@
import java.util.Locale;
import java.util.Map;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.ListOrderedMap;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
@@ -37,6 +38,7 @@
import org.apache.ddlutils.model.ForeignKey;
import org.apache.ddlutils.model.Index;
import org.apache.ddlutils.model.IndexColumn;
+import org.apache.ddlutils.model.Reference;
import org.apache.ddlutils.model.Table;
import org.apache.ddlutils.model.TypeMap;
@@ -429,7 +431,7 @@
for (int columnIdx = 0; columnIdx < desiredTable.getColumnCount(); columnIdx++)
{
Column desiredColumn = desiredTable.getColumn(columnIdx);
- Column currentColumn = currentTable.findColumn(desiredColumn.getName());
+ Column currentColumn = currentTable.findColumn(desiredColumn.getName(), getPlatformInfo().isUseDelimitedIdentifiers());
if (null == currentColumn)
{
@@ -468,7 +470,7 @@
for (int fkIdx = 0; fkIdx < desiredTable.getForeignKeyCount(); fkIdx++)
{
ForeignKey desiredFk = desiredTable.getForeignKey(fkIdx);
- ForeignKey currentFk = currentTable.findForeignKey(desiredFk);
+ ForeignKey currentFk = findCorrespondingForeignKey(currentTable, desiredFk);
if (currentFk == null)
{
@@ -485,7 +487,7 @@
for (int indexIdx = 0; indexIdx < desiredTable.getIndexCount(); indexIdx++)
{
Index desiredIndex = desiredTable.getIndex(indexIdx);
- Index currentIndex = currentTable.findIndex(desiredIndex.getName());
+ Index currentIndex = currentTable.findIndex(desiredIndex.getName(), getPlatformInfo().isUseDelimitedIdentifiers());
if (currentIndex == null)
{
@@ -501,7 +503,7 @@
for (int fkIdx = 0; fkIdx < currentTable.getForeignKeyCount(); fkIdx++)
{
ForeignKey currentFk = currentTable.getForeignKey(fkIdx);
- ForeignKey desiredFk = desiredTable.findForeignKey(currentFk);
+ ForeignKey desiredFk = findCorrespondingForeignKey(desiredTable, currentFk);
if (desiredFk == null)
{
@@ -521,7 +523,7 @@
for (int columnIdx = 0; columnIdx < currentTable.getColumnCount(); columnIdx++)
{
Column currentColumn = currentTable.getColumn(columnIdx);
- Column desiredColumn = desiredTable.findColumn(currentColumn.getName());
+ Column desiredColumn = desiredTable.findColumn(currentColumn.getName(), getPlatformInfo().isUseDelimitedIdentifiers());
if (desiredColumn == null)
{
@@ -550,7 +552,7 @@
for (int indexIdx = 0; indexIdx < currentTable.getIndexCount(); indexIdx++)
{
Index currentIndex = currentTable.getIndex(indexIdx);
- Index desiredIndex = desiredTable.findIndex(currentIndex.getName());
+ Index desiredIndex = desiredTable.findIndex(currentIndex.getName(), getPlatformInfo().isUseDelimitedIdentifiers());
if (desiredIndex == null)
{
@@ -582,8 +584,80 @@
}
}
+ }
+
+ /**
+ * Searches in the given table for a corresponding foreign key. If the given key
+ * has no name, then a foreign key to the same table with the same columns in the
+ * same order is searched. If the given key has a name, then the a corresponding
+ * key also needs to have the same name, or no name at all, but not a different one.
+ *
+ * @param table The table to search in
+ * @param fk The original foreign key
+ * @return The corresponding foreign key if found
+ */
+ protected ForeignKey findCorrespondingForeignKey(Table table, ForeignKey fk)
+ {
+ boolean caseMatters = getPlatformInfo().isUseDelimitedIdentifiers();
+ boolean checkFkName = (fk.getName() != null) && (fk.getName().length() > 0);
+ Reference[] refs = fk.getReferences();
+ ArrayList curRefs = new ArrayList();
+
+ for (int fkIdx = 0; fkIdx < table.getForeignKeyCount(); fkIdx++)
+ {
+ ForeignKey curFk = table.getForeignKey(fkIdx);
+ boolean checkCurFkName = checkFkName &&
+ (curFk.getName() != null) && (curFk.getName().length() > 0);
+
+ if ((!checkCurFkName || areEqual(fk.getName(), curFk.getName(), caseMatters)) &&
+ areEqual(fk.getForeignTableName(), curFk.getForeignTableName(), caseMatters))
+ {
+ curRefs.clear();
+ CollectionUtils.addAll(curRefs, curFk.getReferences());
+
+ // the order is not fixed, so we have to take this long way
+ if (curRefs.size() == refs.length)
+ {
+ for (int refIdx = 0; refIdx < refs.length; refIdx++)
+ {
+ boolean found = false;
+
+ for (int curRefIdx = 0; !found && (curRefIdx < curRefs.size()); curRefIdx++)
+ {
+ Reference curRef = (Reference)curRefs.get(curRefIdx);
+
+ if ((caseMatters && refs[refIdx].equals(curRef)) ||
+ (!caseMatters && refs[refIdx].equalsIgnoreCase(curRef)))
+ {
+ curRefs.remove(curRefIdx);
+ found = true;
+ }
+ }
+ }
+ if (curRefs.isEmpty())
+ {
+ return curFk;
+ }
+ }
+ }
+ }
+ return null;
}
-
+
+ /**
+ * Compares the two strings.
+ *
+ * @param string1 The first string
+ * @param string2 The second string
+ * @param caseMatters Whether case matters in the comparison
+ * @return <code>true</code> if the string are equal
+ */
+ protected boolean areEqual(String string1, String string2, boolean caseMatters)
+ {
+ return (caseMatters && string1.equals(string2)) ||
+ (!caseMatters && string1.equalsIgnoreCase(string2));
+ }
+
/**
* Outputs the DDL to create the table along with any non-external constraints as well
* as with external primary keys and indices (but not foreign keys).
@@ -1364,7 +1438,8 @@
String desiredDefault = desiredColumn.getDefaultValue();
String currentDefault = currentColumn.getDefaultValue();
boolean defaultsEqual = (desiredDefault == null) || desiredDefault.equals(currentDefault);
- boolean sizeMatters = getPlatformInfo().hasSize(currentColumn.getTypeCode());
+ boolean sizeMatters = getPlatformInfo().hasSize(currentColumn.getTypeCode()) &&
+ (desiredColumn.getSize() != null);
// We're comparing the jdbc type that corresponds to the native type for the
// desired type, in order to avoid repeated altering of a perfectly valid column