Edgewall Software

Ticket #2288: datetime-based-queries-1.patch

File datetime-based-queries-1.patch, 7.0 KB (added by ecarter, 18 months ago)

Ugly implementation attempt, incomplete.

  • trac-trunk/trac/ticket/api.py

     
    265265            field = {'name': name, 'type': 'text', 'label': name.title()} 
    266266            fields.append(field) 
    267267 
     268        # Date/Time fields 
     269        for name in ('time', 'changetime'): 
     270            field = {'name': name, 'type': 'time', 'label': name.title()} 
     271            fields.append(field) 
     272 
    268273        for field in self.get_custom_fields(): 
    269274            if field['name'] in [f['name'] for f in fields]: 
    270275                self.log.warning('Duplicate field name "%s" (ignoring)', 
  • trac-trunk/trac/ticket/web_ui.py

     
    934934            field.setdefault('optional', False) 
    935935            field.setdefault('options', []) 
    936936            field['skip'] = name in ('summary', 'reporter', 'description', 
    937                                      'status', 'resolution', 'owner') 
     937                                     'status', 'resolution', 'owner', 'time', 'changetime') 
    938938            fields.append(field) 
    939939 
    940940        data['author_id'] = author_id 
  • trac-trunk/trac/ticket/query.py

     
    6464            rows.append('description') 
    6565        self.fields = TicketSystem(self.env).get_ticket_fields() 
    6666        field_names = [f['name'] for f in self.fields] 
     67        #field_names.append('time') 
     68        #field_names.append('changetime') 
    6769        self.cols = [c for c in cols or [] if c in field_names or c == 'id'] 
    6870        self.rows = [c for c in rows if c in field_names] 
    6971 
     
    9799                raise QuerySyntaxError('Query filter requires field name') 
    98100            # from last char of `field`, get the mode of comparison 
    99101            mode, neg = '', '' 
    100             if field[-1] in ('~', '^', '$'): 
     102            if field[-1] in ('~', '^', '$', '@', '#'): 
    101103                mode = field[-1] 
    102104                field = field[:-1] 
    103105            if field[-1] == '!': 
     
    136138        # Prepare the default list of columns 
    137139        cols = ['id'] 
    138140        cols += [f['name'] for f in self.fields if f['type'] != 'textarea'] 
     141        #cols.append('time') 
     142        #cols.append('changetime') 
    139143        for col in ('reporter', 'keywords', 'cc'): 
    140144            if col in cols: 
    141145                cols.remove(col) 
    142146                cols.append(col) 
     147        import sys 
     148        sys.stderr.write("columns: %r\n" % (cols, )) 
    143149 
    144150        # Semi-intelligently remove columns that are restricted to a single 
    145151        # value by a query constraint. 
    146152        for col in [k for k in self.constraints.keys() 
    147153                    if k != 'id' and k in cols]: 
    148154            constraint = self.constraints[col] 
     155            sys.stderr.write("column %s has constraint %r\n" % (col, constraint)) 
    149156            if len(constraint) == 1 and constraint[0] \ 
    150                     and not constraint[0][0] in ('!', '~', '^', '$'): 
     157                    and not constraint[0][0] in ('!', '~', '^', '$', '@', '#'): 
    151158                if col in cols: 
    152159                    cols.remove(col) 
    153160            if col == 'status' and not 'closed' in constraint \ 
     
    156163        if self.group in cols: 
    157164            cols.remove(self.group) 
    158165 
     166        sys.stderr.write("columns afer removal: %r\n" % (cols, )) 
     167 
    159168        def sort_columns(col1, col2): 
    160169            constrained_fields = self.constraints.keys() 
    161170            # Ticket ID is always the first column 
     
    169178                return col1 in constrained_fields and -1 or 1 
    170179            return 0 
    171180        cols.sort(sort_columns) 
     181 
     182        sys.stderr.write("columns returned: %r\n" % (cols, )) 
    172183        return cols 
    173184 
    174185    def get_default_columns(self): 
     
    308319                name = name + '.value' 
    309320            value = value[len(mode) + neg:] 
    310321 
     322            import sys 
     323            sys.stderr.write("eli: %s %s %s %s\n" % (name, value, mode, neg)) 
     324 
    311325            if mode == '': 
    312326                return ("COALESCE(%s,'')%s=%%s" % (name, neg and '!' or ''), 
    313327                        value) 
     328 
     329            if mode == '@': 
     330                return ("%s<=%%s" % name, value) 
     331            elif mode == '#': 
     332                return ("%s>=%%s" % name, value) 
     333                 
    314334            if not value: 
    315335                return None 
    316336            db = self.env.get_db_cnx() 
     
    334354            # starts-with, negation, etc.) 
    335355            neg = v[0].startswith('!') 
    336356            mode = '' 
    337             if len(v[0]) > neg and v[0][neg] in ('~', '^', '$'): 
     357            if len(v[0]) > neg and v[0][neg] in ('~', '^', '$', '@', '#'): 
    338358                mode = v[0][neg] 
    339359 
    340360            # Special case id ranges 
     
    454474                if neg: 
    455475                    val = val[1:] 
    456476                mode = '' 
    457                 if val[:1] in ('~', '^', '$'): 
     477                if val[:1] in ('~', '^', '$', '@', '#'): 
    458478                    mode, val = val[:1], val[1:] 
    459479                constraint['mode'] = (neg and '!' or '') + mode 
    460480                constraint['values'].append(val) 
     
    495515            {'name': "is", 'value': ""}, 
    496516            {'name': "is not", 'value': "!"} 
    497517        ] 
     518        modes['time'] = [ 
     519            {'name': "before", 'value': "@"}, 
     520            {'name': "after", 'value': "#"}, 
     521            #{'name': "on", 'value': ""}, 
     522        ] 
    498523 
    499524        groups = {} 
    500525        groupsequence = [] 
  • trac-trunk/trac/ticket/templates/query.html

     
    105105                          <input type="text" name="${field_name}" value="$constraint_value" size="42" /> 
    106106                        </py:when> 
    107107 
     108                        <py:when test="'time'"> 
     109                          <input type="text" name="${field_name}" value="$constraint_value" size="42" /> 
     110                        </py:when> 
     111 
    108112                      </td> 
    109113                      <td class="actions" 
    110114                          py:with="rm_idx = multiline and constraint_idx or len(constraint['values']) - 1"><input 
  • trac-trunk/trac/htdocs/js/query.js

     
    224224        element.type = "text"; 
    225225        element.name = propertyName; 
    226226        element.size = 42; 
     227      } else if (property.type == "time") { 
     228        var element = document.createElement("input"); 
     229        element.type = "text"; 
     230        element.name = propertyName; 
     231        element.size = 42; 
    227232      } 
    228233      td.appendChild(element); 
    229234      element.focus();