From f7ec41c8caaf90ff3b25b227d989371c5e287697 Mon Sep 17 00:00:00 2001 From: Hanno Schlichting Date: Sun, 25 Mar 2012 21:59:43 +0000 Subject: [PATCH] Make sort_on for two indexes work for one of the four algorithms in `sortResults` --- src/Products/ZCatalog/Catalog.py | 22 ++++++++++++++++++--- src/Products/ZCatalog/tests/test_catalog.py | 2 +- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/Products/ZCatalog/Catalog.py b/src/Products/ZCatalog/Catalog.py index 241d3de2..e4a1adbe 100644 --- a/src/Products/ZCatalog/Catalog.py +++ b/src/Products/ZCatalog/Catalog.py @@ -15,6 +15,7 @@ import logging import warnings from bisect import bisect +from collections import defaultdict from random import randint import Acquisition @@ -671,12 +672,16 @@ def sortResults(self, rs, sort_index, reverse=0, limit=None, merge=1, # proportion of the time to perform an indexed search. # Try to avoid all non-local attribute lookup inside # those loops. + index2 = None if isinstance(sort_index, list): - # TODO: ignore multiple sort indexes for now + if len(sort_index) > 1: + index2 = sort_index[1] sort_index = sort_index[0] _intersection = intersection _self__getitem__ = self.__getitem__ index_key_map = sort_index.documentToKeyMap() + index2_key_map = (index2 is not None and + index2.documentToKeyMap() or None) _None = None _keyerror = KeyError result = [] @@ -738,7 +743,15 @@ def sortResults(self, rs, sort_index, reverse=0, limit=None, merge=1, # Is this ever true? intset = keys() length += len(intset) - append((k, intset, _self__getitem__)) + # sort on secondary index + if index2_key_map is not None: + keysets = defaultdict(list) + for i in intset: + keysets[(k, index2_key_map.get(i))].append(i) + for k2, v2 in keysets.items(): + append((k2, v2, _self__getitem__)) + else: + append((k, intset, _self__getitem__)) # Note that sort keys are unique. if reverse: @@ -882,7 +895,10 @@ def _getSortIndex(self, args): 'capable of being used as a sort index: ' '%s' % repr(name)) sort_indexes.append(sort_index) - return sort_indexes[0] + if len(sort_indexes) > 2: + raise CatalogError('Two sort indexes are supported at max, ' + 'got: %s' %repr(name)) + return sort_indexes else: return None diff --git a/src/Products/ZCatalog/tests/test_catalog.py b/src/Products/ZCatalog/tests/test_catalog.py index d6327511..3c2a6bb3 100644 --- a/src/Products/ZCatalog/tests/test_catalog.py +++ b/src/Products/ZCatalog/tests/test_catalog.py @@ -499,7 +499,7 @@ def test_sort_on_missing(self): self.assertEqual(len(a), upper, 'length should be %s, its %s' % (upper, len(a))) - def DISABLED_test_sort_on_two(self): + def test_sort_on_two(self): upper = self.upper a = self._catalog(sort_on=('att1', 'num'), att1='att1') self.assertEqual(len(a), upper,