Revision: 3864
Author: [email protected]
Date: Tue Aug 10 13:58:36 2010
Log: Adding in a stop-gap solution for moving columns in a table with
snapshots.
The problem is moving a column causes a remove and an add. The remove will
cause the listener to update the use count of the snapshot to 0 in some
cases and remove the snapshot and UDT. When the column is added back in the
UDT upstream of the column proxy UDT the old snapshot is snapshotted and a
listener is attempted to be added to it as though it is a system snapshot
and causes an NPE.
Now the use count is only updated at the end of a transaction which works
for now because all moves happen in a transaction. A better solution would
involve merging the snapshot object with the snapshotted UDT.
http://code.google.com/p/power-architect/source/detail?r=3864
Modified:
/trunk/src/main/java/ca/sqlpower/architect/SPObjectSnapshotHierarchyListener.java
=======================================
---
/trunk/src/main/java/ca/sqlpower/architect/SPObjectSnapshotHierarchyListener.java
Tue Aug 10 09:28:49 2010
+++
/trunk/src/main/java/ca/sqlpower/architect/SPObjectSnapshotHierarchyListener.java
Tue Aug 10 13:58:36 2010
@@ -69,7 +69,20 @@
* type so that the event details can be used to create a
* new snapshot.
*/
- private Map<UserDefinedSQLType, PropertyChangeEvent>
upstreamTypeChangeEventMap = new HashMap<UserDefinedSQLType,
PropertyChangeEvent>();;
+ private Map<UserDefinedSQLType, PropertyChangeEvent>
upstreamTypeChangeEventMap = new HashMap<UserDefinedSQLType,
PropertyChangeEvent>();
+
+ /**
+ * Each type that needs to be cleaned up is mapped to a count of how
many
+ * times the clean up method should be called on it.
+ * <p>
+ * XXX This is a stop-gap for being able to move a column as a remove
and
+ * add since the column will be pointing at the snapshot and not a
system
+ * type. In the future we need to have the snapshot object override
+ * {...@link UserDefinedSQLType} so it is the same object. That change
will
+ * also simplify the model.
+ */
+ private final Map<UserDefinedSQLType, Integer> typesToCleanup =
+ new HashMap<UserDefinedSQLType, Integer>();
/**
* True if this listener is in the middle of
@@ -135,14 +148,24 @@
for (SQLColumn col :
e.getChild().getChildren(SQLColumn.class)) {
col.getUserDefinedSQLType().removeSPListener(this);
if
(col.getUserDefinedSQLType().isMagicEnabled()) {
-
cleanupSnapshot(col.getUserDefinedSQLType().getUpstreamType());
+ UserDefinedSQLType snapshotType =
col.getUserDefinedSQLType().getUpstreamType();
+ Integer cleanupCount =
typesToCleanup.get(snapshotType);
+ if (cleanupCount == null) {
+ cleanupCount = 0;
+ }
+ typesToCleanup.put(snapshotType,
cleanupCount + 1);
}
}
} else if (e.getChild() instanceof SQLColumn) {
UserDefinedSQLType colType = ((SQLColumn)
e.getChild()).getUserDefinedSQLType();
colType.removeSPListener(this);
if (colType.isMagicEnabled()) {
- cleanupSnapshot(colType.getUpstreamType());
+ UserDefinedSQLType snapshotType =
colType.getUpstreamType();
+ Integer cleanupCount = typesToCleanup.get(snapshotType);
+ if (cleanupCount == null) {
+ cleanupCount = 0;
+ }
+ typesToCleanup.put(snapshotType, cleanupCount + 1);
}
}
}
@@ -385,19 +408,16 @@
logger.debug("Ignoring begin");
return;
}
- if (e.getSource() instanceof UserDefinedSQLType) {
- logger.debug("Processing begin (\"" + e.getMessage() + "\")");
- UserDefinedSQLType udt = (UserDefinedSQLType) e.getSource();
- transactionCount++;
- logger.debug("Incremented transaction counter to " +
transactionCount);
- if (transactionCount == 1) {
- logger.debug("Firing snapshot begin");
- try {
- settingSnapshot = true;
- udt.begin("setting upstream type (snapshot)");
- } finally {
- settingSnapshot = false;
- }
+ logger.debug("Processing begin (\"" + e.getMessage() + "\")");
+ transactionCount++;
+ logger.debug("Incremented transaction counter to " +
transactionCount);
+ if (transactionCount == 1) {
+ logger.debug("Firing snapshot begin");
+ try {
+ settingSnapshot = true;
+ ((SPObject) e.getSource()).begin("setting upstream type
(snapshot)");
+ } finally {
+ settingSnapshot = false;
}
}
}
@@ -408,37 +428,40 @@
logger.debug("Ignoring commit");
return;
}
- if (e.getSource() instanceof UserDefinedSQLType) {
- logger.debug("Processing commit (\"" + e.getMessage() + "\")");
- UserDefinedSQLType udt = (UserDefinedSQLType) e.getSource();
-
- transactionCount--;
- logger.debug("Decremented transaction counter to " +
transactionCount);
- if (transactionCount == 0) {
- try {
- settingSnapshot = true;
- for (Entry<UserDefinedSQLType, PropertyChangeEvent>
entry : upstreamTypeChangeEventMap.entrySet()) {
- UserDefinedSQLType newValue = (UserDefinedSQLType)
entry.getValue().getNewValue();
- UserDefinedSQLType source = (UserDefinedSQLType)
entry.getKey();
- UserDefinedSQLType oldValue = (UserDefinedSQLType)
entry.getValue().getOldValue();
-
- logger.debug("Replacing upstreamType with
snapshot!");
- createSPObjectSnapshot(source, newValue);
-
- if (oldValue != null && source.isMagicEnabled()) {
- cleanupSnapshot(oldValue);
- }
-
- UserDefinedSQLType columnProxyType = source;
-
addUpdateListener(columnProxyType.getUpstreamType());
- }
- upstreamTypeChangeEventMap.clear();
- udt.commit("snapshot commit");
- logger.debug("Firing snapshot commit");
- } finally {
- settingSnapshot = false;
- }
- }
+ logger.debug("Processing commit (\"" + e.getMessage() + "\")");
+
+ transactionCount--;
+ logger.debug("Decremented transaction counter to " +
transactionCount);
+ if (transactionCount == 0) {
+ try {
+ settingSnapshot = true;
+ for (Entry<UserDefinedSQLType, PropertyChangeEvent>
entry : upstreamTypeChangeEventMap.entrySet()) {
+ UserDefinedSQLType newValue = (UserDefinedSQLType)
entry.getValue().getNewValue();
+ UserDefinedSQLType source = (UserDefinedSQLType)
entry.getKey();
+ UserDefinedSQLType oldValue = (UserDefinedSQLType)
entry.getValue().getOldValue();
+
+ logger.debug("Replacing upstreamType with snapshot!");
+ createSPObjectSnapshot(source, newValue);
+
+ if (oldValue != null && source.isMagicEnabled()) {
+ cleanupSnapshot(oldValue);
+ }
+
+ UserDefinedSQLType columnProxyType = source;
+ addUpdateListener(columnProxyType.getUpstreamType());
+ }
+ upstreamTypeChangeEventMap.clear();
+ ((SPObject) e.getSource()).commit("snapshot commit");
+ logger.debug("Firing snapshot commit");
+ } finally {
+ settingSnapshot = false;
+ }
+ for (Map.Entry<UserDefinedSQLType, Integer> entry :
typesToCleanup.entrySet()) {
+ for (int i = 0; i < entry.getValue(); i++) {
+ cleanupSnapshot(entry.getKey());
+ }
+ }
+ typesToCleanup.clear();
}
}
}