[Zope3-checkins] SVN: Zope3/branches/3.3/src/zope/app/catalog/ Merged the fix of issue #466 into the branch.

Uwe Oestermeier uwe_oestermeier at iwm-kmrc.de
Sun Jul 2 08:43:25 EDT 2006


Log message for revision 68948:
  Merged the fix of issue #466 into the branch.

Changed:
  U   Zope3/branches/3.3/src/zope/app/catalog/README.txt
  U   Zope3/branches/3.3/src/zope/app/catalog/browser/advanced.pt
  U   Zope3/branches/3.3/src/zope/app/catalog/catalog.py
  U   Zope3/branches/3.3/src/zope/app/catalog/tests.py

-=-
Modified: Zope3/branches/3.3/src/zope/app/catalog/README.txt
===================================================================
--- Zope3/branches/3.3/src/zope/app/catalog/README.txt	2006-07-02 12:40:19 UTC (rev 68947)
+++ Zope3/branches/3.3/src/zope/app/catalog/README.txt	2006-07-02 12:43:24 UTC (rev 68948)
@@ -216,15 +216,8 @@
     [1, 6]
     >>> list(cat.apply({'color': 'red'}))
     [2]
+    
 
-WARNING: There is an issue here: The updateIndexes() method will include all
-objects that are registered with the next reachable IntId utility. If no IntId
-utility exists in the same site as the catalog, you will end up with objects
-not belonging to the site of the catalog. A work around is to add an IntId
-utility parallel to your catalog. See
-http://www.zope.org/Collectors/Zope3-dev/466 for the current status of this
-issue.
-
 There's an alternate search interface that returns "result sets".
 Result sets provide access to objects, rather than object ids:
 

Modified: Zope3/branches/3.3/src/zope/app/catalog/browser/advanced.pt
===================================================================
--- Zope3/branches/3.3/src/zope/app/catalog/browser/advanced.pt	2006-07-02 12:40:19 UTC (rev 68947)
+++ Zope3/branches/3.3/src/zope/app/catalog/browser/advanced.pt	2006-07-02 12:43:24 UTC (rev 68948)
@@ -23,11 +23,9 @@
            i18n:attributes="value reindex-button"/>
 </form>
 
-<div class="bug">
+<div>
   Please make sure to install an IntId utility before using the reindex
-  function. This is a known issue that will be removed in Zope 3.3. See <a
-    href="http://www.zope.org/Collectors/Zope3-dev/466">Issue 466</a> for a
-  detailed description and the current status.  
+  function.  
 </div>
 
 </div>

Modified: Zope3/branches/3.3/src/zope/app/catalog/catalog.py
===================================================================
--- Zope3/branches/3.3/src/zope/app/catalog/catalog.py	2006-07-02 12:40:19 UTC (rev 68947)
+++ Zope3/branches/3.3/src/zope/app/catalog/catalog.py	2006-07-02 12:43:24 UTC (rev 68948)
@@ -24,6 +24,8 @@
 from zope.app.container.btree import BTreeContainer
 from zope.app.catalog.interfaces import ICatalog
 from zope.app.intid.interfaces import IIntIds
+from zope.traversing.interfaces import IPhysicallyLocatable
+from zope.location import location
 from BTrees.IFBTree import weightedIntersection
 
 class ResultSet:
@@ -63,17 +65,31 @@
         """Unregister the data from indexes of this catalog."""
         for index in self.values():
             index.unindex_doc(docid)
+            
+    def _visitSublocations(self) :
+        """Restricts the access to the objects that live within
+        the nearest site if the catalog itself is locatable.
+        """
+        locatable = IPhysicallyLocatable(self, None)
+        if locatable is not None :
+            uidutil = zapi.getUtility(IIntIds, context=self)
+            site = locatable.getNearestSite()
+            for uid in uidutil:
+                obj = uidutil.getObject(uid)
+                if location.inside(obj, site) :
+                    yield uid, obj
+        else :
+            uidutil = zapi.getUtility(IIntIds)
+            for uid in uidutil:
+                yield uid, uidutil.getObject(uid)
+                 
 
     def updateIndex(self, index):
-        uidutil = zapi.getUtility(IIntIds)
-        for uid in uidutil:
-            obj = uidutil.getObject(uid)
+        for uid, obj in self._visitSublocations() :
             index.index_doc(uid, obj)
 
     def updateIndexes(self):
-        uidutil = zapi.getUtility(IIntIds)
-        for uid in uidutil:
-            obj = uidutil.getObject(uid)
+        for uid, obj in self._visitSublocations() :
             for index in self.values():
                 index.index_doc(uid, obj)
 

Modified: Zope3/branches/3.3/src/zope/app/catalog/tests.py
===================================================================
--- Zope3/branches/3.3/src/zope/app/catalog/tests.py	2006-07-02 12:40:19 UTC (rev 68947)
+++ Zope3/branches/3.3/src/zope/app/catalog/tests.py	2006-07-02 12:43:24 UTC (rev 68948)
@@ -221,6 +221,8 @@
     __name__ = None
     __parent__ = None
 
+
+
 class TestEventSubscribers(unittest.TestCase):
 
     def setUp(self):
@@ -286,11 +288,74 @@
         self.assertEqual(self.cat.regs, [])
 
 
+class TestIndexUpdating(unittest.TestCase) :
+    """Issue #466: When reindexing a catalog it takes all objects from 
+    the nearest IntId utility. This is a problem when IntId utility 
+    lives in another site than the one.
+            
+    To solve this issue we simply check whether the objects are living
+    within the nearest site.
+    """
+
+    def setUp(self):
+        
+        setup.placefulSetUp(True)
+        
+        from zope.app.catalog.catalog import Catalog
+        from zope.app.container.contained import ContainerSublocations
+        
+        self.root = setup.buildSampleFolderTree()
+        
+        subfolder = self.root[u'folder1'][u'folder1_1']
+        root_sm = self.root_sm = setup.createSiteManager(self.root)
+        local_sm = self.local_sm = setup.createSiteManager(subfolder)
+        self.utility = setup.addUtility(root_sm, '', IIntIds, IntIdsStub())
+        self.cat = setup.addUtility(local_sm, '', ICatalog, Catalog())
+        self.cat['name'] = StubIndex('__name__', None)
+        
+        for obj in self.iterAll(self.root) :
+            self.utility.register(obj)
+      
+    def tearDown(self):
+        setup.placefulTearDown()
+
+    def iterAll(self, container) :
+        from zope.app.container.interfaces import IContainer
+        for value in container.values() :
+            yield value
+            if IContainer.providedBy(value) :
+                for obj in self.iterAll(value) :
+                    yield obj
+                    
+    def test_visitSublocations(self) :
+        """ Test the iterContained method which should return only the
+        sublocations which are registered by the IntIds.
+        """
+        
+        names = sorted([ob.__name__ for i, ob in self.cat._visitSublocations()])
+        self.assertEqual(names, [u'folder1_1', u'folder1_1_1', u'folder1_1_2'])
+            
+    def test_updateIndex(self):
+        """ Setup a catalog deeper within the containment hierarchy
+        and call the updateIndexes method. The indexed objects should should
+        be restricted to the sublocations.
+        """
+        
+        self.cat.updateIndexes()
+        index = self.cat['name']
+        names = sorted([ob.__name__ for i, ob in index.doc.items()])
+        self.assertEqual(names, [u'folder1_1', u'folder1_1_1', u'folder1_1_2'])
+        
+ 
+        
+
+
 def test_suite():
     from zope.testing import doctest
     suite = unittest.TestSuite()
     suite.addTest(unittest.makeSuite(Test))
     suite.addTest(unittest.makeSuite(TestEventSubscribers))
+    suite.addTest(unittest.makeSuite(TestIndexUpdating))
     suite.addTest(doctest.DocTestSuite('zope.app.catalog.attribute'))
     suite.addTest(doctest.DocFileSuite(
         'README.txt',



More information about the Zope3-Checkins mailing list