Revision: 6451
http://squirrel-sql.svn.sourceforge.net/squirrel-sql/?rev=6451&view=rev
Author: wis775
Date: 2011-10-07 20:00:25 +0000 (Fri, 07 Oct 2011)
Log Message:
-----------
Some performance improvements, when searching in the object tree.
Now, Squirrel will not try to expand a node twice, if no children were found by the expander.
Modified Paths:
--------------
trunk/sql12/app/src/main/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/ObjectTree.java
trunk/sql12/app/src/main/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/ObjectTreeModel.java
trunk/sql12/app/src/main/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/ObjectTreeNode.java
trunk/sql12/doc/src/main/resources/changes.txt
Added Paths:
-----------
trunk/sql12/app/src/main/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/TreeLoader.java
trunk/sql12/app/src/test/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/ObjectTreeModelTest.java
trunk/sql12/app/src/test/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/TreeLoaderTest.java
Modified: trunk/sql12/app/src/main/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/ObjectTree.java
===================================================================
--- trunk/sql12/app/src/main/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/ObjectTree.java 2011-10-03 23:59:25 UTC (rev 6450)
+++ trunk/sql12/app/src/main/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/ObjectTree.java 2011-10-07 20:00:25 UTC (rev 6451)
@@ -21,7 +21,6 @@
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.Serializable;
-import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
@@ -61,7 +60,6 @@
import net.sourceforge.squirrel_sql.fw.gui.CursorChanger;
import net.sourceforge.squirrel_sql.fw.gui.GUIUtils;
import net.sourceforge.squirrel_sql.fw.id.IIdentifier;
-import net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectInfo;
import net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectType;
import net.sourceforge.squirrel_sql.fw.sql.IDatabaseObjectInfo;
import net.sourceforge.squirrel_sql.fw.sql.ITableInfo;
@@ -544,7 +542,7 @@
throw new IllegalArgumentException("ObjectTreeNode == null");
}
// If node hasn't already been expanded.
- if (node.getChildCount() == 0)
+ if (node.getChildCount() == 0 && node.hasNoChildrenFoundWithExpander() == false)
{
// Add together the standard expanders for this node type and any
// individual expanders that there are for the node and process them.
@@ -569,7 +567,7 @@
System.arraycopy(extraExpanders, 0, expanders, stdExpanders.length,
extraExpanders.length);
}
- new TreeLoader(node, expanders, selectNode).execute();
+ new TreeLoader(this._session, this, this._model, node, expanders, selectNode).execute();
}
}
}
@@ -957,133 +955,4 @@
}
}
}
-
- /**
- * This class actually loads the tree.
- */
- private final class TreeLoader
- {
- private ObjectTreeNode _parentNode;
- private INodeExpander[] _expanders;
- private boolean _selectParentNode;
-
- TreeLoader(ObjectTreeNode parentNode, INodeExpander[] expanders,
- boolean selectParentNode)
- {
- super();
- _parentNode = parentNode;
- _expanders = expanders;
- _selectParentNode= selectParentNode;
- }
-
- void execute()
- {
- try
- {
- try
- {
- ObjectTreeNode loadingNode = showLoadingNode();
- try
- {
- loadChildren();
- }
- finally
- {
- if (_parentNode.isNodeChild(loadingNode)){
- _parentNode.remove(loadingNode);
- }
- }
- }
- finally
- {
- fireStructureChanged(_parentNode);
- if (_selectParentNode)
- {
- clearSelection();
- setSelectionPath(new TreePath(_parentNode.getPath()));
- }
- }
- }
- catch (Throwable ex)
- {
- final String msg = "Error: " + _parentNode.toString();
- s_log.error(msg, ex);
- _session.showErrorMessage(msg + ": " + ex.toString());
- }
- }
-
- /**
- * This adds a node to the tree that says "Loading..." in order to give
- * feedback to the user.
- */
- private ObjectTreeNode showLoadingNode()
- {
- IDatabaseObjectInfo doi = new DatabaseObjectInfo(null, null,
- "Loading...", DatabaseObjectType.OTHER,
- _session.getSQLConnection().getSQLMetaData());
- ObjectTreeNode loadingNode = new ObjectTreeNode(_session, doi);
- _parentNode.add(loadingNode);
- fireStructureChanged(_parentNode);
- return loadingNode;
- }
-
- /**
- * This expands the parent node and shows all its children.
- */
- private void loadChildren() throws SQLException
- {
- for (int i = 0; i < _expanders.length; ++i)
- {
- boolean nodeTypeAllowsChildren = false;
- DatabaseObjectType lastDboType = null;
- List<ObjectTreeNode> list = _expanders[i].createChildren(_session, _parentNode);
- Iterator<ObjectTreeNode> it = list.iterator();
- while (it.hasNext())
- {
- Object nextObj = it.next();
- if (nextObj instanceof ObjectTreeNode)
- {
- ObjectTreeNode childNode = (ObjectTreeNode)nextObj;
- if (childNode.getExpanders().length >0)
- {
- childNode.setAllowsChildren(true);
- }
- else
- {
- DatabaseObjectType childNodeDboType = childNode.getDatabaseObjectType();
- if (childNodeDboType != lastDboType)
- {
- getTypedModel().addKnownDatabaseObjectType(childNodeDboType);
- lastDboType = childNodeDboType;
- if (_model.getExpanders(childNodeDboType).length > 0)
- {
- nodeTypeAllowsChildren = true;
- }
- else
- {
- nodeTypeAllowsChildren = false;
- }
- }
- childNode.setAllowsChildren(nodeTypeAllowsChildren);
- }
- _parentNode.add(childNode);
- }
- }
- }
- }
-
- /**
- * Let the object tree model know that its structure has changed.
- */
- private void fireStructureChanged(final ObjectTreeNode node)
- {
- GUIUtils.processOnSwingEventThread(new Runnable()
- {
- public void run()
- {
- ObjectTree.this._model.nodeStructureChanged(node);
- }
- });
- }
- }
}
Modified: trunk/sql12/app/src/main/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/ObjectTreeModel.java
===================================================================
--- trunk/sql12/app/src/main/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/ObjectTreeModel.java 2011-10-03 23:59:25 UTC (rev 6450)
+++ trunk/sql12/app/src/main/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/ObjectTreeModel.java 2011-10-07 20:00:25 UTC (rev 6451)
@@ -279,11 +279,10 @@
}
else
{
- if(useExpanders && 0 == startNode.getChildCount())
+ if(useExpanders && startNode.getAllowsChildren() && 0 == startNode.getChildCount() && startNode.hasNoChildrenFoundWithExpander() == false)
{
INodeExpander[] expanders = getExpanders(startNode.getDatabaseObjectType());
-
for (int i = 0; i < expanders.length; i++)
{
try
@@ -291,19 +290,23 @@
List<ObjectTreeNode> children =
expanders[i].createChildren(startNode.getSession(), startNode);
- for (int j = 0; j < children.size(); j++)
- {
- ObjectTreeNode newChild = children.get(j);
- if(0 == getExpanders(newChild.getDatabaseObjectType()).length)
- {
- newChild.setAllowsChildren(false);
- }
- else
- {
- newChild.setAllowsChildren(true);
- }
+ if(children.isEmpty()){
+ startNode.setNoChildrenFoundWithExpander(true);
+ }else{
+ for (int j = 0; j < children.size(); j++)
+ {
+ ObjectTreeNode newChild = children.get(j);
+ if(0 == getExpanders(newChild.getDatabaseObjectType()).length)
+ {
+ newChild.setAllowsChildren(false);
+ }
+ else
+ {
+ newChild.setAllowsChildren(true);
+ }
- startNode.add(newChild);
+ startNode.add(newChild);
+ }
}
}
catch (Exception e)
Modified: trunk/sql12/app/src/main/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/ObjectTreeNode.java
===================================================================
--- trunk/sql12/app/src/main/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/ObjectTreeNode.java 2011-10-03 23:59:25 UTC (rev 6450)
+++ trunk/sql12/app/src/main/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/ObjectTreeNode.java 2011-10-07 20:00:25 UTC (rev 6451)
@@ -56,6 +56,8 @@
/** Collection of <TT>INodeExpander</TT> objects for this node. */
private final List<INodeExpander> _expanders = new ArrayList<INodeExpander>();
+
+ private boolean noChildrenFoundWithExpander = false;
/**
* Ctor that assumes node cannot have children.
@@ -189,4 +191,18 @@
{
return _dboInfo.getDatabaseObjectType().getIcon();
}
+
+/**
+ * @return the noChildrenFoundWithExpander
+ */
+public boolean hasNoChildrenFoundWithExpander() {
+ return noChildrenFoundWithExpander;
}
+
+/**
+ * @param noChildrenFoundWithExpander the noChildrenFoundWithExpander to set
+ */
+public void setNoChildrenFoundWithExpander(boolean noChildrenFoundWithExpander) {
+ this.noChildrenFoundWithExpander = noChildrenFoundWithExpander;
+}
+}
Added: trunk/sql12/app/src/main/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/TreeLoader.java
===================================================================
--- trunk/sql12/app/src/main/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/TreeLoader.java (rev 0)
+++ trunk/sql12/app/src/main/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/TreeLoader.java 2011-10-07 20:00:25 UTC (rev 6451)
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2002-2004 Colin Bell
+ * co...@us...
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write toS the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree;
+
+import java.sql.SQLException;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.swing.tree.TreePath;
+
+import net.sourceforge.squirrel_sql.client.session.ISession;
+import net.sourceforge.squirrel_sql.fw.gui.GUIUtils;
+import net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectInfo;
+import net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectType;
+import net.sourceforge.squirrel_sql.fw.sql.IDatabaseObjectInfo;
+import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
+import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
+
+/**
+ * This class actually loads the tree.
+ * Note: This class was extracted from {@link ObjectTree} to make it more testable.
+ */
+public class TreeLoader
+{
+
+ /** Logger for this class. */
+ private static final ILogger s_log =
+ LoggerController.createLogger(TreeLoader.class);
+
+ private ObjectTree objectTree;
+ private ObjectTreeNode _parentNode;
+ private INodeExpander[] _expanders;
+ private boolean _selectParentNode;
+ private ObjectTreeModel model;
+ private ISession session;
+
+ TreeLoader(ISession session, ObjectTree objectTree, ObjectTreeModel model, ObjectTreeNode parentNode, INodeExpander[] expanders,
+ boolean selectParentNode)
+ {
+ super();
+ this.session = session;
+ this.objectTree = objectTree;
+ this.model = model;
+ _parentNode = parentNode;
+ _expanders = expanders;
+ _selectParentNode= selectParentNode;
+ }
+
+ void execute()
+ {
+ try
+ {
+ try
+ {
+ ObjectTreeNode loadingNode = showLoadingNode();
+ try
+ {
+ loadChildren();
+ }
+ finally
+ {
+ if (_parentNode.isNodeChild(loadingNode)){
+ _parentNode.remove(loadingNode);
+ }
+ }
+ }
+ finally
+ {
+ fireStructureChanged(_parentNode);
+ if (_selectParentNode)
+ {
+ this.objectTree.clearSelection();
+ this.objectTree.setSelectionPath(new TreePath(_parentNode.getPath()));
+ }
+ }
+ }
+ catch (Throwable ex)
+ {
+ final String msg = "Error: " + _parentNode.toString();
+ s_log.error(msg, ex);
+ this.session.showErrorMessage(msg + ": " + ex.toString());
+ }
+ }
+
+ /**
+ * This adds a node to the tree that says "Loading..." in order to give
+ * feedback to the user.
+ */
+ private ObjectTreeNode showLoadingNode()
+ {
+ IDatabaseObjectInfo doi = new DatabaseObjectInfo(null, null,
+ "Loading...", DatabaseObjectType.OTHER,
+ this.session.getSQLConnection().getSQLMetaData());
+ ObjectTreeNode loadingNode = new ObjectTreeNode(this.session, doi);
+ _parentNode.add(loadingNode);
+ fireStructureChanged(_parentNode);
+ return loadingNode;
+ }
+
+ /**
+ * This expands the parent node and shows all its children.
+ */
+ private void loadChildren() throws SQLException
+ {
+ boolean noChildrenFound = true;
+ for (int i = 0; i < _expanders.length; ++i)
+ {
+ boolean nodeTypeAllowsChildren = false;
+ DatabaseObjectType lastDboType = null;
+ List<ObjectTreeNode> list = _expanders[i].createChildren(this.session, _parentNode);
+
+ if(list.isEmpty() == false){
+ noChildrenFound = false;
+ }
+
+ Iterator<ObjectTreeNode> it = list.iterator();
+ while (it.hasNext())
+ {
+ Object nextObj = it.next();
+ if (nextObj instanceof ObjectTreeNode)
+ {
+ ObjectTreeNode childNode = (ObjectTreeNode)nextObj;
+ if (childNode.getExpanders().length >0)
+ {
+ childNode.setAllowsChildren(true);
+ }
+ else
+ {
+ DatabaseObjectType childNodeDboType = childNode.getDatabaseObjectType();
+ if (childNodeDboType != lastDboType)
+ {
+ this.objectTree.getTypedModel().addKnownDatabaseObjectType(childNodeDboType);
+ lastDboType = childNodeDboType;
+ if (this.model.getExpanders(childNodeDboType).length > 0)
+ {
+ nodeTypeAllowsChildren = true;
+ }
+ else
+ {
+ nodeTypeAllowsChildren = false;
+ }
+ }
+ childNode.setAllowsChildren(nodeTypeAllowsChildren);
+ }
+ _parentNode.add(childNode);
+ }
+ }
+ }
+
+ // We cann't use getChildCount, because the node has a temporary child called "Loading..."
+ _parentNode.setNoChildrenFoundWithExpander(noChildrenFound);
+ }
+
+ /**
+ * Let the object tree model know that its structure has changed.
+ */
+ private void fireStructureChanged(final ObjectTreeNode node)
+ {
+ GUIUtils.processOnSwingEventThread(new Runnable()
+ {
+ public void run()
+ {
+ model.nodeStructureChanged(node);
+ }
+ });
+ }
+}
\ No newline at end of file
Property changes on: trunk/sql12/app/src/main/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/TreeLoader.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/sql12/app/src/test/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/ObjectTreeModelTest.java
===================================================================
--- trunk/sql12/app/src/test/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/ObjectTreeModelTest.java (rev 0)
+++ trunk/sql12/app/src/test/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/ObjectTreeModelTest.java 2011-10-07 20:00:25 UTC (rev 6451)
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2011 Stefan Willinger
+ * wi...@us...
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree;
+
+import static org.easymock.classextension.EasyMock.expect;
+
+import java.util.ArrayList;
+
+import javax.swing.tree.TreePath;
+
+import org.easymock.classextension.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import net.sourceforge.squirrel_sql.BaseSQuirreLTestCase;
+import net.sourceforge.squirrel_sql.client.AppTestUtil;
+import net.sourceforge.squirrel_sql.client.session.ISession;
+import net.sourceforge.squirrel_sql.client.session.SessionManager;
+import net.sourceforge.squirrel_sql.client.session.schemainfo.FilterMatcher;
+import net.sourceforge.squirrel_sql.fw.FwTestUtil;
+import net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectType;
+import net.sourceforge.squirrel_sql.fw.sql.IDatabaseObjectInfo;
+
+/**
+ * Some Tests about the ObjectTreeModel.
+ * @author Stefan Willinger
+ *
+ */
+public class ObjectTreeModelTest extends BaseSQuirreLTestCase {
+
+ private ISession session = null;
+ private ObjectTreeModel classUnderTest = null;
+ private IDatabaseObjectInfo mockDbInfo = null;
+
+ @Before
+ protected void setUp() throws Exception {
+ super.setUp();
+ session = AppTestUtil.getEasyMockSession("Oracle");
+ classUnderTest = new ObjectTreeModel(session);
+
+ SessionManager mockSessionManager = session.getApplication().getSessionManager();
+
+ // redefine the mockSessionManager, to know our mockSession.
+ EasyMock.resetToDefault(mockSessionManager);
+ EasyMock.expect(mockSessionManager.getSession(session.getIdentifier())).andReturn(session).anyTimes();
+ EasyMock.replay(mockSessionManager);
+
+ mockDbInfo =
+ FwTestUtil.getEasyMockDatabaseObjectInfo("catalog",
+ "schema",
+ "table",
+ "schema.table",
+ DatabaseObjectType.TABLE);
+ }
+
+ @After
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ /**
+ * Ensure, that the expander is not called twice to fetch the children, if no children exists.
+ */
+ @Test
+ public void testPathToDBInfo_NoChildrensFoundByExpander() throws Exception {
+
+ ObjectTreeNode node = new ObjectTreeNode(session, mockDbInfo);
+
+ INodeExpander mockExpander = EasyMock.createMock(INodeExpander.class);
+ // Simulate, that a expander didn't find any children.
+ expect(mockExpander.createChildren(session, node)).andReturn(new ArrayList<ObjectTreeNode>());
+
+ EasyMock.replay(mockExpander);
+
+ classUnderTest.addExpander(node.getDatabaseObjectType(), mockExpander);
+ FilterMatcher matcher = new FilterMatcher("xy", null);
+ TreePath treePath = classUnderTest.getPathToDbInfo(mockDbInfo.getCatalogName(), mockDbInfo.getSchemaName(), matcher , node, true);
+ assertNull(treePath);
+ // after the first call, the node must know, that expanders didn't find any children.
+ assertTrue(node.hasNoChildrenFoundWithExpander());
+
+ // Try it a second time.
+ treePath = classUnderTest.getPathToDbInfo(mockDbInfo.getCatalogName(), mockDbInfo.getSchemaName(), matcher , node, true);
+ assertNull(treePath);
+
+ // Verify, that the expander is only called once.
+ EasyMock.verify(mockExpander);
+
+ }
+
+ /**
+ * Ensure, that the expander is not called, if the node is already marked with "NoChildrenFoundWithExpander".
+ */
+ @Test
+ public void testPathToDBInfo_AlreadyNoChildrensFoundByExpander() throws Exception {
+
+
+ ObjectTreeNode node = new ObjectTreeNode(session, mockDbInfo);
+ node.setNoChildrenFoundWithExpander(true);
+
+ INodeExpander mockExpander = EasyMock.createMock(INodeExpander.class);
+ EasyMock.replay(mockExpander);
+
+ classUnderTest.addExpander(node.getDatabaseObjectType(), mockExpander);
+ FilterMatcher matcher = new FilterMatcher("xy", null);
+ TreePath treePath = classUnderTest.getPathToDbInfo(mockDbInfo.getCatalogName(), mockDbInfo.getSchemaName(), matcher , node, true);
+ assertNull(treePath);
+
+ treePath = classUnderTest.getPathToDbInfo(mockDbInfo.getCatalogName(), mockDbInfo.getSchemaName(), matcher , node, true);
+ assertNull(treePath);
+
+ // Verify, that the expander is not called
+ EasyMock.verify(mockExpander);
+
+ }
+}
Property changes on: trunk/sql12/app/src/test/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/ObjectTreeModelTest.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/sql12/app/src/test/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/TreeLoaderTest.java
===================================================================
--- trunk/sql12/app/src/test/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/TreeLoaderTest.java (rev 0)
+++ trunk/sql12/app/src/test/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/TreeLoaderTest.java 2011-10-07 20:00:25 UTC (rev 6451)
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2011 Stefan Willinger
+ * wi...@us...
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree;
+
+import static org.easymock.EasyMock.expect;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.squirrel_sql.BaseSQuirreLTestCase;
+import net.sourceforge.squirrel_sql.client.AppTestUtil;
+import net.sourceforge.squirrel_sql.client.session.ISession;
+import net.sourceforge.squirrel_sql.fw.FwTestUtil;
+import net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectType;
+import net.sourceforge.squirrel_sql.fw.sql.IDatabaseObjectInfo;
+import net.sourceforge.squirrel_sql.fw.sql.ISQLConnection;
+import net.sourceforge.squirrel_sql.fw.sql.SQLDatabaseMetaData;
+
+import org.easymock.classextension.EasyMock;
+import org.junit.Before;
+
+/**
+ * @author Stefan Willinger
+ *
+ */
+public class TreeLoaderTest extends BaseSQuirreLTestCase {
+ private ISession mockSession = null;
+ private IDatabaseObjectInfo mockDbInfo = null;
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Before
+ public void setUp() throws Exception {
+ mockSession = AppTestUtil.getEasyMockSession("Oracle");
+ mockDbInfo = FwTestUtil.getEasyMockDatabaseObjectInfo("catalog", "schema", "table", "schema.table",
+ DatabaseObjectType.TABLE);
+ }
+
+ /**
+ * Ensure, that a node is marked with"NoChildrenFoundWithExpander" if a
+ * expander didn't find any children for this node.
+ */
+ public void testNoChildrenFoundByExpander() throws Exception {
+
+ ObjectTreeNode node = new ObjectTreeNode(mockSession, mockDbInfo);
+
+ INodeExpander mockExpander = EasyMock.createMock(INodeExpander.class);
+ // Simulate, that a expander didn't find any children.
+ expect(mockExpander.createChildren(mockSession, node)).andReturn(new ArrayList<ObjectTreeNode>());
+
+ // redefine the mockConnection
+ ISQLConnection mockConnection = mockSession.getSQLConnection();
+ EasyMock.resetToDefault(mockConnection);
+ SQLDatabaseMetaData mockMetadata = EasyMock.createNiceMock(SQLDatabaseMetaData.class);
+ EasyMock.expect(mockConnection.getSQLMetaData()).andReturn(mockMetadata);
+ EasyMock.replay(mockConnection);
+ EasyMock.replay(mockMetadata);
+
+ ObjectTree mockObjectTree = EasyMock.createMock(ObjectTree.class);
+
+ ObjectTreeModel mockModel = EasyMock.createMock(ObjectTreeModel.class);
+
+ EasyMock.replay(mockExpander, mockObjectTree);
+
+ TreeLoader classUnderTest = new TreeLoader(mockSession, mockObjectTree, mockModel, node,
+ new INodeExpander[] { mockExpander }, false);
+
+ classUnderTest.execute();
+
+ assertTrue(node.hasNoChildrenFoundWithExpander());
+ }
+
+ /**
+ * Ensure, that a node is not marked with"NoChildrenFoundWithExpander" if a
+ * expander find a child node
+ */
+ public void testChildrenFoundByExpander() throws Exception {
+ // The parent node
+ ObjectTreeNode node = new ObjectTreeNode(mockSession, mockDbInfo);
+
+ // Simulate, that a expander didn't find any children.
+ INodeExpander mockExpander = EasyMock.createMock(INodeExpander.class);
+ List<ObjectTreeNode> childs = new ArrayList<ObjectTreeNode>();
+ childs.add(new ObjectTreeNode(mockSession, mockDbInfo));
+ expect(mockExpander.createChildren(mockSession, node)).andReturn(childs);
+
+
+ // Setup some infrastucture
+ ISQLConnection mockConnection = mockSession.getSQLConnection();
+ EasyMock.resetToDefault(mockConnection);
+ SQLDatabaseMetaData mockMetadata = EasyMock.createNiceMock(SQLDatabaseMetaData.class);
+ EasyMock.expect(mockConnection.getSQLMetaData()).andReturn(mockMetadata);
+ EasyMock.replay(mockConnection);
+ EasyMock.replay(mockMetadata);
+
+
+ // Setup a ObjectTree with a Model
+ ObjectTree mockObjectTree = EasyMock.createMock(ObjectTree.class);
+ ObjectTreeModel mockModel = EasyMock.createNiceMock(ObjectTreeModel.class);
+ EasyMock.expect(mockModel.getExpanders(childs.get(0).getDatabaseObjectType())).andReturn(
+ new INodeExpander[] {});
+ // We need the mock thread save, because some methods will be called at
+ // the AWT-Event thread.
+ EasyMock.makeThreadSafe(mockModel, true);
+
+ EasyMock.expect(mockObjectTree.getTypedModel()).andReturn(mockModel);
+
+ EasyMock.replay(mockExpander, mockObjectTree, mockModel);
+
+ // Create a Treeloader
+ TreeLoader classUnderTest = new TreeLoader(mockSession, mockObjectTree, mockModel, node,
+ new INodeExpander[] { mockExpander }, false);
+
+ classUnderTest.execute();
+
+ // The expander found some childs.
+ assertFalse(node.hasNoChildrenFoundWithExpander());
+
+ // Because we didn't specify a expander for the new child
+ assertFalse(childs.get(0).getAllowsChildren());
+ }
+
+}
Property changes on: trunk/sql12/app/src/test/java/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/TreeLoaderTest.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/sql12/doc/src/main/resources/changes.txt
===================================================================
--- trunk/sql12/doc/src/main/resources/changes.txt 2011-10-03 23:59:25 UTC (rev 6450)
+++ trunk/sql12/doc/src/main/resources/changes.txt 2011-10-07 20:00:25 UTC (rev 6451)
@@ -7,6 +7,9 @@
Enhancements:
+Some performance improvements, when searching in the object tree.
+ Now, Squirrel will not try to expand a node twice, if no children were found for a node at a previous search.
+
Updated Translations:
* French (Erwan Duroselle)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|