def apply(self, data): if data is None: return data if self.fields: fields = set(self.fields) def includeFields(d): return dict((k, v) for k, v in d.items() if k in fields) applyFields = includeFields else: fields = None if isinstance(data, dict): # item details if fields: data = applyFields(data) return data else: filters = self.filters order = self.order # item collection if isinstance(data, base.ListResult): # if pagination was applied, then fields, etc. must be empty assert not fields and not order and not filters, \ "endpoint must apply fields, order, and filters if it performs pagination" offset, total = data.offset, data.total limit = data.limit else: offset, total = None, None limit = None if fields: data = (applyFields(d) for d in data) # link the filters together and then flatten to list for f in self.filters: data = f.apply(data) data = list(data) if total is None: total = len(data) if self.order: def keyFunc(elem, order=self.order): """ Do a multi-level sort by passing in the keys to sort by. @param elem: each item in the list to sort. It must be a C{dict} @param order: a list of keys to sort by, such as: ('lastName', 'firstName', 'age') @return: a key used by sorted(). This will be a list such as: [a['lastName', a['firstName'], a['age']] @rtype: a C{list} """ compareKey = [] for k in order: doReverse = False if k[0] == '-': # If we get a key '-lastName', # it means sort by 'lastName' in reverse. k = k[1:] doReverse = True val = NoneComparator(elem[k]) if doReverse: val = ReverseComparator(val) compareKey.append(val) return compareKey data.sort(key=keyFunc) # finally, slice out the limit/offset if self.offset is not None or self.limit is not None: if offset is not None or limit is not None: raise AssertionError("endpoint must clear offset/limit") end = ((self.offset or 0) + self.limit if self.limit is not None else None) data = data[self.offset:end] offset = self.offset limit = self.limit rv = base.ListResult(data) rv.offset, rv.total = offset, total rv.limit = limit return rv
def test_repr(self): lr = base.ListResult([1, 2, 3], offset=10, total=20, limit=3) self.assertTrue(repr(lr).startswith('ListResult'))
def apply(self, data): if data is None: return data if self.fields: fields = set(self.fields) def includeFields(d): return dict((k, v) for k, v in iteritems(d) if k in fields) applyFields = includeFields else: fields = None if isinstance(data, dict): # item details if fields: data = applyFields(data) return data else: filters = self.filters order = self.order # item collection if isinstance(data, base.ListResult): # if pagination was applied, then fields, etc. must be empty assert not fields and not order and not filters, \ "endpoint must apply fields, order, and filters if it performs pagination" offset, total = data.offset, data.total limit = data.limit else: offset, total = None, None limit = None if fields: data = (applyFields(d) for d in data) # link the filters together and then flatten to list for f in self.filters: data = f.apply(data) data = list(data) if total is None: total = len(data) # precompute the ordering functions and sort if self.order: order = [(lambda a, b, k=k[1:]: nonecmp(b[k], a[k])) if k[0] == '-' else (lambda a, b, k=k: nonecmp(a[k], b[k])) for k in self.order] def cmpFunc(a, b): for f in order: c = f(a, b) if c: return c return 0 data.sort(cmp=cmpFunc) # finally, slice out the limit/offset if self.offset is not None or self.limit is not None: if offset is not None or limit is not None: raise AssertionError("endpoint must clear offset/limit") end = ((self.offset or 0) + self.limit if self.limit is not None else None) data = data[self.offset:end] offset = self.offset limit = self.limit rv = base.ListResult(data) rv.offset, rv.total = offset, total rv.limit = limit return rv
def test_constructor(self): lr = base.ListResult([1, 2, 3], offset=10, total=20, limit=3) self.assertEqual(lr.data, [1, 2, 3]) self.assertEqual(lr.offset, 10) self.assertEqual(lr.total, 20) self.assertEqual(lr.limit, 3)
def check(gotten): self.assertEqual(gotten, base.ListResult( [{'val': 919}, {'val': 918}], total=10, limit=2)) ep.get.assert_called_once_with(mock.ANY, {})