comparison roundup/backends/rdbms_common.py @ 6415:dbacf6bf2a2f

Implement expressions for Link properties
author Ralf Schlatterbeck <rsc@runtux.com>
date Tue, 18 May 2021 08:50:46 +0200
parents 7b1b6dffc7ed
children ada1edcc9132
comparison
equal deleted inserted replaced
6414:3dbf1bc5e567 6415:dbacf6bf2a2f
2450 if last_id is not None and is_valid(kws): 2450 if last_id is not None and is_valid(kws):
2451 append(last_id) 2451 append(last_id)
2452 2452
2453 # we have ids of the classname table 2453 # we have ids of the classname table
2454 return ids.where("_%s.id" % classname, self.db.arg) 2454 return ids.where("_%s.id" % classname, self.db.arg)
2455
2456 def _filter_link_expression(self, proptree, v):
2457 """ Filter elements in the table that match the given expression
2458 """
2459 pln = proptree.parent.uniqname
2460 prp = proptree.name
2461 try:
2462 opcodes = [int(x) for x in v]
2463 if min(opcodes) >= -1:
2464 raise ValueError()
2465 expr = compile_expression(opcodes)
2466 # NULL doesn't compare to NULL in SQL
2467 # So not (x = '1') will *not* include NULL values for x
2468 # That's why we need that and clause:
2469 atom = "_%s._%s = %s and _%s._%s is not NULL" % (
2470 pln, prp, self.db.arg, pln, prp)
2471 atom_nil = "_%s._%s is NULL" % (pln, prp)
2472 lambda_atom = lambda n: atom if n.x >= 0 else atom_nil
2473 values = []
2474 w = expr.generate(lambda_atom)
2475 def collect_values(n):
2476 if n.x >= 0:
2477 values.append(n.x)
2478 expr.visit(collect_values)
2479 return w, values
2480 except:
2481 pass
2482 # Fallback to original code
2483 args = []
2484 where = None
2485 d = {}
2486 for entry in v:
2487 if entry == '-1':
2488 entry = None
2489 d[entry] = entry
2490 l = []
2491 if None in d or not d:
2492 if None in d: del d[None]
2493 l.append('_%s._%s is NULL'%(pln, prp))
2494 if d:
2495 v = list(d)
2496 s = ','.join([self.db.arg for x in v])
2497 l.append('(_%s._%s in (%s))'%(pln, prp, s))
2498 args = v
2499 if l:
2500 where = '(' + ' or '.join(l) +')'
2501 return where, args
2455 2502
2456 def _filter_multilink_expression(self, proptree, v): 2503 def _filter_multilink_expression(self, proptree, v):
2457 """ Filters out elements of the classname table that do not 2504 """ Filters out elements of the classname table that do not
2458 match the given expression. 2505 match the given expression.
2459 Returns tuple of 'WHERE' introns for the overall filter. 2506 Returns tuple of 'WHERE' introns for the overall filter.
2676 c = [x for x in p.children if 'search' in x.need_for] 2723 c = [x for x in p.children if 'search' in x.need_for]
2677 if c: 2724 if c:
2678 where.append('_%s._%s=_%s.id'%(pln, k, ln)) 2725 where.append('_%s._%s=_%s.id'%(pln, k, ln))
2679 if p.has_values: 2726 if p.has_values:
2680 if isinstance(v, type([])): 2727 if isinstance(v, type([])):
2681 d = {} 2728 w, arg = self._filter_link_expression(p, v)
2682 for entry in v: 2729 if w:
2683 if entry == '-1': 2730 where.append(w)
2684 entry = None 2731 args += arg
2685 d[entry] = entry
2686 l = []
2687 if None in d or not d:
2688 if None in d: del d[None]
2689 l.append('_%s._%s is NULL'%(pln, k))
2690 if d:
2691 v = list(d)
2692 s = ','.join([a for x in v])
2693 l.append('(_%s._%s in (%s))'%(pln, k, s))
2694 args = args + v
2695 if l:
2696 where.append('(' + ' or '.join(l) +')')
2697 else: 2732 else:
2698 if v in ('-1', None): 2733 if v in ('-1', None):
2699 v = None 2734 v = None
2700 where.append('_%s._%s is NULL'%(pln, k)) 2735 where.append('_%s._%s is NULL'%(pln, k))
2701 else: 2736 else:

Roundup Issue Tracker: http://roundup-tracker.org/