Code

sort/group by multilink in RDBMS
authorrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Mon, 5 Apr 2004 07:13:10 +0000 (07:13 +0000)
committerrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Mon, 5 Apr 2004 07:13:10 +0000 (07:13 +0000)
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@2256 57a73879-2fb5-44c3-a270-3262357dd7e2

CHANGES.txt
roundup/backends/rdbms_common.py
test/db_test_base.py

index b1164924da7dee064d530b546e36570d0970e667..5f1a1e4ca6ff0151d5f5e1d54f5ccfcd06fb85ce 100644 (file)
@@ -19,6 +19,7 @@ Fixed:
   download links (sf bug 927745)
 - all uses of TRACKER_WEB now ensure it ends with a '/'
 - roundup-admin install checks for existing tracker in target home
+- grouping (and sorting) by multilink in RDBMS backends (sf bug 655702)
 
 
 2004-03-27 0.7.0b2
index 657b477cd4bdaa3f82f733ec537f9d2c1154b9c6..ab43ecd1709126a15fea3b33b734d72d83a885a5 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: rdbms_common.py,v 1.88 2004-04-02 05:58:45 richard Exp $
+# $Id: rdbms_common.py,v 1.89 2004-04-05 07:13:10 richard Exp $
 ''' Relational database (SQL) backend common code.
 
 Basics:
@@ -2024,34 +2024,23 @@ class Class(hyperdb.Class):
             args = args + v
 
         # "grouping" is just the first-order sorting in the SQL fetch
-        # can modify it...)
         orderby = []
         ordercols = []
-        if group[0] is not None and group[1] is not None:
-            if group[0] != '-':
-                orderby.append('_'+group[1])
-                ordercols.append('_'+group[1])
-            else:
-                orderby.append('_'+group[1]+' desc')
-                ordercols.append('_'+group[1])
-
-        # now add in the sorting
-        group = ''
-        if sort[0] is not None and sort[1] is not None:
-            direction, colname = sort
-            if direction != '-':
-                if colname == 'id':
-                    orderby.append(colname)
-                else:
-                    orderby.append('_'+colname)
-                    ordercols.append('_'+colname)
-            else:
-                if colname == 'id':
-                    orderby.append(colname+' desc')
-                    ordercols.append(colname)
+        mlsort = []
+        for sortby in group, sort:
+            sdir, prop = sortby
+            if sdir and prop:
+                if isinstance(props[prop], Multilink):
+                    mlsort.append(sortby)
+                    continue
+                elif prop == 'id':
+                    o = 'id'
                 else:
-                    orderby.append('_'+colname+' desc')
-                    ordercols.append('_'+colname)
+                    o = '_'+prop
+                    ordercols.append(o)
+                if sdir == '-':
+                    o += ' desc'
+                orderby.append(o)
 
         # construct the SQL
         frum = ','.join(frum)
@@ -2059,14 +2048,14 @@ class Class(hyperdb.Class):
             where = ' where ' + (' and '.join(where))
         else:
             where = ''
-        cols = ['id']
+        cols = ['distinct(id)']
         if orderby:
             cols = cols + ordercols
             order = ' order by %s'%(','.join(orderby))
         else:
             order = ''
         cols = ','.join(cols)
-        sql = 'select %s from %s %s%s%s'%(cols, frum, where, group, order)
+        sql = 'select %s from %s %s%s'%(cols, frum, where, order)
         args = tuple(args)
         if __debug__:
             print >>hyperdb.DEBUG, 'filter', (self, sql, args)
@@ -2079,7 +2068,28 @@ class Class(hyperdb.Class):
 
         # return the IDs (the first column)
         # XXX numeric ids
-        return [str(row[0]) for row in l]
+        l =  [str(row[0]) for row in l]
+
+        if not mlsort:
+            return l
+
+        # ergh. someone wants to sort by a multilink.
+        r = []
+        for id in l:
+            m = []
+            for ml in mlsort:
+                m.append(self.get(id, ml[1]))
+            r.append((id, m))
+        i = 0
+        for sortby in mlsort:
+            def sortfun(a, b, dir=sortby[i]):
+                if dir == '-':
+                    return cmp(b[1][i], a[1][i])
+                else:
+                    return cmp(a[1][i], b[1][i])
+            r.sort(sortfun)
+            i += 1
+        return [i[0] for i in r]
 
     def count(self):
         '''Get the number of nodes in this class.
index 14a9e38e4514a003675967123bb0f58e26033482..a69b859d0dbab9efa25f933bc7f93aa8a63d7d58 100644 (file)
@@ -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.20 2004-03-24 04:57:25 richard Exp $ 
+# $Id: db_test_base.py,v 1.21 2004-04-05 07:13:10 richard Exp $ 
 
 import unittest, os, shutil, errno, imp, sys, time, pprint
 
@@ -892,6 +892,11 @@ class DBTest(MyTestCase):
         # descending should sort 1d, 1:10, None
         ae(filt(None, {}, ('-','foo'), (None,None)), ['2', '1', '4', '3'])
 
+    def testFilteringMultilinkSort(self):
+        ae, filt = self.filteringSetup()
+        ae(filt(None, {}, ('+','nosy'), (None,None)), ['1', '2', '4', '3'])
+        ae(filt(None, {}, ('-','nosy'), (None,None)), ['3', '4', '1', '2'])
+
 # XXX add sorting tests for other types
 # XXX test auditors and reactors