Skip to content

Commit e0d2932

Browse files
committed
Merge default to stable.
--HG-- branch : stable
2 parents a6fcb8b + 1c34c54 commit e0d2932

31 files changed

+938
-732
lines changed

ChangeLog.txt

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
1+
Version 0.8 (Aug 13, 2010)
2+
--------------------------
3+
4+
* The couchdb-replicate script has changed from being a poor man's version of
5+
continuous replication (predating it) to being a simple script to help
6+
kick off replication jobs across databases and servers.
7+
* Reinclude all http exception types in the 'couchdb' package's scope.
8+
* Replaced epydoc API docs by more extensive Sphinx-based documentation.
9+
* Request retries schedule and frequency are now customizable.
10+
* Allow more kinds of request errors to trigger a retry.
11+
* Improve wrapping of view results.
12+
* Added a `uuids()` method to the `client.Server` class (issue 122).
13+
* Tested with CouchDB 0.10 - 1.0 (and Python 2.4 - 2.7).
14+
15+
116
Version 0.7.0 (Apr 15, 2010)
2-
http://couchdb-python.googlecode.com/hg/?r=0.7.0
17+
----------------------------
318

419
* Breaking change: the dependency on `httplib2` has been replaced by
520
an internal `couchdb.http` library. This changes the API in several places.
@@ -17,9 +32,9 @@ http://couchdb-python.googlecode.com/hg/?r=0.7.0
1732
* Added an optional argument to the 'Database.compact` method to enable
1833
view compaction (the rest of issue 37).
1934

20-
Version 0.6.1
21-
http://couchdb-python.googlecode.com/hg/?r=0.6.1
22-
(Dec 14, 2009, from branches/0.6.x)
35+
36+
Version 0.6.1 (Dec 14, 2009)
37+
----------------------------
2338

2439
* Compatible with CouchDB 0.9.x and 0.10.x.
2540
* Removed debugging statement from `json` module (issue 82).
@@ -39,9 +54,8 @@ http://couchdb-python.googlecode.com/hg/?r=0.6.1
3954
* Make sure we always return UTF-8 from the view server (issue 81).
4055

4156

42-
Version 0.6
43-
http://couchdb-python.googlecode.com/hg/?r=0.6.0
44-
(Jul 2, 2009, from 0.6.x)
57+
Version 0.6 (Jul 2, 2009)
58+
-------------------------
4559

4660
* Compatible with CouchDB 0.9.x.
4761
* `schema.DictField` instances no longer need to be bound to a `Schema`
@@ -76,9 +90,8 @@ http://couchdb-python.googlecode.com/hg/?r=0.6.0
7690
to see all communication between CouchDB and the view server (issue 55).
7791

7892

79-
Version 0.5
80-
http://couchdb-python.googlecode.com/hg/?r=0.5.0
81-
(Nov 28, 2008, from 0.5.x)
93+
Version 0.5 (Nov 29, 2008)
94+
--------------------------
8295

8396
* `schema.Document` objects can now be used in the documents list passed to
8497
`client.Database.update()`.
@@ -110,9 +123,8 @@ http://couchdb-python.googlecode.com/hg/?r=0.5.0
110123
* The `keys` option for views is now supported (issue 35).
111124

112125

113-
Version 0.4
114-
http://couchdb-python.googlecode.com/hg/?r=0.4.0
115-
(Jun 28, 2008, from 0.4.x)
126+
Version 0.4 (Jun 28, 2008)
127+
--------------------------
116128

117129
* Updated for compatibility with CouchDB 0.8.0
118130
* Added command-line scripts for importing/exporting databases.
@@ -121,9 +133,8 @@ http://couchdb-python.googlecode.com/hg/?r=0.4.0
121133
* The `_view` prefix can now be omitted when specifying view names.
122134

123135

124-
Version 0.3
125-
http://couchdb-python.googlecode.com/hg/?r=0.3.0
126-
(Feb 6, 2008, from 0.3.x)
136+
Version 0.3 (Feb 6, 2008)
137+
-------------------------
127138

128139
* The `schema.Document` class now has a `view()` method that can be used to
129140
execute a CouchDB view and map the result rows back to objects of that
@@ -134,9 +145,8 @@ http://couchdb-python.googlecode.com/hg/?r=0.3.0
134145
* Add a `query()` classmethod to the `Document` class.
135146

136147

137-
Version 0.2
138-
http://couchdb-python.googlecode.com/hg/?r=0.2.0
139-
(Nov 21, 2007, from 0.2.x)
148+
Version 0.2 (Nov 21, 2007)
149+
--------------------------
140150

141151
* Added __len__ and __iter__ to the `schema.Schema` class to iterate
142152
over and get the number of items in a document or compound field.
@@ -162,8 +172,7 @@ http://couchdb-python.googlecode.com/hg/?r=0.2.0
162172
* Updated for compatibility with CouchDB release 0.7.0.
163173

164174

165-
Version 0.1
166-
http://couchdb-python.googlecode.com/hg/?r=0.1.0
167-
(Sep 23, 2007, from 0.1.x)
175+
Version 0.1 (Sep 23, 2007)
176+
--------------------------
168177

169178
* First public release.

MANIFEST.in

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
include COPYING
2+
include Makefile
23
include ChangeLog.txt
3-
include doc/api/*.*
4-
include doc/*.html
5-
include doc/conf/*.ini
4+
include doc/conf.py
5+
include doc/*.rst

Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.PHONY: test doc upload-doc
2+
3+
test:
4+
PYTHONPATH=. python couchdb/tests/__init__.py
5+
6+
doc:
7+
python setup.py build_sphinx
8+
9+
upload-doc:
10+
python setup.py upload_sphinx

couchdb/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
# This software is licensed as described in the file COPYING, which
77
# you should have received as part of this distribution.
88

9-
from couchdb.client import *
9+
from couchdb.client import Database, Document, Server
10+
from couchdb.http import HTTPError, PreconditionFailed, Resource, \
11+
ResourceConflict, ResourceNotFound, ServerError, Session, Unauthorized
1012

1113
try:
1214
__version__ = __import__('pkg_resources').get_distribution('CouchDB').version

couchdb/client.py

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
"""Python client API for CouchDB.
1010
11-
>>> server = Server('http://localhost:5984/')
11+
>>> server = Server()
1212
>>> db = server.create('python-tests')
1313
>>> doc_id, doc_rev = db.save({'type': 'Person', 'name': 'John Doe'})
1414
>>> doc = db[doc_id]
@@ -37,13 +37,13 @@
3737
__docformat__ = 'restructuredtext en'
3838

3939

40-
DEFAULT_BASE_URL = 'http://localhost:5984/'
40+
DEFAULT_BASE_URL = os.environ.get('COUCHDB_URL', 'http://localhost:5984/')
4141

4242

4343
class Server(object):
4444
"""Representation of a CouchDB server.
4545
46-
>>> server = Server('http://localhost:5984/')
46+
>>> server = Server()
4747
4848
This class behaves like a dictionary of databases. For example, to get a
4949
list of database names on the server, you can simply iterate over the
@@ -169,6 +169,19 @@ def tasks(self):
169169
status, headers, data = self.resource.get_json('_active_tasks')
170170
return data
171171

172+
def uuids(self, count=None):
173+
"""Retrieve a batch of uuids
174+
175+
:param count: a number of uuids to fetch
176+
(None -- get as many as the server sends)
177+
:return: a list of uuids
178+
"""
179+
if count is None:
180+
_, _, data = self.resource.get_json('_uuids')
181+
else:
182+
_, _, data = self.resource.get_json('_uuids', count=count)
183+
return data['uuids']
184+
172185
def create(self, name):
173186
"""Create a new database with the given name.
174187
@@ -205,7 +218,7 @@ def replicate(self, source, target, **options):
205218
class Database(object):
206219
"""Representation of a database on a CouchDB server.
207220
208-
>>> server = Server('http://localhost:5984/')
221+
>>> server = Server()
209222
>>> db = server.create('python-tests')
210223
211224
New documents can be added to the database using the `save()` method:
@@ -387,7 +400,11 @@ def save(self, doc, **options):
387400
:return: (id, rev) tuple of the save document
388401
:rtype: `tuple`
389402
"""
390-
_, _, data = self.resource.post_json(body=doc, **options)
403+
if '_id' in doc:
404+
func = self.resource(doc['_id']).put_json
405+
else:
406+
func = self.resource.post_json
407+
_, _, data = func(body=doc, **options)
391408
id, rev = data['id'], data.get('rev')
392409
doc['_id'] = id
393410
if rev is not None: # Not present for batch='ok'
@@ -400,7 +417,9 @@ def commit(self):
400417
immediate commits, this method can be used to ensure that any
401418
non-committed changes are committed to physical storage.
402419
"""
403-
_, _, data = self.resource.post_json('_ensure_full_commit')
420+
_, _, data = self.resource.post_json(
421+
'_ensure_full_commit',
422+
headers={'Content-Type': 'application/json'})
404423
return data
405424

406425
def compact(self, ddoc=None):
@@ -415,9 +434,11 @@ def compact(self, ddoc=None):
415434
:rtype: `bool`
416435
"""
417436
if ddoc:
418-
_, _, data = self.resource('_compact').post_json(ddoc)
437+
resource = self.resource('_compact', ddoc)
419438
else:
420-
_, _, data = self.resource.post_json('_compact')
439+
resource = self.resource('_compact')
440+
_, _, data = resource.post_json(
441+
headers={'Content-Type': 'application/json'})
421442
return data['ok']
422443

423444
def copy(self, src, dest):
@@ -467,7 +488,7 @@ def delete(self, doc):
467488
the document has been updated since it was retrieved, this method will
468489
raise a `ResourceConflict` exception.
469490
470-
>>> server = Server('http://localhost:5984/')
491+
>>> server = Server()
471492
>>> db = server.create('python-tests')
472493
473494
>>> doc = dict(type='Person', name='John Doe')
@@ -568,8 +589,8 @@ def get_attachment(self, id_or_doc, filename, default=None):
568589
:param filename: the name of the attachment file
569590
:param default: default value to return when the document or attachment
570591
is not found
571-
:return: the content of the attachment as a string, or the value of the
572-
`default` argument if the attachment is not found
592+
:return: a file-like object with read and close methods, or the value
593+
of the `default` argument if the attachment is not found
573594
:since: 0.4.1
574595
"""
575596
if isinstance(id_or_doc, basestring):
@@ -621,7 +642,7 @@ def query(self, map_fun, reduce_fun=None, language='javascript',
621642
wrapper=None, **options):
622643
"""Execute an ad-hoc query (a "temp view") against the database.
623644
624-
>>> server = Server('http://localhost:5984/')
645+
>>> server = Server()
625646
>>> db = server.create('python-tests')
626647
>>> db['johndoe'] = dict(type='Person', name='John Doe')
627648
>>> db['maryjane'] = dict(type='Person', name='Mary Jane')
@@ -664,7 +685,7 @@ def update(self, documents, **options):
664685
"""Perform a bulk update or insertion of the given documents using a
665686
single HTTP request.
666687
667-
>>> server = Server('http://localhost:5984/')
688+
>>> server = Server()
668689
>>> db = server.create('python-tests')
669690
>>> for doc in db.update([
670691
... Document(type='Person', name='John Doe'),
@@ -732,7 +753,7 @@ def update(self, documents, **options):
732753
def view(self, name, wrapper=None, **options):
733754
"""Execute a predefined view.
734755
735-
>>> server = Server('http://localhost:5984/')
756+
>>> server = Server()
736757
>>> db = server.create('python-tests')
737758
>>> db['gotham'] = dict(type='City', name='Gotham City')
738759
@@ -901,7 +922,7 @@ class ViewResults(object):
901922
This class allows the specification of ``key``, ``startkey``, and
902923
``endkey`` options using Python slice notation.
903924
904-
>>> server = Server('http://localhost:5984/')
925+
>>> server = Server()
905926
>>> db = server.create('python-tests')
906927
>>> db['johndoe'] = dict(type='Person', name='John Doe')
907928
>>> db['maryjane'] = dict(type='Person', name='Mary Jane')
@@ -960,19 +981,15 @@ def __getitem__(self, key):
960981
return ViewResults(self.view, options)
961982

962983
def __iter__(self):
963-
wrapper = self.view.wrapper
964-
for row in self.rows:
965-
if wrapper is not None:
966-
yield wrapper(row)
967-
else:
968-
yield row
984+
return iter(self.rows)
969985

970986
def __len__(self):
971987
return len(self.rows)
972988

973989
def _fetch(self):
974990
data = self.view._exec(self.options)
975-
self._rows = [Row(row) for row in data['rows']]
991+
wrapper = self.view.wrapper or Row
992+
self._rows = [wrapper(row) for row in data['rows']]
976993
self._total_rows = data.get('total_rows')
977994
self._offset = data.get('offset', 0)
978995

@@ -1049,8 +1066,11 @@ def doc(self):
10491066
return Document(doc)
10501067

10511068

1069+
SPECIAL_DB_NAMES = set(['_users'])
10521070
VALID_DB_NAME = re.compile(r'^[a-z][a-z0-9_$()+-/]*$')
10531071
def validate_dbname(name):
1072+
if name in SPECIAL_DB_NAMES:
1073+
return name
10541074
if not VALID_DB_NAME.match(name):
10551075
raise ValueError('Invalid database name')
10561076
return name

couchdb/design.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class ViewDefinition(object):
2727
with the definition in the application code.
2828
2929
>>> from couchdb import Server
30-
>>> server = Server('http://localhost:5984/')
30+
>>> server = Server()
3131
>>> db = server.create('python-tests')
3232
3333
>>> view = ViewDefinition('tests', 'all', '''function(doc) {

0 commit comments

Comments
 (0)