(self, db, view_name, wrapper=None, cache_expire=COUCH_CACHE_TIMEOUT, force_invalidate=False,
                    **params)
Call a view and cache the results, return cached if it's a cache hit.

        db: couch database to do query on
        view_name, params: couch view call parameters
        force_invalidate: extra param to always hit the db and cache on read.

        Note, a view call with include_docs=True will not be wrapped, you must wrap it on your own.
Call a view and cache the results, return cached if it's a cache hit.
Call a view and cache the results return cached if it s a cache hit .
def cached_view(self, db, view_name, wrapper=None, cache_expire=COUCH_CACHE_TIMEOUT, force_invalidate=False,
                    **params):
        """
        Call a view and cache the results, return cached if it's a cache hit.

        db: couch database to do query on
        view_name, params: couch view call parameters
        force_invalidate: extra param to always hit the db and cache on read.

        Note, a view call with include_docs=True will not be wrapped, you must wrap it on your own.
        """
        from .api import cached_open_doc

        include_docs = params.get('include_docs', False)

        try:
            if force_invalidate:
                self.invalidate_all()
            cache_view_key = self._mk_view_cache_key(view_name, params)
            cached_view = rcache().get(cache_view_key, MISSING)
        except ConnectionInterrupted:
            cache_view_key = INTERRUPTED
            cached_view = INTERRUPTED

        is_cache_hit = cached_view not in (MISSING, INTERRUPTED) and CACHE_VIEWS
        if include_docs:
            # include_docs=True results in couchdbkit remove the 'rows' result
            # and returns just the actual rows in an array
            if is_cache_hit:
                results = simplejson.loads(cached_view)
                final_results = {}

                if include_docs:
                    row_stubs = results['row_stubs']

                    final_results['total_rows'] = results['total_rows']
                    final_results['offset'] = results['offset']

                    rows = []
                    for stub in row_stubs:
                        try:
                            row = {
                                "id": stub['id'],
                                "value": None,
                                "key": stub["key"],
                                # this feels hacky, but for some reason other views are squashing the master cached doc.
                                # a more true invalidation scheme should have this more readily address this, but for now
                                # do a db call here and cache it. Should be a _cached_doc_only call here
                                "doc": cached_open_doc(db, stub['id'])
                            }
                            rows.append(row)
                        except ResourceNotFound:
                            # maybe the doc was deleted just after we cached the view.
                            # in that scenario, just don't add it to the results rather than failing hard
                            pass
                    if wrapper:
                        final_results = [wrapper(x['doc']) for x in rows]
                    else:
                        final_results = rows
                return final_results
            else:
                # cache miss, get view, cache it and all docs
                view_obj = db.view(view_name, **params)
                # todo: we should try and decouple this from the "protected" methods of
                # couchdbkit's ViewResults
                view_obj._fetch_if_needed()
                view_results = view_obj._result_cache
                row_stubs = []

                for row in view_results["rows"]:
                    stub = {
                        "id": row['id'],
                        "value": None,
                        "key": row["key"],
                    }
                    self._cached_view_doc(row["doc"], cache_expire=cache_expire)
                    row_stubs.append(stub)

                cached_results = {
                    "total_rows": view_obj._total_rows,
                    "offset": view_obj._offset,
                    "row_stubs": row_stubs
                }

                if wrapper:
                    retval = [wrapper(x['doc']) for x in view_results['rows']]
                else:
                    retval = view_results['rows']
                if cached_view is not INTERRUPTED:
                    rcache().set(cache_view_key, simplejson.dumps(cached_results), timeout=cache_expire)
                return retval

        else:
            # include_docs=False just returns the entire view verbatim
            if is_cache_hit:
                results = simplejson.loads(cached_view)
                return results
            else:
                view_results = db.view(view_name, **params).all()
                if cached_view is not INTERRUPTED:
                    rcache().set(cache_view_key, simplejson.dumps(view_results), timeout=cache_expire)
                    for row in view_results:
                        doc_id = row.get('id', None)
                        if doc_id:
                            # a non reduce view will have doc_ids on each row, we want to reverse index these
                            # to know when to invalidate
                            self._cached_view_doc(doc_id)
                return view_results
def cached_view ( self , db , view_name , wrapper = None , cache_expire = COUCH_CACHE_TIMEOUT , force_invalidate = False , * * params ) : from . api import cached_open_doc include_docs = params . get ( 'include_docs' , False ) try : if force_invalidate : self . invalidate_all ( ) cache_view_key = self . _mk_view_cache_key ( view_name , params ) cached_view = rcache ( ) . get ( cache_view_key , MISSING ) except ConnectionInterrupted : cache_view_key = INTERRUPTED cached_view = INTERRUPTED is_cache_hit = cached_view not in ( MISSING , INTERRUPTED ) and CACHE_VIEWS if include_docs : # include_docs=True results in couchdbkit remove the 'rows' result # and returns just the actual rows in an array if is_cache_hit : results = simplejson . loads ( cached_view ) final_results = { } if include_docs : row_stubs = results [ 'row_stubs' ] final_results [ 'total_rows' ] = results [ 'total_rows' ] final_results [ 'offset' ] = results [ 'offset' ] rows = [ ] for stub in row_stubs : try : row = { "id" : stub [ 'id' ] , "value" : None , "key" : stub [ "key" ] , # this feels hacky, but for some reason other views are squashing the master cached doc. # a more true invalidation scheme should have this more readily address this, but for now # do a db call here and cache it. Should be a _cached_doc_only call here "doc" : cached_open_doc ( db , stub [ 'id' ] ) } rows . append ( row ) except ResourceNotFound : # maybe the doc was deleted just after we cached the view. # in that scenario, just don't add it to the results rather than failing hard pass if wrapper : final_results = [ wrapper ( x [ 'doc' ] ) for x in rows ] else : final_results = rows return final_results else : # cache miss, get view, cache it and all docs view_obj = db . view ( view_name , * * params ) # todo: we should try and decouple this from the "protected" methods of # couchdbkit's ViewResults view_obj . _fetch_if_needed ( ) view_results = view_obj . _result_cache row_stubs = [ ] for row in view_results [ "rows" ] : stub = { "id" : row [ 'id' ] , "value" : None , "key" : row [ "key" ] , } self . _cached_view_doc ( row [ "doc" ] , cache_expire = cache_expire ) row_stubs . append ( stub ) cached_results = { "total_rows" : view_obj . _total_rows , "offset" : view_obj . _offset , "row_stubs" : row_stubs } if wrapper : retval = [ wrapper ( x [ 'doc' ] ) for x in view_results [ 'rows' ] ] else : retval = view_results [ 'rows' ] if cached_view is not INTERRUPTED : rcache ( ) . set ( cache_view_key , simplejson . dumps ( cached_results ) , timeout = cache_expire ) return retval else : # include_docs=False just returns the entire view verbatim if is_cache_hit : results = simplejson . loads ( cached_view ) return results else : view_results = db . view ( view_name , * * params ) . all ( ) if cached_view is not INTERRUPTED : rcache ( ) . set ( cache_view_key , simplejson . dumps ( view_results ) , timeout = cache_expire ) for row in view_results : doc_id = row . get ( 'id' , None ) if doc_id : # a non reduce view will have doc_ids on each row, we want to reverse index these # to know when to invalidate self . _cached_view_doc ( doc_id ) return view_results