Latest Version: 0.9.6.2
/Users/bbangert/Programming/Python/WebHelpers/webhelpers/pagination/orm.py
0001"""ORM Wrappers"""
0002import inspect
0003from webhelpers.util import Partial
0004
0005orms = {}
0006try:
0007    import sqlobject
0008except:
0009    pass
0010else:
0011    orms['sqlobject'] = True
0012try:
0013    import sqlalchemy
0014except:
0015    pass
0016else:
0017    orms['sqlalchemy'] = True
0018
0019def get_wrapper(obj, *args, **kw):
0020    if isinstance(obj, (list, tuple)):
0021        return obj
0022    if orms.get('sqlobject'):
0023        if inspect.isclass(obj) and issubclass(obj, sqlobject.SQLObject):
0024            return SQLObjectLazy(obj.select, *args, **kw)
0025    if orms.get('sqlalchemy'):
0026        if hasattr(obj, '_is_primary_mapper') or              (not sqlalchemy.__version__.startswith('0.4') and               isinstance(obj, sqlalchemy.Query)):
0029            return SQLAlchemyLazyMapper(obj, *args, **kw)
0030        if hasattr(obj, 'mapper') and hasattr(obj, 'select') and hasattr(obj, 'count'):
0031            return SQLAlchemyLazyMapper(obj, *args, **kw)
0032        if isinstance(obj, sqlalchemy.Table):
0033            return SQLAlchemyLazyTable(obj, *args, **kw)
0034        if hasattr(obj, 'query'):
0035            return SQLAlchemy04LazySessionMapper(obj, *args, **kw)
0036        if '_session' in kw:
0037            return SQLAlchemy04LazyMapper(obj, *args, **kw)
0038    raise TypeError("You must call paginate() with either a sequence, an "
0039                    "SQLObject class or an SQLAlchemy query object.")
0040
0041
0042class SQLObjectLazy(Partial):
0043    def __getitem__(self, key):
0044        if not isinstance(key, slice):
0045            raise Exception, "SQLObjectLazy doesn't support getitem without slicing"
0046        return list(self()[key.start:key.stop])
0047
0048    def __len__(self):
0049        return self().count()
0050
0051class SQLAlchemyLazyTable(Partial):
0052    def __getitem__(self, key):
0053        if not isinstance(key, slice):
0054            raise Exception, "SQLAlchemyLazy doesn't support getitem without slicing"
0055        limit = key.stop - key.start
0056        offset = key.start
0057        fn = self.fn
0058        self.fn = fn.select
0059        results = self(limit=limit, offset=offset).execute()
0060        self.fn = fn
0061        return results
0062
0063    def __len__(self):
0064        s = self.fn.select(*self.args, **self.kw)
0065        return self.fn([func.count(1)], from_obj=[s])
0066
0067class SQLAlchemyLazyMapper(Partial):
0068    def __getitem__(self, key):
0069        if not isinstance(key, slice):
0070            raise Exception, "SQLAlchemyLazy doesn't support getitem without slicing"
0071        limit = key.stop - key.start
0072        offset = key.start
0073        fn = self.fn
0074        self.fn = fn.select
0075        results = self(limit=limit, offset=offset)
0076        self.fn = fn
0077        return results
0078
0079    def __len__(self):
0080        kw = {}
0081        for k, v in self.kw.iteritems():
0082            if k != 'order_by':
0083                kw[k] = v
0084        return self.fn.count(*self.args, **kw)
0085
0086class SQLAlchemy04LazySessionMapper(Partial):
0087    def __getitem__(self, key):
0088        if not isinstance(key, slice):
0089            raise Exception, "SQLAlchemyLazy doesn't support getitem without slicing"
0090        limit = key.stop - key.start
0091        offset = key.start
0092        fn = self.fn
0093        result = fn.query
0094        if self.args:
0095            result = result.filter(*self.args)
0096
0097        # Translate keyword args like 'order_by=blah' into func calls for SA 0.4
0098        # such that its .order_by(blah) on the query object
0099        for key, val in self.kw.iteritems():
0100            result = getattr(result, key)(val)
0101        return result.limit(limit).offset(offset).all()
0102
0103    def __len__(self):
0104        kw = {}
0105        fn = self.fn.query
0106        if self.args:
0107            fn = fn.filter(*self.args)
0108
0109        for key, val in self.kw.iteritems():
0110            fn = getattr(fn, key)(val)
0111        return fn.count()
0112
0113class SQLAlchemy04LazyMapper(Partial):
0114    def __getitem__(self, key):
0115        if not isinstance(key, slice):
0116            raise Exception, "SQLAlchemyLazy doesn't support getitem without slicing"
0117        Session = self.kw.pop('_session')
0118        limit = key.stop - key.start
0119        offset = key.start
0120        fn = self.fn
0121        result = Session.query(fn)
0122        if self.args:
0123            result = result.filter(*self.args)
0124
0125        # Translate keyword args like 'order_by=blah' into func calls for SA 0.4
0126        # such that its .order_by(blah) on the query object
0127        for key, val in self.kw.iteritems():
0128            result = getattr(result, key)(val)
0129        query = result.limit(limit).offset(offset)
0130        self.kw['_session'] = Session
0131        return query.all()
0132
0133    def __len__(self):
0134        Session = self.kw.pop('_session')
0135        kw = {}
0136        fn = Session.query(self.fn)
0137        if self.args:
0138            fn = fn.filter(*self.args)
0139
0140        for key, val in self.kw.iteritems():
0141            fn = getattr(fn, key)(val)
0142        count = fn.count()
0143        self.kw['_session'] = Session
0144        return count

Top