Edgewall Software

Ticket #10178: trac_ordering-r2.patch

File trac_ordering-r2.patch, 6.5 KB (added by david@…, 6 years ago)

Second revision

  • (a) query.py.orig vs. (b) /usr/local/lib/python2.6/dist-packages/Trac-0.12.2-py2.6.egg/trac/ticket/query.py

    a b  
    7070            constraints = [constraints]
    7171        self.constraints = constraints
    7272        synonyms = TicketSystem(self.env).get_field_synonyms()
    73         self.order = synonyms.get(order, order)     # 0.11 compatibility
     73        if not isinstance(order, list):
     74            if order is None:
     75                order = []
     76            else:
     77                order = [order]
     78        if not isinstance(desc, list):
     79            if desc is None:
     80                desc = []
     81            else:
     82                desc = [desc]
     83
     84        self.order = [synonyms.get(o, o) for o in order]     # 0.11 compatibility
    7485        self.desc = desc
    7586        self.group = group
    7687        self.groupdesc = groupdesc
     
    121132        self.cols = [c for c in cols or [] if c in field_names or
    122133                     c == 'id']
    123134        self.rows = [c for c in rows if c in field_names]
    124         if self.order != 'id' and self.order not in field_names:
    125             self.order = 'priority'
     135        if 'id' not in self.order and not (set(self.order) & set(field_names)):
     136            self.order = ['priority']
    126137
    127138        if self.group not in field_names:
    128139            self.group = None
     
    138149   
    139150    @classmethod
    140151    def from_string(cls, env, string, **kw):
    141         kw_strs = ['order', 'group', 'page', 'max', 'format']
    142         kw_arys = ['rows']
    143         kw_bools = ['desc', 'groupdesc', 'verbose']
     152        def as_str(s):
     153            if isinstance(s, unicode):
     154                return s.encode('utf-8')
     155            return s
     156
     157        kw_strs = ['group', 'page', 'max', 'format']
     158        kw_bools = ['groupdesc', 'verbose']
     159        kw_arys_str = ['order', 'rows']
     160        kw_arys_bool = ['desc']
    144161        kw_synonyms = {'row': 'rows'}
    145162        # i18n TODO - keys will be unicode
    146163        synonyms = TicketSystem(env).get_field_synonyms()
    147164        constraints = [{}]
    148165        cols = []
    149166        report = None
    150         def as_str(s):
    151             if isinstance(s, unicode):
    152                 return s.encode('utf-8')
    153             return s
    154167        for filter_ in cls._clause_splitter.split(string):
    155168            if filter_ == 'or':
    156169                constraints.append({})
     
    177190                                for val in cls._item_splitter.split(values)]
    178191            if field in kw_strs:
    179192                kw[as_str(field)] = processed_values[0]
    180             elif field in kw_arys:
     193            elif field in kw_arys_str:
    181194                kw.setdefault(as_str(field), []).extend(processed_values)
     195            elif field in kw_arys_bool:
     196                kw.setdefault(as_str(field), []).extend([as_bool(p) for p in processed_values])
    182197            elif field in kw_bools:
    183198                kw[as_str(field)] = as_bool(processed_values[0])
    184199            elif field == 'col':
     
    254269
    255270        # Only display the first seven columns by default
    256271        cols = cols[:7]
    257         # Make sure the column we order by is visible, if it isn't also
    258         # the column we group by
    259         if not self.order in cols and not self.order == self.group:
    260             cols[-1] = self.order
     272        # Make sure the columns we order by are visible, if they don't also
     273        # overlap the column we group by
     274        if not (set(self.order) & set(cols)) and not self.group in self.order:
     275            cols = [c for c in set(cols) | set(self.order)]
    261276        return cols
    262277
    263278    def count(self, req=None, db=None, cached_ids=None, authname=None,
     
    440455            add_cols(self.group)
    441456        if self.rows:
    442457            add_cols('reporter', *self.rows)
    443         add_cols('status', 'priority', 'time', 'changetime', self.order)
     458
     459        add_cols('status', 'priority', 'time', 'changetime', *self.order)
    444460        cols.extend([c for c in self.constraint_cols if not c in cols])
    445461
    446462        custom_fields = [f['name'] for f in self.fields if 'custom' in f]
     
    461477
    462478        # Join with the enum table for proper sorting
    463479        for col in [c for c in enum_columns
    464                     if c == self.order or c == self.group or c == 'priority']:
     480                    if c in self.order or c == self.group or c == 'priority']:
    465481            sql.append("\n  LEFT OUTER JOIN enum AS %s ON "
    466482                       "(%s.type='%s' AND %s.name=%s)"
    467483                       % (col, col, col, col, col))
    468484
    469485        # Join with the version/milestone tables for proper sorting
    470486        for col in [c for c in ['milestone', 'version']
    471                     if c == self.order or c == self.group]:
     487                    if c in self.order or c == self.group]:
    472488            sql.append("\n  LEFT OUTER JOIN %s ON (%s.name=%s)"
    473489                       % (col, col, col))
    474490
     
    619635                           (','.join([str(id) for id in cached_ids])))
    620636           
    621637        sql.append("\nORDER BY ")
    622         order_cols = [(self.order, self.desc)]
    623         if self.group and self.group != self.order:
     638        desc = self.desc + [
     639            0 for c in range(len(self.order) - len(self.desc))
     640            if len(self.order) > len(self.desc)
     641        ]
     642        order_cols = [(col, dsc) for col,dsc in zip(self.order, desc)]
     643        if self.group and self.group not in self.order:
    624644            order_cols.insert(0, (self.group, self.groupdesc))
    625645
     646        count = 0 
    626647        for name, desc in order_cols:
     648            count += 1
    627649            if name in enum_columns:
    628650                col = name + '.value'
    629651            elif name in custom_fields:
     
    652674                           % (desc, desc, col, desc))
    653675            else:
    654676                sql.append("%s%s" % (col, desc))
    655             if name == self.group and not name == self.order:
     677            if count != len(order_cols):
    656678                sql.append(",")
    657         if self.order != 'id':
     679        if 'id' not in self.order:
    658680            sql.append(",t.id") 
    659681
    660682        if errors:
    661683            raise QueryValueError(errors)
     684
    662685        return "".join(sql), args
    663686
    664687    @staticmethod
     
    715738            'name': col, 'label': labels.get(col, _('Ticket')),
    716739            'wikify': col in wikify,
    717740            'href': self.get_href(context.href, order=col,
    718                                   desc=(col == self.order and not self.desc))
     741                                  desc=(col in self.order and not self.desc))
    719742        } for col in cols]
    720743
    721744        fields = {'id': {'type': 'id', 'label': _("Ticket")}}