Mercurial > p > roundup > code
changeset 6151:ff059afae50a
Make 'find' work for rev_multilink properties
| author | Ralf Schlatterbeck <rsc@runtux.com> |
|---|---|
| date | Fri, 01 May 2020 16:34:35 +0200 |
| parents | edbd4bba728a |
| children | 546763f4ce44 |
| files | roundup/backends/back_anydbm.py roundup/backends/rdbms_common.py test/db_test_base.py |
| diffstat | 3 files changed, 53 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/roundup/backends/back_anydbm.py Fri May 01 16:33:05 2020 +0200 +++ b/roundup/backends/back_anydbm.py Fri May 01 16:34:35 2020 +0200 @@ -1581,6 +1581,7 @@ # ok, now do the find cldb = self.db.getclassdb(self.classname) l = [] + rev_multilinks = [] try: for id in self.getnodeids(db=cldb): item = self.db.getnode(self.classname, id, db=cldb) @@ -1607,6 +1608,9 @@ l.append(id) break elif isinstance(prop, hyperdb.Multilink): + if prop.rev_property: + rev_multilinks.append ((prop, itemids)) + continue hit = 0 for v in value: if v in itemids: @@ -1615,6 +1619,15 @@ break if hit: break + for prop, itemids in rev_multilinks: + rprop = prop.rev_property + fun = l.append + if isinstance (rprop, hyperdb.Multilink): + fun = l.extend + for id in itemids: + fun(rprop.cls.get(id, rprop.name)) + if rev_multilinks: + l = list(sorted(set(l))) finally: cldb.close() return l
--- a/roundup/backends/rdbms_common.py Fri May 01 16:33:05 2020 +0200 +++ b/roundup/backends/rdbms_common.py Fri May 01 16:34:35 2020 +0200 @@ -2252,21 +2252,29 @@ # now multilinks for prop, values in propspec.items(): - if not isinstance(props[prop], hyperdb.Multilink): + p = props[prop] + if not isinstance(p, hyperdb.Multilink): continue if not values: continue allvalues += (0, ) + tn = p.table_name + ln = p.linkid_name + nn = p.nodeid_name + cn = '_' + self.classname + ret = '' + if p.rev_property and isinstance(p.rev_property, Link): + ret = 'and %s.__retired__=%s ' % (tn, a) + allvalues += (0, ) if type(values) is type(''): allvalues += (values,) s = a else: allvalues += tuple(values) s = ','.join([a]*len(values)) - tn = '%s_%s'%(self.classname, prop) - sql.append("""select id from _%s, %s where __retired__=%s - and id = %s.nodeid and %s.linkid in (%s)"""%(self.classname, - tn, a, tn, tn, s)) + sql.append("""select %s.id from %s, %s where %s.__retired__=%s + %sand %s.id = %s.%s and %s.%s in (%s)"""%(cn, cn, tn, cn, + a, ret, cn, tn, nn, tn, ln, s)) if not sql: return []
--- a/test/db_test_base.py Fri May 01 16:33:05 2020 +0200 +++ b/test/db_test_base.py Fri May 01 16:34:35 2020 +0200 @@ -1564,6 +1564,33 @@ got.sort() self.assertEqual(got, [one, three]) + def testFindRevLinkMultilink(self): + ae, filter, filter_iter = self.filteringSetupTransitiveSearch('user') + ni = 'nosy_issues' + self.db.issue.set('6', nosy=['3', '4', '5']) + self.db.issue.set('7', nosy=['5']) + # After this setup we have the following values for nosy: + # issue assignedto nosy + # 1: 6 4 + # 2: 6 5 + # 3: 7 + # 4: 8 + # 5: 9 + # 6: 10 3, 4, 5 + # 7: 10 5 + # 8: 10 + # assignedto links back from 'issues' + # nosy links back from 'nosy_issues' + self.assertEqual(self.db.user.find(issues={'1':1}), ['6']) + self.assertEqual(self.db.user.find(issues={'8':1}), ['10']) + self.assertEqual(self.db.user.find(issues={'2':1, '5':1}), ['6', '9']) + self.assertEqual(self.db.user.find(nosy_issues={'8':1}), []) + self.assertEqual(self.db.user.find(nosy_issues={'6':1}), + ['3', '4', '5']) + self.assertEqual(self.db.user.find(nosy_issues={'3':1, '5':1}), []) + self.assertEqual(self.db.user.find(nosy_issues={'2':1, '6':1, '7':1}), + ['3', '4', '5']) + def testFindLinkFail(self): self._find_test_setup() self.assertEqual(self.db.issue.find(status='4'), [])
