Ticket #1601: simulate_offset_auto.diff

File simulate_offset_auto.diff, 2.2 kB (added by joelpearson, 9 months ago)

Workaround is on by default for certain databases, but can be forced on or off in config file

  • paginate.py

    old new  
    3131 
    3232log = logging.getLogger("turbogears.paginate") 
    3333 
     34# lists of databases that lack support for OFFSET 
     35# this will need to be updated periodically as modules change 
     36_so_no_offset = 'mssql maxdb sybase'.split() 
     37_sa_no_offset = 'mssql maxdb access'.split() 
     38 
     39# this is a global that is set the first time paginate() is called 
     40_simulate_offset = None 
     41 
    3442def paginate(var_name, default_order='', default_reversed=False, limit=10, 
    3543            allow_limit_override=False, max_pages=5, dynamic_limit=None): 
    3644    ''' 
     
    200208            # we replace the var with the sliced one 
    201209            endpoint = offset + limit_ 
    202210            log.debug("slicing data between %d and %d", offset, endpoint) 
    203             output[var_name] = var_data[offset:endpoint] 
    204211 
     212            global _simulate_offset 
     213            get = turbogears.config.get 
     214            if _simulate_offset is None: 
     215                _simulate_offset = get('paginate.simulate_offset', None) 
     216                if _simulate_offset is None: 
     217                    _simulate_offset = False 
     218                    so_db = get('sqlobject.dburi', 'NOMATCH:').split(':', 1)[0] 
     219                    sa_db = get('sqlalchemy.dburi', 'NOMATCH:').split(':', 1)[0] 
     220                    if so_db in _so_no_offset or sa_db in _sa_no_offset: 
     221                        _simulate_offset = True 
     222                        log.warning("simulating OFFSET, paginate may be slow") 
     223                        log.warning("to turn off, set " 
     224                                     "paginate.simulate_offset=False") 
     225 
     226            if _simulate_offset: 
     227                var_data_iter = iter(var_data[:endpoint]) 
     228                # skip over the number of records specified by offset 
     229                for i in range(offset):    
     230                    var_data_iter.next() 
     231                # return the records that remain 
     232                output[var_name] = list(var_data_iter) 
     233            else: 
     234                output[var_name] = var_data[offset:endpoint] 
     235 
    205236            return output 
    206237        return decorated 
    207238    return weak_signature_decorator(entangle)