def listDoc(self, dbName, reverse=False, startkey=None, endkey=None, include_docs=False, limit=-1, **obsolete): """ List all documents in a given database. """ # Responses: {u'rows': [{u'_rev': -1825937535, u'_id': u'mydoc'}], # u'view': u'_all_docs'}, 404 Object Not Found import warnings if 'count' in obsolete: warnings.warn("listDoc 'count' parameter has been renamed to " "'limit' to reflect changing couchDB api", DeprecationWarning) limit = obsolete.pop('count') if obsolete: raise AttributeError("Unknown attribute(s): %r" % ( obsolete.keys(), )) uri = "/%s/_all_docs" % (dbName, ) args = {} if reverse: args["reverse"] = "true" if startkey: args["startkey"] = json.dumps(startkey) if endkey: args["endkey"] = json.dumps(endkey) if include_docs: args["include_docs"] = True if limit >= 0: args["limit"] = int(limit) if args: uri += "?%s" % (urlencode(args), ) return self.get(uri, descr='listDoc').addCallback(self.parseResult)
def openView(self, dbName, docId, viewId, **kwargs): """ Open a view of a document in a given database. """ # Responses: # 500 Internal Server Error (illegal database name) def buildUri(dbName=dbName, docId=docId, viewId=viewId, kwargs=kwargs): return "/%s/_design/%s/_view/%s?%s" % ( dbName, quote(docId), viewId, urlencode(kwargs)) # if there is a "keys" argument, remove it from the kwargs # dictionary now so that it doesn't get double JSON-encoded body = None if "keys" in kwargs: body = json.dumps({"keys": kwargs.pop("keys")}) # encode the rest of the values with JSON for use as query # arguments in the URI for k, v in kwargs.iteritems(): if k == 'keys': # we do this below, for the full body pass else: kwargs[k] = json.dumps(v) if 'count' in kwargs : # we keep the paisley API, but couchdb uses limit now kwargs['limit'] = kwargs.pop('count') # If there's a list of keys to send, POST the # query so that we can upload the keys as the body of # the POST request, otherwise use a GET request if body: return self.post(buildUri(), body=body, descr='openView').addCallback(self.parseResult) else: return self.get(buildUri(), descr='openView').addCallback(self.parseResult)
def saveDoc(self, dbName, body, docId=None): """ Save/create a document to/in a given database. @param dbName: identifier of the database. @type dbName: C{str} @param body: content of the document. @type body: C{str} or any structured object @param docId: if specified, the identifier to be used in the database. @type docId: C{unicode} """ # Responses: {'rev': '1-9dd776365618752ddfaf79d9079edf84', 'ok': True, 'id': '198abfee8852816bc112992564000295'} # 404 Object not found (if database does not exist) # 409 Conflict, 500 Internal Server Error if docId: # FIXME: remove these conversions and have our callers do them docId = unicode(docId) assert type(docId) is unicode, \ 'docId is %r instead of unicode' % (type(docId), ) if not isinstance(body, (str, unicode)): body = json.dumps(body) if docId is not None: d = self.put("/%s/%s" % (dbName, quote(docId.encode('utf-8'))), body, descr='saveDoc') else: d = self.post("/%s/" % (dbName, ), body, descr='saveDoc') return d.addCallback(self.parseResult)
def buildUri(dbName=dbName, docId=docId, viewId=viewId, kwargs=kwargs): result = "/%s/_design/%s/_view/%s" % (dbName, quote(docId), viewId) if kwargs: encoded = urlencode( dict((k, json.dumps(v)) for k, v in kwargs.iteritems())) result += '?' + encoded return result
def saveDoc(self, dbName, body, docId=None): """ Save/create a document to/in a given database. @param dbName: identifier of the database. @type dbName: C{str} @param body: content of the document. @type body: C{str} or any structured object @param docId: if specified, the identifier to be used in the database. @type docId: C{unicode} """ # Responses: {'rev': '1-9dd776365618752ddfaf79d9079edf84', # 'ok': True, 'id': '198abfee8852816bc112992564000295'} # 404 Object not found (if database does not exist) # 409 Conflict, 500 Internal Server Error if docId: # FIXME: remove these conversions and have our callers do them docId = unicode(docId) assert type(docId) is unicode, \ 'docId is %r instead of unicode' % (type(docId), ) if not isinstance(body, (str, unicode)): body = json.dumps(body) if docId is not None: d = self.put("/%s/%s" % (dbName, quote(docId.encode('utf-8'))), body, descr='saveDoc') else: d = self.post("/%s/" % (dbName, ), body, descr='saveDoc') return d.addCallback(self.parseResult)
def buildUri(dbName=dbName, docId=docId, viewId=viewId, kwargs=kwargs): result = "/%s/_design/%s/_view/%s" % (dbName, quote(docId), viewId) if kwargs: encoded = urlencode(dict((k, json.dumps(v)) for k, v in kwargs.iteritems())) result += '?' + encoded return result
def tempView(self, dbName, view): """ Make a temporary view on the server. """ if not isinstance(view, (str, unicode)): view = json.dumps(view) d = self.post("/%s/_temp_view" % (dbName, ), view, descr='tempView') return d.addCallback(self.parseResult)
def _test_listDB(self): data = [u"mydb"] self.resource.result = json.dumps(data) d = self.client.listDB() def cb(result): self.assertEquals(result, data) d.addCallback(cb) return d
def tempView(self, dbName, view): """ Make a temporary view on the server. """ if not isinstance(view, (str, unicode)): view = json.dumps(view) d = self.post("/%s/_temp_view" % (_namequote(dbName), ), view, descr='tempView') return d.addCallback(self.parseResult)
def tempView(self, dbName, view, **kw): """ Make a temporary view on the server. This one accepts query string parameters. """ encoded_args = '' if not kw else '?%s' % urllib.urlencode(kw) if not isinstance(view, (str, unicode)): view = json.dumps(view) d = self.post("/%s/_temp_view%s" % (dbName, encoded_args, ), view, descr='tempView') return d.addCallback(self.parseResult)
def test_listDB(self): """ Test listDB. """ data = [u"mydb"] self.resource.result = json.dumps(data) d = self.client.listDB() def cb(result): self.assertEquals(result, data) d.addCallback(cb) return d
def openView(self, dbName, docId, viewId, **kwargs): """ Open a view of a document in a given database. """ # Responses: # 500 Internal Server Error (illegal database name) def buildUri(dbName=dbName, docId=docId, viewId=viewId, kwargs=kwargs): return "/%s/_design/%s/_view/%s?%s" % ( _namequote(dbName), quote(docId), viewId, urlencode(kwargs)) # if there is a "keys" argument, remove it from the kwargs # dictionary now so that it doesn't get double JSON-encoded body = None if "keys" in kwargs: body = json.dumps({"keys": kwargs.pop("keys")}) # encode the rest of the values with JSON for use as query # arguments in the URI for k, v in kwargs.iteritems(): if k == 'keys': # we do this below, for the full body pass else: kwargs[k] = json.dumps(v) # we keep the paisley API, but couchdb uses limit now if 'count' in kwargs: kwargs['limit'] = kwargs.pop('count') # If there's a list of keys to send, POST the # query so that we can upload the keys as the body of # the POST request, otherwise use a GET request if body: return self.post(buildUri(), body=body, descr='openView').addCallback(self.parseResult) else: return self.get(buildUri(), descr='openView').addCallback(self.parseResult)
def listDoc(self, dbName, reverse=False, startkey=None, endkey=None, include_docs=False, limit=-1, **obsolete): """ List all documents in a given database. """ # Responses: {u'rows': [{u'_rev': -1825937535, u'_id': u'mydoc'}], # u'view': u'_all_docs'}, 404 Object Not Found import warnings if 'count' in obsolete: warnings.warn( "listDoc 'count' parameter has been renamed to " "'limit' to reflect changing couchDB api", DeprecationWarning) limit = obsolete.pop('count') if obsolete: raise AttributeError("Unknown attribute(s): %r" % (obsolete.keys(), )) uri = "/%s/_all_docs" % (_namequote(dbName), ) args = {} if reverse: args["reverse"] = "true" if startkey: args["startkey"] = json.dumps(startkey) if endkey: args["endkey"] = json.dumps(endkey) if include_docs: args["include_docs"] = True if limit >= 0: args["limit"] = int(limit) if args: uri += "?%s" % (urlencode(args), ) return self.get(uri, descr='listDoc').addCallback(self.parseResult)
def openView(self, dbName, docId, viewId, **kwargs): """ Open a view of a document in a given database. """ # Responses: # 500 Internal Server Error (illegal database name) def buildUri(dbName=dbName, docId=docId, viewId=viewId, kwargs=kwargs): return "/%s/_design/%s/_view/%s?%s" % ( dbName, quote(docId), viewId, urlencode(kwargs)) for k, v in kwargs.iteritems(): kwargs[k] = json.dumps(v) #couchdb requires this if "keys" in kwargs: body = {"keys": kwargs.pop("keys")} return self.post(buildUri(), body=body, descr='openView') else: return self.get(buildUri(), descr='openView').addCallback(self.parseResult)
def openView(self, dbName, docId, viewId, **kwargs): """ Open a view of a document in a given database. """ # Responses: # 500 Internal Server Error (illegal database name) def buildUri(dbName=dbName, docId=docId, viewId=viewId, kwargs=kwargs): return "/%s/_design/%s/_view/%s?%s" % (dbName, quote(docId), viewId, urlencode(kwargs)) for k, v in kwargs.iteritems(): kwargs[k] = json.dumps(v) #couchdb requires this if "keys" in kwargs: body = {"keys": kwargs.pop("keys")} return self.post(buildUri(), body=body, descr='openView') else: return self.get(buildUri(), descr='openView').addCallback(self.parseResult)
def openView(self, dbName, docId, viewId, **kwargs): """ Open a view of a document in a given database. """ # Responses: # 500 Internal Server Error (illegal database name) def buildUri(dbName=dbName, docId=docId, viewId=viewId, kwargs=kwargs): result = "/%s/_design/%s/_view/%s" % (dbName, quote(docId), viewId) if kwargs: encoded = urlencode(dict((k, json.dumps(v)) for k, v in kwargs.iteritems())) result += '?' + encoded return result if "keys" in kwargs: kwargs = dict(kwargs) body = json.dumps({"keys": kwargs.pop("keys")}) d = self.post(buildUri(kwargs=kwargs), body=body, descr='openView') else: d = self.get(buildUri(), descr='openView') d.addCallback(self.parseResult) return d
def openView(self, dbName, docId, viewId, **kwargs): """ Open a view of a document in a given database. """ # Responses: # 500 Internal Server Error (illegal database name) def buildUri(dbName=dbName, docId=docId, viewId=viewId, kwargs=kwargs): result = "/%s/_design/%s/_view/%s" % (dbName, quote(docId), viewId) if kwargs: encoded = urlencode( dict((k, json.dumps(v)) for k, v in kwargs.iteritems())) result += '?' + encoded return result if "keys" in kwargs: kwargs = dict(kwargs) body = json.dumps({"keys": kwargs.pop("keys")}) d = self.post(buildUri(kwargs=kwargs), body=body, descr='openView') else: d = self.get(buildUri(), descr='openView') d.addCallback(self.parseResult) return d
def doLater(self, args): root = self.getRootCommand() sourceUri = '/' + root.getDatabase() client = self.getRootCommand().getClient() # figure out target try: url = args[0] except IndexError: self.stdout.write('Please give a database to replicate to.\n') return # urlparse really needs a scheme there if not url.startswith('http'): url = 'http://' + url # if a username was given, but no password, ask for it parsed = urlparse.urlparse(url) self.log('url %s parsed to %r', url, parsed) # if password specified in URL, use it password = parsed.password # if password file given, use that if self.options.password_file: try: with open(self.options.password_file, "r") as handle: password = handle.read().strip() except: self.stderr.write( "ERROR: Could not read password from file %s\n" % ( self.options.password_file, )) # if still no password, prompt for it if we have a username too if parsed.username and not password: password = root.getPassword( prompt='\nPassword for target database %s: ' % url) # default to same db name on different host jane = urlrewrite.rewrite(url, hostname=HOST, port=PORT, password=password, path=sourceUri) self.log('remote url rewritten to %s', jane) # figure out source # sourceUri = '/' + root.getDatabase() # tarzan = client.url_template % sourceUri tarzan = root.getDatabase() self.log('local url rewritten to %s', tarzan) dbs = [] if self.options.direction in ['forward', 'both']: dbs.append((tarzan, jane)) if self.options.direction in ['backward', 'both']: dbs.append((jane, tarzan)) for source, target in dbs: s = json.dumps({ "source": source, "target": target, "continuous": self.options.type == 'continuous'}) self.info('replicating from %s to %s', urlrewrite.rewrite_safe(source), urlrewrite.rewrite_safe(target)) try: d = client.post('/_replicate', s) except Exception, e: self.stdout.write('Exception %r\n' % e) self.stdout.write( 'FAILED: local server failed for source %s\n' % source.encode('utf-8')) self.stdout.write('Is the server running ?\n') defer.returnValue(e) return error = None # set with a non-newline string in case of error try: result = yield d except twerror.Error, e: error = 'CouchDB returned error response %r' % e.status try: self.debug('CouchDB message: %r', e.message) r = json.loads(e.message) error = 'CouchDB returned error reason: %s' % r['reason'] except: pass
def doLater(self, args): c = self.getRootCommand() try: url = args[0] except IndexError: self.stdout.write('Please give a database to replicate with.\n') return # urlparse really needs a scheme there if not url.startswith('http'): url = 'http://' + url server = c.getNewServer() # FIXME: don't poke privately client = server._couch # if a username was given, but no password, ask for it parsed = urlparse.urlparse(url) password = None if parsed.username and not parsed.password: password = c.getPassword( prompt='\nPassword for target database %s: ' % url) jane = urlrewrite.rewrite(url, hostname=HOST, port=PORT, password=password, path='/' + DB) dbs = [ c.dbName, jane, ] for source, target in [(dbs[0], dbs[1]), (dbs[1], dbs[0])]: s = json.dumps({ "source": source, "target": target, "continuous": True}) self.info('replicating from %s to %s', urlrewrite.rewrite_safe(source), urlrewrite.rewrite_safe(target)) try: d = client.post('/_replicate', s) except Exception, e: self.stdout.write('Exception %r\n', e) self.stdout.write( 'FAILED: local server failed for source %s\n' % source.encode('utf-8')) self.stdout.write('Is the server running ?\n') defer.returnValue(e) return error = None # set with a non-newline string in case of error try: result = yield d except twerror.Error, e: error = 'CouchDB returned error response %r' % e.status try: self.debug('CouchDB message: %r', e.message) r = json.loads(e.message) error = 'CouchDB returned error reason: %s' % r['reason'] except: pass