def _query(self, **kw): sort_index = kw.pop('_sort_index', None) limit = kw.pop('_limit', None) reverse = kw.pop('_reverse', False) catalog = self.catalog querykw = {} for key in kw: # XXX: remove special case in later version if isinstance(catalog[key], FieldIndex) \ and not isinstance(kw[key], tuple) \ and not isinstance(kw[key], list): querykw[key] = (kw[key], kw[key]) else: querykw[key] = kw[key] results = catalog.apply(querykw) if results is not None: if sort_index is not None: index = catalog[sort_index] if not IIndexSort.providedBy(index): msg = 'Index %s does not support sorting.' % sort_index raise ValueError(msg) results = list(index.sort(results, limit=limit, reverse=reverse)) return results
def searchResults( self, query, context=None, sort_field=None, limit=None, reverse=False): results = query.apply(context) if results is None: return if sort_field is not None: # Like in zope.catalog's searchResults we require the given # index to sort on to provide IIndexSort. We bail out if # the index does not. catalog_name, index_name = sort_field catalog = getUtility(ICatalog, catalog_name, context) index = catalog[index_name] if not IIndexSort.providedBy(index): raise ValueError( 'Index %s in catalog %s does not support ' 'sorting.' % (index_name, catalog_name)) results = list(index.sort(results, limit=limit, reverse=reverse)) else: # There's no sort_field given. We still allow to reverse # and/or limit the resultset. This mimics zope.catalog's # searchResults semantics. if reverse or limit: results = list(results) if reverse: results.reverse() if limit: del results[limit:] uidutil = getUtility(IIntIds, '', context) return ResultSet(results, uidutil)
def sorted_results(self): if self._sorted_results is None: results = iter(self._results) if self.sort_on is not None: sort_index = self.parent.catalog[self.sort_on] if IIndexSort.providedBy(sort_index): results = sort_index.sort(results, reverse=self.reverse) self._sorted_results = GeneratorWrapper(results) return self._sorted_results
def _query(self, **kw): sort_index = kw.pop('_sort_index', None) limit = kw.pop('_limit', None) reverse = kw.pop('_reverse', False) catalog = self.catalog querykw = {} for key in kw: # XXX: remove special case in later version if isinstance(catalog[key], FieldIndex) \ and not isinstance(kw[key], tuple) \ and not isinstance(kw[key], list): querykw[key] = (kw[key], kw[key]) else: querykw[key] = kw[key] results = catalog.apply(querykw) if results is not None: if sort_index is not None: index = catalog[sort_index] if not IIndexSort.providedBy(index): msg = 'Index %s does not support sorting.' % sort_index raise ValueError(msg) results = list( index.sort(results, limit=limit, reverse=reverse)) return results
def searchResults(self, query, context=None, sort_field=None, limit=None, reverse=False, start=0, caching=None, timing=HURRY_QUERY_TIMING, wrapper=None, locate_to=None): if context is None: context = getSiteManager() else: context = IComponentLookup(context) if caching in (True, False, None): cache = {} else: # A custom cache object was injected, use it. cache = caching timer = None if timing: timer = cache = TimingAwareCache(cache) all_results = query.cached_apply(cache, context) if not all_results: if timer is not None: timer.report(over=timing) return no_results if timer is not None: timer.start_post() is_iterator = False if sort_field is not None: # Like in zope.catalog's searchResults we require the given # index to sort on to provide IIndexSort. We bail out if # the index does not. if not IIndexSort.providedBy(sort_field): assert isinstance(sort_field, tuple) and len(sort_field) == 2 catalog_name, index_name = sort_field catalog = getUtility(ICatalog, catalog_name, context) sort_field = catalog[index_name] if not IIndexSort.providedBy(sort_field): raise ValueError('Index {} in catalog {} does not support ' 'sorting.'.format(index_name, catalog_name)) sort_limit = None if limit: sort_limit = limit if start: sort_limit += start selected_results = sort_field.sort(all_results, limit=sort_limit, reverse=reverse) if start: selected_results = itertools.islice(selected_results, start, None) is_iterator = True else: # There's no sort_field given. We still allow to reverse # and/or limit the resultset. This mimics zope.catalog's # searchResults semantics. selected_results = all_results if reverse: selected_results = reversed(selected_results) is_iterator = True if limit or start: slice_end = limit and start + limit or None selected_results = itertools.islice(selected_results, start, slice_end) is_iterator = True if is_iterator: selected_results = list(selected_results) if timer is not None: timer.end_post() timer.report(over=timing) return Results(context, all_results, selected_results, wrapper, locate_to)