selectors.py
changeset 7610 838a0c910bb5
parent 7559 50122a47ce4f
child 7624 ce020f90fb8e
equal deleted inserted replaced
7609:fbefd1b9e587 7610:838a0c910bb5
   253 
   253 
   254     Here are entity lookup / scoring rules:
   254     Here are entity lookup / scoring rules:
   255 
   255 
   256     * if `entity` is specified, return score for this entity's class
   256     * if `entity` is specified, return score for this entity's class
   257 
   257 
   258     * elif `row` is specified, return score for the class of the entity
   258     * elif `rset`, `select` and `filtered_variable` are specified, return score
   259       found in the specified cell, using column specified by `col` or 0
   259       for the possible classes for variable in the given rql :class:`Select`
   260 
   260       node
   261     * else return the sum of scores for each entity class found in the column
   261 
   262       specified specified by the `col` argument or in column 0 if not specified,
   262     * elif `rset` and `row` are specified, return score for the class of the
   263       unless:
   263       entity found in the specified cell, using column specified by `col` or 0
       
   264 
       
   265     * elif `rset` is specified return score for each entity class found in the
       
   266       column specified specified by the `col` argument or in column 0 if not
       
   267       specified
       
   268 
       
   269     When there are several classes to be evaluated, return the sum of scores for
       
   270     each entity class unless:
   264 
   271 
   265       - `once_is_enough` is False (the default) and some entity class is scored
   272       - `once_is_enough` is False (the default) and some entity class is scored
   266         to 0, in which case 0 is returned
   273         to 0, in which case 0 is returned
   267 
   274 
   268       - `once_is_enough` is True, in which case the first non-zero score is
   275       - `once_is_enough` is True, in which case the first non-zero score is
   274     def __init__(self, once_is_enough=False, accept_none=True):
   281     def __init__(self, once_is_enough=False, accept_none=True):
   275         self.once_is_enough = once_is_enough
   282         self.once_is_enough = once_is_enough
   276         self.accept_none = accept_none
   283         self.accept_none = accept_none
   277 
   284 
   278     @lltrace
   285     @lltrace
   279     def __call__(self, cls, req, rset=None, row=None, col=0, accept_none=None,
   286     def __call__(self, cls, req, rset=None, row=None, col=0, entity=None,
       
   287                  select=None, filtered_variable=None,
       
   288                  accept_none=None,
   280                  **kwargs):
   289                  **kwargs):
   281         if kwargs.get('entity'):
   290         if entity is not None:
   282             return self.score_class(kwargs['entity'].__class__, req)
   291             return self.score_class(entity.__class__, req)
   283         if not rset:
   292         if not rset:
   284             return 0
   293             return 0
   285         score = 0
   294         if select is not None and filtered_variable is not None:
   286         if row is None:
   295             etypes = set(sol[filtered_variable.name] for sol in select.solutions)
       
   296         elif row is None:
   287             if accept_none is None:
   297             if accept_none is None:
   288                 accept_none = self.accept_none
   298                 accept_none = self.accept_none
   289             if not accept_none:
   299             if not accept_none and \
   290                 if any(rset[i][col] is None for i in xrange(len(rset))):
   300                    any(rset[i][col] is None for i in xrange(len(rset))):
   291                     return 0
   301                 return 0
   292             for etype in rset.column_types(col):
   302             etypes = rset.column_types(col)
   293                 if etype is None: # outer join
       
   294                     return 0
       
   295                 escore = self.score(cls, req, etype)
       
   296                 if not escore and not self.once_is_enough:
       
   297                     return 0
       
   298                 elif self.once_is_enough:
       
   299                     return escore
       
   300                 score += escore
       
   301         else:
   303         else:
   302             etype = rset.description[row][col]
   304             etype = rset.description[row][col]
   303             if etype is not None:
   305             # may have None in rset.description on outer join
   304                 score = self.score(cls, req, etype)
   306             if etype is None:
       
   307                 return 0
       
   308             etypes = (etype,)
       
   309         score = 0
       
   310         for etype in etypes:
       
   311             escore = self.score(cls, req, etype)
       
   312             if not escore and not self.once_is_enough:
       
   313                 return 0
       
   314             elif self.once_is_enough:
       
   315                 return escore
       
   316             score += escore
   305         return score
   317         return score
   306 
   318 
   307     def score(self, cls, req, etype):
   319     def score(self, cls, req, etype):
   308         if etype in BASE_TYPES:
   320         if etype in BASE_TYPES:
   309             return 0
   321             return 0