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 |