Mercurial > p > roundup > code
changeset 2318:fa2f7ba34399
merge from maint-0-7
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Sun, 16 May 2004 09:35:50 +0000 |
| parents | f8a4c51e5847 |
| children | 7cf7e3bd1b31 |
| files | CHANGES.txt roundup/backends/back_anydbm.py roundup/backends/back_mysql.py roundup/backends/rdbms_common.py test/db_test_base.py |
| diffstat | 5 files changed, 90 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/CHANGES.txt Sun May 16 09:23:18 2004 +0000 +++ b/CHANGES.txt Sun May 16 09:35:50 2004 +0000 @@ -16,6 +16,8 @@ - mention DEFAULT_TIMEZONE requirement in upgrading doc (sf bug 952932) - fix DateHTMLProperty so local() can override user timezone (sf bug 953678) +- fix anydbm sort/group direction handling, and make RDBMS sort/group use + Link'ed "order" properties (sf bug 953148) 2004-05-10 0.7.1
--- a/roundup/backends/back_anydbm.py Sun May 16 09:23:18 2004 +0000 +++ b/roundup/backends/back_anydbm.py Sun May 16 09:35:50 2004 +0000 @@ -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.147 2004-05-12 22:27:17 richard Exp $ +#$Id: back_anydbm.py,v 1.148 2004-05-16 09:35:49 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 versions >2.1.1 (the dumbdbm fallback in 2.1.1 and earlier has several @@ -1800,21 +1800,27 @@ finally: cldb.close() + # sort vals are inserted, but directions are appended, so reverse + directions.reverse() + if '-' in directions: # one or more of the sort specs is in reverse order, so we have # to use this icky function to sort def sortfun(a, b, directions=directions, n=range(len(directions))): for i in n: - if a[i] == b[i]: continue + if not cmp(a[i], b[i]): + continue if directions[i] == '+': + # compare in the usual, ascending direction return cmp(a[i],b[i]) else: + # compare in the reverse, descending direction return cmp(b[i],a[i]) # for consistency, sort by the id if the items are equal return cmp(a[-2], b[-2]) matches.sort(sortfun) else: - # sorting is in the normal direction + # sorting is in the normal, ascending direction matches.sort() # pull the id out of the individual entries
--- a/roundup/backends/back_mysql.py Sun May 16 09:23:18 2004 +0000 +++ b/roundup/backends/back_mysql.py Sun May 16 09:35:50 2004 +0000 @@ -638,7 +638,7 @@ args.append(v) # don't match retired nodes - where.append('__retired__ <> 1') + where.append('_%s.__retired__ <> 1'%cn) # add results of full text search if search_matches is not None: @@ -661,6 +661,16 @@ # use the int column for sorting o = '__'+prop+'_int__' ordercols.append(o) + elif isinstance(props[prop], Link): + # determine whether the linked Class has an order property + lcn = props[prop].classname + link = self.db.classes[lcn] + if link.getprops().has_key('order'): + tn = '_' + lcn + frum.append(tn) + where.append('_%s._%s = %s.id'%(cn, prop, tn)) + ordercols.append(tn + '._order') + o = tn + '._order' elif prop == 'id': o = 'id' else: @@ -679,9 +689,9 @@ if mlfilt: # we're joining tables on the id, so we will get dupes if we # don't distinct() - cols = ['distinct(id)'] + cols = ['distinct(_%s.id)'%cn] else: - cols = ['id'] + cols = ['_%s.id'%cn] if orderby: cols = cols + ordercols order = ' order by %s'%(','.join(orderby))
--- a/roundup/backends/rdbms_common.py Sun May 16 09:23:18 2004 +0000 +++ b/roundup/backends/rdbms_common.py Sun May 16 09:35:50 2004 +0000 @@ -1,4 +1,4 @@ -# $Id: rdbms_common.py,v 1.99 2004-05-10 01:30:02 richard Exp $ +# $Id: rdbms_common.py,v 1.100 2004-05-16 09:35:49 richard Exp $ ''' Relational database (SQL) backend common code. Basics: @@ -2123,7 +2123,7 @@ args.append(v) # don't match retired nodes - where.append('__retired__ <> 1') + where.append('_%s.__retired__ <> 1'%cn) # add results of full text search if search_matches is not None: @@ -2146,6 +2146,16 @@ # use the int column for sorting o = '__'+prop+'_int__' ordercols.append(o) + elif isinstance(props[prop], Link): + # determine whether the linked Class has an order property + lcn = props[prop].classname + link = self.db.classes[lcn] + if link.getprops().has_key('order'): + tn = '_' + lcn + frum.append(tn) + where.append('_%s._%s = %s.id'%(cn, prop, tn)) + ordercols.append(tn + '._order') + o = tn + '._order' elif prop == 'id': o = 'id' else: @@ -2164,9 +2174,9 @@ if mlfilt: # we're joining tables on the id, so we will get dupes if we # don't distinct() - cols = ['distinct(id)'] + cols = ['distinct(_%s.id)'%cn] else: - cols = ['id'] + cols = ['_%s.id'%cn] if orderby: cols = cols + ordercols order = ' order by %s'%(','.join(orderby))
--- a/test/db_test_base.py Sun May 16 09:23:18 2004 +0000 +++ b/test/db_test_base.py Sun May 16 09:35:50 2004 +0000 @@ -15,7 +15,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -# $Id: db_test_base.py,v 1.27 2004-05-06 01:03:01 richard Exp $ +# $Id: db_test_base.py,v 1.28 2004-05-16 09:35:50 richard Exp $ import unittest, os, shutil, errno, imp, sys, time, pprint @@ -27,6 +27,8 @@ def setupSchema(db, create, module): status = module.Class(db, "status", name=String()) status.setkey("name") + priority = module.Class(db, "priority", name=String(), order=String()) + priority.setkey("name") user = module.Class(db, "user", username=String(), password=Password(), assignable=Boolean(), age=Number(), roles=String()) user.setkey("username") @@ -34,7 +36,8 @@ comment=String(indexme="yes"), fooz=Password()) issue = module.IssueClass(db, "issue", title=String(indexme="yes"), status=Link("status"), nosy=Multilink("user"), deadline=Date(), - foo=Interval(), files=Multilink("file"), assignedto=Link('user')) + foo=Interval(), files=Multilink("file"), assignedto=Link('user'), + priority=Link('priority')) stuff = module.Class(db, "stuff", stuff=String()) session = module.Class(db, 'session', title=String()) session.disableJournalling() @@ -48,6 +51,9 @@ status.create(name="in-progress") status.create(name="testing") status.create(name="resolved") + priority.create(name="feature", order="2") + priority.create(name="wish", order="3") + priority.create(name="bug", order="1") db.commit() class MyTestCase(unittest.TestCase): @@ -814,15 +820,15 @@ iss = self.db.issue for issue in ( {'title': 'issue one', 'status': '2', 'assignedto': '1', - 'foo': date.Interval('1:10'), + 'foo': date.Interval('1:10'), 'priority': '1', 'deadline': date.Date('2003-01-01.00:00')}, - {'title': 'issue two', 'status': '1', 'assignedto': '2', - 'foo': date.Interval('1d'), + {'title': 'issue two', 'status': '1', 'assignedto': '2', + 'foo': date.Interval('1d'), 'priority': '3', 'deadline': date.Date('2003-02-16.22:50')}, - {'title': 'issue three', 'status': '1', + {'title': 'issue three', 'status': '1', 'priority': '2', 'nosy': ['1','2'], 'deadline': date.Date('2003-02-18')}, {'title': 'non four', 'status': '3', - 'foo': date.Interval('0:10'), + 'foo': date.Interval('0:10'), 'priority': '1', 'nosy': ['1'], 'deadline': date.Date('2004-03-08')}): self.db.issue.create(**issue) self.db.commit() @@ -887,6 +893,10 @@ ae(filt(None, {'foo': 'to 0:05'}), []) def testFilteringIntervalSort(self): + # 1: '1:10' + # 2: '1d' + # 3: None + # 4: '0:10' ae, filt = self.filteringSetup() # ascending should sort None, 1:10, 1d ae(filt(None, {}, ('+','foo'), (None,None)), ['3', '4', '1', '2']) @@ -894,10 +904,42 @@ ae(filt(None, {}, ('-','foo'), (None,None)), ['2', '1', '4', '3']) def testFilteringMultilinkSort(self): + # 1: [] + # 2: [] + # 3: ['1','2'] + # 4: ['1'] ae, filt = self.filteringSetup() ae(filt(None, {}, ('+','nosy'), (None,None)), ['1', '2', '4', '3']) ae(filt(None, {}, ('-','nosy'), (None,None)), ['3', '4', '1', '2']) + def testFilteringDateSort(self): + # '1': '2003-01-01.00:00' + # '2': '2003-02-16.22:50' + # '3': '2003-02-18' + # '4': '2004-03-08' + ae, filt = self.filteringSetup() + # ascending + ae(filt(None, {}, ('+','deadline'), (None,None)), ['1', '2', '3', '4']) + # descending + ae(filt(None, {}, ('-','deadline'), (None,None)), ['4', '3', '2', '1']) + + def testFilteringDateSortPriorityGroup(self): + # '1': '2003-01-01.00:00' 1 => 2 + # '2': '2003-02-16.22:50' 3 => 1 + # '3': '2003-02-18' 2 => 3 + # '4': '2004-03-08' 1 => 2 + ae, filt = self.filteringSetup() + # ascending + ae(filt(None, {}, ('+','deadline'), ('+','priority')), + ['2', '1', '4', '3']) + ae(filt(None, {}, ('-','deadline'), ('+','priority')), + ['2', '4', '1', '3']) + # descending + ae(filt(None, {}, ('+','deadline'), ('-','priority')), + ['3', '1', '4', '2']) + ae(filt(None, {}, ('-','deadline'), ('-','priority')), + ['3', '4', '1', '2']) + # XXX add sorting tests for other types # XXX test auditors and reactors @@ -993,7 +1035,7 @@ keys.sort() self.assertEqual(keys, ['activity', 'actor', 'assignedto', 'creation', 'creator', 'deadline', 'files', 'fixer', 'foo', 'id', 'messages', - 'nosy', 'status', 'superseder', 'title']) + 'nosy', 'priority', 'status', 'superseder', 'title']) self.assertEqual(self.db.issue.get('1', "fixer"), None) def testRemoveProperty(self): @@ -1007,7 +1049,7 @@ keys.sort() self.assertEqual(keys, ['activity', 'actor', 'assignedto', 'creation', 'creator', 'deadline', 'files', 'foo', 'id', 'messages', - 'nosy', 'status', 'superseder']) + 'nosy', 'priority', 'status', 'superseder']) self.assertEqual(self.db.issue.list(), ['1']) def testAddRemoveProperty(self): @@ -1022,7 +1064,7 @@ keys.sort() self.assertEqual(keys, ['activity', 'actor', 'assignedto', 'creation', 'creator', 'deadline', 'files', 'fixer', 'foo', 'id', 'messages', - 'nosy', 'status', 'superseder']) + 'nosy', 'priority', 'status', 'superseder']) self.assertEqual(self.db.issue.list(), ['1']) class ROTest(MyTestCase):
