Example #1
0
    def save_doc(self, doc, encode=False, force_update=False, **params):
        """ Save a document. It will use the `_id` member of the document
        or request a new uuid from CouchDB. IDs are attached to
        documents on the client side because POST has the curious property of
        being automatically retried by proxies in the event of network
        segmentation and lost responses.

        @param doc: dict.  doc is updated
        with doc '_id' and '_rev' properties returned
        by CouchDB server when you save.
        @param force_update: boolean, if there is conlict, try to update
        with latest revision
        @param encode: Encode attachments if needed (depends on couchdb
        version)

        @return: new doc with updated revision an id
        """
        if '_attachments' in doc and encode:
            doc['_attachments'] = encode_attachments(doc['_attachments'])

        headers = params.get('headers', {})
        headers.setdefault('Content-Type', 'application/json')
        params['headers'] = headers

        if '_id' in doc:
            docid = escape_docid(doc['_id'])
            try:
                resp = self.res.put(docid, payload=json.dumps(doc), **params)
            except ResourceConflict:
                if not force_update:
                    raise
                rev = self.last_rev(doc['_id'])
                doc['_rev'] = rev
                resp = self.res.put(docid, payload=json.dumps(doc), **params)
        else:
            json_doc = json.dumps(doc)
            try:
                doc['_id'] = self.uuids.next()
                resp = self.res.put(doc['_id'], payload=json_doc, **params)
            except ResourceConflict:
                resp = self.res.post(payload=json_doc, **params)

        json_res = resp.json_body
        doc1 = {}
        for a, n in aliases.items():
            if a in json_res:
                doc1[n] = json_res[a]
        doc.update(doc1)
        return doc
Example #2
0
    def save_doc(self, doc, encode=False, force_update=False, **params):
        """ Save a document. It will use the `_id` member of the document
        or request a new uuid from CouchDB. IDs are attached to
        documents on the client side because POST has the curious property of
        being automatically retried by proxies in the event of network
        segmentation and lost responses.

        @param doc: dict.  doc is updated
        with doc '_id' and '_rev' properties returned
        by CouchDB server when you save.
        @param force_update: boolean, if there is conlict, try to update
        with latest revision
        @param encode: Encode attachments if needed (depends on couchdb
        version)

        @return: new doc with updated revision an id
        """
        if '_attachments' in doc and encode:
            doc['_attachments'] = encode_attachments(doc['_attachments'])

        headers = params.get('headers', {})
        headers.setdefault('Content-Type', 'application/json')
        params['headers'] = headers

        if '_id' in doc:
            docid = escape_docid(doc['_id'])
            try:
                resp = self.res.put(docid, payload=json.dumps(doc), **params)
            except ResourceConflict:
                if not force_update:
                    raise
                rev = self.last_rev(doc['_id'])
                doc['_rev'] = rev
                resp = self.res.put(docid, payload=json.dumps(doc), **params)
        else:
            json_doc = json.dumps(doc)
            try:
                doc['_id'] = self.uuids.next()
                resp = self.res.put(doc['_id'], payload=json_doc, **params)
            except ResourceConflict:
                resp = self.res.post(payload=json_doc, **params)

        json_res = resp.json_body
        doc1 = {}
        for a, n in aliases.items():
            if a in json_res:
                doc1[n] = json_res[a]
        doc.update(doc1)
        return doc
Example #3
0
def encode_params(params):
    """ encode parameters in json if needed """
    _params = {}
    if params:
        for name, value in params.items():
            if value is None:
                continue
            if name in ("key", "startkey", "endkey") or not isinstance(value, basestring):
                value = json.dumps(value).encode("utf-8")
            _params[name] = value
    return _params
Example #4
0
    def view(self, view_name, **params):
        try:
            dname, vname = view_name.split("/")
            path = "/_design/%s/_view/%s" % (dname, vname)
        except ValueError:
            path = view_name

        if "keys" in params:
            keys = params.pop("keys")
            return self.post(path, json.dumps({"keys": keys}, **params)).json_body

        return self.get(path, **params).json_body
Example #5
0
def encode_params(params):
    """ encode parameters in json if needed """
    _params = {}
    if params:
        for name, value in params.items():
            if value is None:
                continue
            if name in ('key', 'startkey', 'endkey') \
                    or not isinstance(value, basestring):
                value = json.dumps(value).encode('utf-8')
            _params[name] = value
    return _params
Example #6
0
    def view(self, view_name, **params):
        try:
            dname, vname = view_name.split("/")
            path = "/_design/%s/_view/%s" % (dname, vname)
        except ValueError:
            path = view_name

        if "keys" in params:
            keys = params.pop("keys")
            return self.res.post(path, json.dumps({"keys": keys}, **params)).json_body

        return self.res.get(path, **params).json_body
Example #7
0
    def save_docs(self, docs, all_or_nothing=False, use_uuids=True):
        """ Bulk save. Modify Multiple Documents With a Single Request

        @param docs: list of docs
        @param use_uuids: add _id in doc who don't have it already set.
        @param all_or_nothing: In the case of a power failure, when the
        database restarts either all the changes will have been saved or none
        of them. However, it does not do conflict checking, so the documents
        will.


        @return doc lists updated with new revision or raise BulkSaveError
        exception. You can access to doc created and docs in error as
        properties of this exception.
        """

        def is_id(doc):
            return '_id' in doc

        if use_uuids:
            noids = []
            for k, g in itertools.groupby(docs, is_id):
                if not k:
                    noids = list(g)

            for doc in noids:
                nextid = self.uuids.next()
                if nextid:
                    doc['_id'] = nextid

        payload = {"docs": docs}
        if all_or_nothing:
            payload["all-or-nothing"] = True

        # update docs
        res = self.res.post('/_bulk_docs', payload=json.dumps(payload),
                            headers={'Content-Type': 'application/json'})

        json_res = res.json_body
        errors = []
        for i, r in enumerate(json_res):
            if 'error' in r:
                doc1 = docs[i]
                doc1.update({'_id': r['id'],
                             '_rev': r['rev']})
                errors.append(doc1)
            else:
                docs[i].update({'_id': r['id'],
                                '_rev': r['rev']})

        if errors:
            raise BulkSaveError(docs, errors)
Example #8
0
    def save_docs(self, docs, all_or_nothing=False, use_uuids=True):
        """ Bulk save. Modify Multiple Documents With a Single Request

        @param docs: list of docs
        @param use_uuids: add _id in doc who don't have it already set.
        @param all_or_nothing: In the case of a power failure, when the database 
        restarts either all the changes will have been saved or none of them.
        However, it does not do conflict checking, so the documents will


        @return doc lists updated with new revision or raise BulkSaveError 
        exception. You can access to doc created and docs in error as properties
        of this exception.
        """
            
        def is_id(doc):
            return '_id' in doc
            
        if use_uuids:
            noids = []
            for k, g in itertools.groupby(docs, is_id):
                if not k:
                    noids = list(g)
                    
            for doc in noids:
                nextid = self.uuids.next()
                if nextid:
                    doc['_id'] = nextid
                    
        payload = { "docs": docs }
        if all_or_nothing:
            payload["all-or-nothing"] = True
            
        # update docs
        res = self.res.post('/_bulk_docs', payload=json.dumps(payload),
                    headers={'Content-Type': 'application/json'})
            
        json_res = res.json_body
        errors = []
        for i, r in enumerate(json_res):
            if 'error' in r:
                doc1 = docs[i]
                doc1.update({'_id': r['id'], 
                                '_rev': r['rev']})
                errors.append(doc1)
            else:
                docs[i].update({'_id': r['id'], 
                                '_rev': r['rev']})
                                
        if errors:
            raise BulkSaveError(docs, errors)