[Zope-Checkins] CVS: Zope/lib/python/Products/ZCatalog - Catalog.py:1.93
Shane Hathaway
shane@cvs.zope.org
Tue, 30 Jul 2002 11:07:31 -0400
Update of /cvs-repository/Zope/lib/python/Products/ZCatalog
In directory cvs.zope.org:/tmp/cvs-serv10041
Modified Files:
Catalog.py
Log Message:
Refactored searchResults() for clarity and also to provide a way to merge
and sort results from multiple catalogs (or multiple queries) efficiently.
=== Zope/lib/python/Products/ZCatalog/Catalog.py 1.92 => 1.93 ===
return val
return kw.get("sort_%s" % attr, None)
- def searchResults(self, REQUEST=None, used=None, **kw):
- # Get search arguments:
- args = CatalogSearchArgumentsMap(REQUEST, kw)
- # Compute "sort_index", which is a sort index, or none:
- sort_index = self._get_sort_attr("on", args)
- if sort_index is not None:
+ def _getSortIndex(self, args):
+ """Returns a search index object or None."""
+ sort_index_name = self._get_sort_attr("on", args)
+ if sort_index_name is not None:
# self.indexes is always a dict, so get() w/ 1 arg works
- sort_index = self.indexes.get(sort_index)
+ sort_index = self.indexes.get(sort_index_name)
if sort_index is None:
- raise CatalogError, ('Unknown sort_on index')
+ raise CatalogError, 'Unknown sort_on index'
else:
if not hasattr(sort_index, 'keyForDocument'):
raise CatalogError(
'The index chosen for sort_on is not capable of being'
' used as a sort index.'
)
-
+ return sort_index
+ else:
+ return None
+
+
+ def searchResults(self, REQUEST=None, used=None, _merge=1, **kw):
+ args = CatalogSearchArgumentsMap(REQUEST, kw)
+ sort_index = self._getSortIndex(args)
# Perform searches with indexes and sort_index
r = []
used = self._indexedSearch(args, sort_index, r.append, used)
- if not r:
- return LazyCat(r)
-
- # Sort/merge sub-results
-
- # The contents of r depend on whether sort_index is set.
- # If sort_index is None, r contains sequences of records.
- # If sort_index is not None, r contains pairs of (sort_key, sequence)
- # and now we have to sort the results.
- if len(r) == 1:
- if sort_index is None:
- r = r[0]
- else:
- r = r[0][1]
+ if not _merge:
+ # Postpone merging and sorting. This provides a way to
+ # sort results merged from multiple catalogs.
+ return r
else:
- if sort_index is None:
- r = LazyCat(r, len(r))
- else:
- r.sort()
- so = self._get_sort_attr("order", args)
- if (isinstance(so, types.StringType) and
- so.lower() in ('reverse', 'descending')):
- r.reverse()
-
- size = 0
- tmp = []
- for i in r:
- elt = i[1]
- tmp.append(elt)
- size += len(elt)
- r = LazyCat(tmp, size)
-
- return r
+ has_sort_keys = 0
+ reverse = 0
+ if sort_index is not None:
+ has_sort_keys = 1
+ order = self._get_sort_attr("order", args)
+ if (isinstance(order, types.StringType) and
+ order.lower() in ('reverse', 'descending')):
+ reverse = 1
+ return mergeResults(r, has_sort_keys, reverse)
__call__ = searchResults
@@ -701,4 +687,33 @@
return 1
-
+def mergeResults(r, has_sort_keys, reverse):
+ """Sort/merge sub-results, generating a flat sequence.
+
+ The contents of r depend on whether has_sort_keys is set.
+ If not has_sort_keys, r contains sequences of records.
+ If has_sort_keys, r contains pairs of (sort_key, sequence)
+ and now we have to sort the results.
+ """
+ if not r:
+ return LazyCat(r)
+ elif len(r) == 1:
+ if not has_sort_keys:
+ return r[0]
+ else:
+ return r[0][1]
+ else:
+ if not has_sort_keys:
+ return LazyCat(r, len(r))
+ else:
+ r.sort()
+ if reverse:
+ r.reverse()
+ size = 0
+ tmp = []
+ for i in r:
+ elt = i[1]
+ tmp.append(elt)
+ size += len(elt)
+ return LazyCat(tmp, size)
+