Unify 'getForFields' and 'getForLimitAndOffset'
This also fixes the broken list views for filtered lists.
Patch by: Sverre Rabbelier
--- a/app/soc/logic/models/base.py Sun Feb 01 22:35:35 2009 +0000
+++ b/app/soc/logic/models/base.py Sun Feb 01 22:44:14 2009 +0000
@@ -274,46 +274,31 @@
raise out_of_band.Error(msg, status=404)
- def getForLimitAndOffset(self, limit, offset=0):
- """Returns entities for given offset and limit or None if not found.
-
- Args:
- limit: max amount of entities to return
- offset: optional number of results to skip first; default zero.
- """
-
- query = self._model.all()
- return query.fetch(limit, offset)
-
- def getForFields(self, filter, unique=False):
+ def getForFields(self, filter=None, unique=False, limit=1000, offset=0):
"""Returns all entities that have the specified properties.
Args:
filter: a dict for the properties that the entities should have
unique: if set, only the first item from the resultset will be returned
+ limit: the amount of entities to fetch at most
+ offset: the position to start at
"""
if not filter:
- raise Error("Properties did not contain any values")
+ filter = {}
+ if unique:
+ limit = 1
- queries = dicts.split(filter)
+ q = db.Query(self._model)
- def toQuery(filter):
- q = db.Query(self._model)
- for key, value in filter.iteritems():
+ for key, values in filter.iteritems():
+ for value in (values if isinstance(values, list) else [values]):
q.filter(key, value)
- return q
- result = itertools.chain(*[toQuery(x) for x in queries])
+ result = q.fetch(limit, offset)
if unique:
- # Return the first item, we need the loop as itertools.chain
- # returns an iterable rather than a list
- for item in result:
- return item
-
- # In the case result is empty, return None
- return None
+ return result[0] if result else None
return result
--- a/app/soc/views/helper/lists.py Sun Feb 01 22:35:35 2009 +0000
+++ b/app/soc/views/helper/lists.py Sun Feb 01 22:44:14 2009 +0000
@@ -124,17 +124,10 @@
pagination_form = makePaginationForm(request, limit, arg_name)
# Fetch one more to see if there should be a 'next' link
- if not filter:
- data = logic.getForLimitAndOffset(limit+1, offset=offset)
- else:
- data = logic.getForFields(filter)
-
- if not data:
- data = []
-
- data = list(itertools.islice(data, limit+1))
+ data = logic.getForFields(filter=filter, limit=limit+1, offset=offset)
more = len(data) > limit
+
if more:
del data[limit:]
--- a/app/soc/views/models/base.py Sun Feb 01 22:35:35 2009 +0000
+++ b/app/soc/views/models/base.py Sun Feb 01 22:44:14 2009 +0000
@@ -574,12 +574,12 @@
return_url = get_dict['continue']
field = get_dict['field']
+ filter = {}
+
if scope_path:
- filter = {}
filter['scope_path'] = scope_path
- data = data = self._logic.getForFields(filter)
- else:
- data = self._logic.getForLimitAndOffset(1000)
+
+ data = self._logic.getForFields(filter=filter, limit=1000)
data = [i.toDict() for i in data]