Unify 'getForFields' and 'getForLimitAndOffset'
authorSverre Rabbelier <srabbelier@gmail.com>
Sun, 01 Feb 2009 22:44:14 +0000
changeset 1165 4db62684ce13
parent 1164 d0e14654431a
child 1166 558bd62ee9d4
Unify 'getForFields' and 'getForLimitAndOffset' This also fixes the broken list views for filtered lists. Patch by: Sverre Rabbelier
app/soc/logic/models/base.py
app/soc/views/helper/lists.py
app/soc/views/models/base.py
--- 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]