From 468c535aba2a8bf1fc9ac5e8f9d3657e911be736 Mon Sep 17 00:00:00 2001 From: richard Date: Wed, 26 Mar 2003 04:56:21 +0000 Subject: [PATCH] implemented ability to search for multilink properties with no value (not in mk) git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1627 57a73879-2fb5-44c3-a270-3262357dd7e2 --- CHANGES.txt | 5 +++-- roundup/backends/back_anydbm.py | 23 +++++++++++++++++++---- roundup/backends/rdbms_common.py | 11 ++++++++--- test/test_db.py | 3 ++- 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index e15788b..bd18ae1 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -52,6 +52,7 @@ Feature: - added ability to restore retired nodes - more lenient date input and addition Interval input support (sf bug 677764) - roundup mailgw now handles apop +- implemented ability to search for multilink properties with no value Fixed: @@ -71,8 +72,6 @@ Fixed: - fixed export/import of retired nodes (sf bug 685273) - remember the display template specified during edit (sf bug 701815) - added example HTML tempating for vacation flag (sf bug 701722) -- only look for CSV files when importing (thanks Dan Grassi) -- can now unset values in CSV editing (sf bug 704788) - finally, tables autosize columns (sf bug 609070) - added creation to index columns (sf bug 708247) @@ -82,6 +81,8 @@ Fixed: - fixed sqlite rollback/caching bug (sf bug 689383) - fixed rdbms table update detection logic (sf bug 703297) - fixed detection of bad date specs (sf bug 691439) +- only look for CSV files when importing (thanks Dan Grassi) +- can now unset values in CSV editing (sf bug 704788) - fixed rdbms email address lookup (case insensitivity) diff --git a/roundup/backends/back_anydbm.py b/roundup/backends/back_anydbm.py index c167c3c..b412443 100644 --- a/roundup/backends/back_anydbm.py +++ b/roundup/backends/back_anydbm.py @@ -15,7 +15,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -#$Id: back_anydbm.py,v 1.113 2003-03-17 22:03:04 kedder Exp $ +#$Id: back_anydbm.py,v 1.114 2003-03-26 04:56:21 richard Exp $ ''' This module defines a backend that saves the hyperdatabase in a database chosen by anydbm. It is guaranteed to always be available in python @@ -1601,7 +1601,9 @@ class Class(hyperdb.Class): The filter must match all properties specificed - but if the property value to match is a list, any one of the values in the - list may match for that property to match. + list may match for that property to match. Unless the property + is a Multilink, in which case the item's property list must + match the filterspec list. ''' cn = self.classname @@ -1624,7 +1626,9 @@ class Class(hyperdb.Class): u = [] link_class = self.db.classes[propclass.classname] for entry in v: - if entry == '-1': entry = None + # the value -1 is a special "not set" sentinel + if entry == '-1': + entry = None elif not num_re.match(entry): try: entry = link_class.lookup(entry) @@ -1635,8 +1639,12 @@ class Class(hyperdb.Class): l.append((LINK, k, u)) elif isinstance(propclass, Multilink): - if type(v) is not type([]): + # the value -1 is a special "not set" sentinel + if v == '-1': + v = [] + elif type(v) is not type([]): v = [v] + # replace key values with node ids u = [] link_class = self.db.classes[propclass.classname] @@ -1648,6 +1656,7 @@ class Class(hyperdb.Class): raise ValueError, 'new property "%s": %s not a %s'%( k, entry, self.properties[k].classname) u.append(entry) + u.sort() l.append((MULTILINK, k, u)) elif isinstance(propclass, String) and k != 'id': # simple glob searching @@ -1710,6 +1719,12 @@ class Class(hyperdb.Class): # filterspec aren't in this node's property, then skip # it have = node[k] + # check for matching the absence of multilink values + if not v and have: + break + + # othewise, make sure this node has each of the + # required values for want in v: if want not in have: break diff --git a/roundup/backends/rdbms_common.py b/roundup/backends/rdbms_common.py index a350425..c627b62 100644 --- a/roundup/backends/rdbms_common.py +++ b/roundup/backends/rdbms_common.py @@ -1,4 +1,4 @@ -# $Id: rdbms_common.py,v 1.48 2003-03-24 04:47:44 richard Exp $ +# $Id: rdbms_common.py,v 1.49 2003-03-26 04:56:21 richard Exp $ ''' Relational database (SQL) backend common code. Basics: @@ -1786,13 +1786,18 @@ class Class(hyperdb.Class): # now do other where clause stuff if isinstance(propclass, Multilink): tn = '%s_%s'%(cn, k) - frum.append(tn) if isinstance(v, type([])): + frum.append(tn) s = ','.join([a for x in v]) where.append('id=%s.nodeid and %s.linkid in (%s)'%(tn,tn,s)) args = args + v + elif v == '-1': + # only match rows that have count(linkid)=0 in the + # corresponding multilink table) + where.append('id not in (select nodeid from %s)'%tn) else: - where.append('id=%s.nodeid and %s.linkid = %s'%(tn, tn, a)) + frum.append(tn) + where.append('id=%s.nodeid and %s.linkid=%s'%(tn, tn, a)) args.append(v) elif k == 'id': if isinstance(v, type([])): diff --git a/test/test_db.py b/test/test_db.py index 742e65b..b631cbe 100644 --- a/test/test_db.py +++ b/test/test_db.py @@ -15,7 +15,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -# $Id: test_db.py,v 1.81 2003-03-22 22:43:21 richard Exp $ +# $Id: test_db.py,v 1.82 2003-03-26 04:56:21 richard Exp $ import unittest, os, shutil, time @@ -672,6 +672,7 @@ class anydbmDBTestCase(MyTestCase): def testFilteringMultilink(self): ae, filt = self.filteringSetup() ae(filt(None, {'nosy': '2'}, ('+','id'), (None,None)), ['3']) + ae(filt(None, {'nosy': '-1'}, ('+','id'), (None,None)), ['1', '2']) def testFilteringMany(self): ae, filt = self.filteringSetup() -- 2.30.2