app/soc/logic/models/base.py
changeset 2854 003a84e774e2
parent 2853 80a71738cb4f
child 2897 c0e78185444c
equal deleted inserted replaced
2853:80a71738cb4f 2854:003a84e774e2
   310       'There is no "%(name)s" where %(pairs)s.') % {
   310       'There is no "%(name)s" where %(pairs)s.') % {
   311         'name': self._name, 'pairs': joined_pairs}
   311         'name': self._name, 'pairs': joined_pairs}
   312 
   312 
   313     raise out_of_band.Error(msg, status=404)
   313     raise out_of_band.Error(msg, status=404)
   314 
   314 
       
   315   def prefetchField(self, field, data):
       
   316     """Prefetches all fields in data from the datastore in one fetch.
       
   317 
       
   318     Args:
       
   319       field: the field that should be fetched
       
   320       data: the data for which the prefetch should be done
       
   321     """
       
   322 
       
   323     prop = getattr(self._model, field, None)
       
   324 
       
   325     if not prop:
       
   326       logging.exception("Model %s does not have attribute %s" %
       
   327                         (self._model, field))
       
   328       return
       
   329 
       
   330     if not isinstance(prop, db.ReferenceProperty):
       
   331       logging.exception("Property %s of %s is not a ReferenceProperty but a %s" %
       
   332                         (field, self._model.kind(), prop.__class__.__name__))
       
   333       return
       
   334 
       
   335     keys = [prop.get_value_for_datastore(i) for i in data]
       
   336 
       
   337     prefetched_entities = db.get(keys)
       
   338     prefetched_dict = dict((i.key(), i) for i in prefetched_entities)
       
   339 
       
   340     for i in data:
       
   341       value = prefetched_dict[prop.get_value_for_datastore(i)]
       
   342       setattr(i, field, value)
       
   343 
   315   def getForFields(self, filter=None, unique=False, limit=1000, offset=0,
   344   def getForFields(self, filter=None, unique=False, limit=1000, offset=0,
   316                    ancestors=None, order=None):
   345                    ancestors=None, order=None, prefetch=None):
   317     """Returns all entities that have the specified properties.
   346     """Returns all entities that have the specified properties.
   318 
   347 
   319     Args:
   348     Args:
   320       filter: a dict for the properties that the entities should have
   349       filter: a dict for the properties that the entities should have
   321       unique: if set, only the first item from the resultset will be returned
   350       unique: if set, only the first item from the resultset will be returned
   322       limit: the amount of entities to fetch at most
   351       limit: the amount of entities to fetch at most
   323       offset: the position to start at
   352       offset: the position to start at
   324       ancestors: list of ancestors properties to set for this query
   353       ancestors: list of ancestors properties to set for this query
   325       order: a list with the sort order
   354       order: a list with the sort order
       
   355       prefetch: the fields of the data that should be pre-fetched,
       
   356           has no effect if unique is True
   326     """
   357     """
   327 
   358 
   328     if unique:
   359     if unique:
   329       limit = 1
   360       limit = 1
       
   361 
       
   362     if not prefetch:
       
   363       prefetch = []
   330 
   364 
   331     query = self.getQueryForFields(filter=filter, 
   365     query = self.getQueryForFields(filter=filter, 
   332                                    ancestors=ancestors, order=order)
   366                                    ancestors=ancestors, order=order)
   333 
   367 
   334     try:
   368     try:
   339                         (exception, self._model, filter, ancestors, order))
   373                         (exception, self._model, filter, ancestors, order))
   340       # TODO: send email
   374       # TODO: send email
   341 
   375 
   342     if unique:
   376     if unique:
   343       return result[0] if result else None
   377       return result[0] if result else None
       
   378 
       
   379     for field in prefetch:
       
   380       self.prefetchField(field, result)
   344 
   381 
   345     return result
   382     return result
   346 
   383 
   347   def getQueryForFields(self, filter=None, ancestors=None, order=None):
   384   def getQueryForFields(self, filter=None, ancestors=None, order=None):
   348     """Returns a query with the specified properties.
   385     """Returns a query with the specified properties.