Author: jfuerth
Date: Fri Nov  7 13:17:00 2008
New Revision: 2831

Modified:
branches/release-0.9.12/regress/ca/sqlpower/architect/swingui/TestSwingUIProject.java
   branches/release-0.9.12/src/ca/sqlpower/architect/CoreProject.java
   branches/release-0.9.12/src/ca/sqlpower/architect/SQLIndex.java

Log:
Merged r2815 - Fixed Bug 1662: Indexes remain on tables even after columns removed


Modified: branches/release-0.9.12/regress/ca/sqlpower/architect/swingui/TestSwingUIProject.java
==============================================================================
--- branches/release-0.9.12/regress/ca/sqlpower/architect/swingui/TestSwingUIProject.java (original) +++ branches/release-0.9.12/regress/ca/sqlpower/architect/swingui/TestSwingUIProject.java Fri Nov 7 13:17:00 2008
@@ -28,6 +28,7 @@
 import java.io.PrintWriter;
 import java.sql.Connection;
 import java.sql.Types;
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -1218,5 +1219,40 @@
         SQLObjectRoot rootObject = session.getRootObject();
         SQLDatabase ppdb = (SQLDatabase) rootObject.getChild(0);
         assertTrue(ppdb.isPlayPenDatabase());
+    }
+
+    /**
+ * Regression test for bug 1662: after loading a project, all the indexes + * have to be listening to the columns folder of the table they belong to.
+     */
+    public void testIndexListensToColumnsAfterLoad() throws Exception {
+        testLoad();
+        SQLDatabase ppdb = session.getTargetDatabase();
+        SQLTable t = ppdb.getTableByName("mm_project");
+
+        // have to do the same check for every index, because (for example)
+        // the PK index didn't exhibit this problem
+        for (SQLIndex idx : new ArrayList<SQLIndex>(t.getIndices())) {
+
+            assertTrue(
+                    "didn't expect this index to have no columns!",
+                    idx.getChildCount() > 0);
+
+            List<SQLIndex.Column> indexCols = idx.getChildren();
+            List<SQLColumn> colsToRemove = new ArrayList<SQLColumn>();
+            for (SQLIndex.Column indexCol : indexCols) {
+                colsToRemove.add(indexCol.getColumn());
+            }
+
+            for (SQLColumn col : colsToRemove) {
+                t.removeColumn(col);
+            }
+
+            // prove the listener was hooked up
+            assertTrue(
+ "Index " + idx + " wasn't listening to columns folder!",
+                    idx.getChildCount() == 0);
+            assertFalse(t.getIndices().contains(idx));
+        }
     }
 }

Modified: branches/release-0.9.12/src/ca/sqlpower/architect/CoreProject.java
==============================================================================
--- branches/release-0.9.12/src/ca/sqlpower/architect/CoreProject.java (original) +++ branches/release-0.9.12/src/ca/sqlpower/architect/CoreProject.java Fri Nov 7 13:17:00 2008
@@ -365,7 +365,7 @@
         SQLFolderFactory folderFactory = new SQLFolderFactory();
         d.addFactoryCreate("*/folder", folderFactory);
         d.addSetProperties("*/folder");
-        d.addSetNext("*/folder", "addChild");
+        // the factory adds the folder to the table upon creation

         SQLColumnFactory columnFactory = new SQLColumnFactory();
         d.addFactoryCreate("*/column", columnFactory);
@@ -554,6 +554,14 @@
     }

     /**
+ * The table most recently loaded from the project file. The SQLFolderFactory + * has to know which table it's creating a folder for, because it has to add + * the folder upon creation instead of waiting for the digester to do it at the
+     * end of the enclosing table element.
+     */
+    private SQLTable currentTable;
+
+    /**
      * Creates a SQLTable instance and adds it to the objectIdMap.
      */
     private class SQLTableFactory extends AbstractObjectCreationFactory {
@@ -579,6 +587,7 @@
                 }
             }

+            currentTable = tab;
             return tab;
         }
     }
@@ -605,7 +614,17 @@
                             +typeStr+"\"");
                 }
             }
-            return new SQLTable.Folder(type, true);
+
+ // have to add folders right away because some stuff (for example, the SQLIndex constructor) + // requires that the folder's parent table is already linked up. It's done here because + // the Digester is incapable of doing this up front (see javadoc for CallMethodRule)
+            Folder f = new SQLTable.Folder(type, true);
+            try {
+                currentTable.addChild(f);
+            } catch (ArchitectException ex) {
+                throw new ArchitectRuntimeException(ex);
+            }
+            return f;
         }
     }


Modified: branches/release-0.9.12/src/ca/sqlpower/architect/SQLIndex.java
==============================================================================
--- branches/release-0.9.12/src/ca/sqlpower/architect/SQLIndex.java (original) +++ branches/release-0.9.12/src/ca/sqlpower/architect/SQLIndex.java Fri Nov 7 13:17:00 2008
@@ -454,17 +454,31 @@
     }

     /**
-     * Updates this index's parent reference.
-     *
-     *  @param parent must be a SQLTable.Folder instance.
+ * Updates this index's parent reference, and attaches a listener to the
+     * columns folder of the new parent's parent table.
+     *
+     * @param parent
+ * The new parent. Must be null or a SQLTable.Folder instance. If
+     *            it's a folder, it must already have a parent table.
+     * @throws IllegalStateException
+ * if the given parent is non-null and does not itself have a
+     *             parent table.
      */
     @Override
     protected void setParent(SQLObject parent) {
+
+        if (this.parent != null) {
+ getParentTable().getColumnsFolder().removeSQLObjectListener(removeColumnListener);
+        }
+
         this.parent = (Folder<SQLIndex>) parent;
-        if (this.parent != null && this.parent.getParent() != null) {
- this.parent.getParent().getColumnsFolder().addSQLObjectListener(removeColumnListener);
+
+        if (this.parent != null) {
+            if (getParentTable() == null) {
+ throw new IllegalStateException("Index folder is unparented!");
+            }
+ getParentTable().getColumnsFolder().addSQLObjectListener(removeColumnListener);
         }
-
     }

     /**

Reply via email to