trac-t10425 / default_order.diff

# HG changeset patch
# Parent 4c77b779c8f5496ef02c25acd502cf875c09d0b6

diff --git a/trac/ticket/query.py b/trac/ticket/query.py
--- a/trac/ticket/query.py
+++ b/trac/ticket/query.py
@@ -125,8 +125,15 @@ class Query(object):
         self.cols = [c for c in cols or [] if c in field_names or 
                      c == 'id']
         self.rows = [c for c in rows if c in field_names]
+
+        self.order = self.order or QueryModule(self.env).default_order
+        if self.order:
+            if self.order[0] == '-':
+                (self.order, self.desc) = (self.order[1:], 1)
+            elif self.order[0] == '+':
+                (self.order, self.desc) = (self.order[1:], 0)
         if self.order != 'id' and self.order not in field_names:
-            self.order = 'priority'
+            (self.order, self.desc) = ('priority', 0)
 
         if self.group not in field_names:
             self.group = None
@@ -849,6 +856,10 @@ class QueryModule(Component):
         default=None,
         doc="""List of columns to show in query unless defined by the query.
             Default is to let Trac calculate this internally. (''since 0.13'')""")
+    
+    default_order = Option('query', 'default_order',
+        default='priority',
+        doc="""The default order to use for queries. (''since 0.13'')""")
 
     # IContentConverter methods
 
diff --git a/trac/ticket/tests/query.py b/trac/ticket/tests/query.py
--- a/trac/ticket/tests/query.py
+++ b/trac/ticket/tests/query.py
@@ -101,7 +101,7 @@ ORDER BY COALESCE(priority.value,'')='',
         tickets = query.execute(self.req)
 
     def test_all_ordered_by_priority_desc(self):
-        query = Query(self.env, desc=1) # priority is default order
+        query = Query(self.env, order='priority', desc=1)
         sql, args = query.get_sql()
         self.assertEqualSQL(sql,
 """SELECT t.id AS id,t.summary AS summary,t.owner AS owner,t.type AS type,t.status AS status,t.priority AS priority,t.milestone AS milestone,t.time AS time,t.changetime AS changetime,priority.value AS priority_value
@@ -498,6 +498,104 @@ ORDER BY COALESCE(t.id,0)=0,t.id""")
         self.assertEqual(['anonymous'], args)
         tickets = query.execute(self.req)
 
+    def test_default_order_no_config_with_request(self):
+        query = Query(self.env, order='summary')
+        sql, args = query.get_sql()
+        self.assertEqualSQL(sql,
+"""SELECT t.id AS id,t.summary AS summary,t.owner AS owner,t.type AS type,t.status AS status,t.priority AS priority,t.milestone AS milestone,t.time AS time,t.changetime AS changetime,priority.value AS priority_value
+FROM ticket AS t
+  LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND priority.name=priority)
+ORDER BY COALESCE(t.summary,'')='',t.summary,t.id""")
+        self.assertEqual([], args)
+        tickets = query.execute(self.req)
+
+    def test_default_order_no_config_no_request(self):
+        query = Query(self.env)
+        sql, args = query.get_sql()
+        self.assertEqualSQL(sql,
+"""SELECT t.id AS id,t.summary AS summary,t.owner AS owner,t.type AS type,t.status AS status,t.priority AS priority,t.milestone AS milestone,t.time AS time,t.changetime AS changetime,priority.value AS priority_value
+FROM ticket AS t
+  LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND priority.name=priority)
+ORDER BY COALESCE(priority.value,'')='',CAST(priority.value AS integer),t.id""")
+        self.assertEqual([], args)
+        tickets = query.execute(self.req)
+
+    def test_default_order_with_config_with_request(self):
+        self.env.config.set('query', 'default_order', 'type')
+        query = Query(self.env, order='summary')
+        sql, args = query.get_sql()
+        self.assertEqualSQL(sql,
+"""SELECT t.id AS id,t.summary AS summary,t.owner AS owner,t.type AS type,t.status AS status,t.priority AS priority,t.milestone AS milestone,t.time AS time,t.changetime AS changetime,priority.value AS priority_value
+FROM ticket AS t
+  LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND priority.name=priority)
+ORDER BY COALESCE(t.summary,'')='',t.summary,t.id""")
+        self.assertEqual([], args)
+        tickets = query.execute(self.req)
+
+    def test_default_order_with_config_no_request(self):
+        self.env.config.set('query', 'default_order', 'time')
+        query = Query(self.env)
+        sql, args = query.get_sql()
+        self.assertEqualSQL(sql,
+"""SELECT t.id AS id,t.summary AS summary,t.owner AS owner,t.type AS type,t.status AS status,t.priority AS priority,t.milestone AS milestone,t.time AS time,t.changetime AS changetime,priority.value AS priority_value
+FROM ticket AS t
+  LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND priority.name=priority)
+ORDER BY COALESCE(t.time,0)=0,t.time,t.id""")
+        self.assertEqual([], args)
+        tickets = query.execute(self.req)
+
+    def test_default_order_with_config_no_request_desc(self):
+        self.env.config.set('query', 'default_order', '-time')
+        query = Query(self.env)
+        sql, args = query.get_sql()
+        self.assertEqualSQL(sql,
+"""SELECT t.id AS id,t.summary AS summary,t.owner AS owner,t.type AS type,t.status AS status,t.priority AS priority,t.milestone AS milestone,t.time AS time,t.changetime AS changetime,priority.value AS priority_value
+FROM ticket AS t
+  LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND priority.name=priority)
+ORDER BY COALESCE(t.time,0)=0 DESC,t.time DESC,t.id""")
+        self.assertEqual([], args)
+        tickets = query.execute(self.req)
+
+    def test_default_order_invalid_field_1(self):
+        # invalid argument and no config
+        query = Query(self.env, order='foo', desc=1)
+        self.assertEqual('priority', query.order)
+        self.assertEqual(0, query.desc)
+
+    def test_default_order_invalid_field_2(self):
+        # valid argument and no config
+        query = Query(self.env, order='status')
+        self.assertEqual('status', query.order)
+        self.assertEqual(0, query.desc)
+
+    def test_default_order_invalid_field_3(self):
+        # no argument and invalid config
+        self.env.config.set('query', 'default_order', '-foo')
+        query = Query(self.env)
+        self.assertEqual('priority', query.order)
+        self.assertEqual(0, query.desc)
+
+    def test_default_order_invalid_field_4(self):
+        # invalid argument and invalid config
+        self.env.config.set('query', 'default_order', '-foo')
+        query = Query(self.env, order='bar')
+        self.assertEqual('priority', query.order)
+        self.assertEqual(0, query.desc)
+
+    def test_default_order_invalid_field_5(self):
+        # invalid argument but valid config
+        self.env.config.set('query', 'default_order', '-milestone')
+        query = Query(self.env, order='bar')
+        self.assertEqual('milestone', query.order)
+        self.assertEqual(1, query.desc)
+
+    def test_default_order_invalid_field_6(self):
+        # valid argument and valid config
+        self.env.config.set('query', 'default_order', '-milestone')
+        query = Query(self.env, order='type')
+        self.assertEqual('type', query.order)
+        self.assertEqual(0, query.desc)
+
     def test_default_cols_with_config_no_request(self):
         self.env.config.set('query', 'default_columns', 'id,time,changetime,summary,milestone,type')
         query = Query(self.env)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.