Merge lp://qastaging/~thisfred/desktopcouch/couchdb-conflicts into lp://qastaging/desktopcouch

Proposed by Eric Casteleijn
Status: Merged
Approved by: Elliot Murphy
Approved revision: 3
Merged at revision: not available
Proposed branch: lp://qastaging/~thisfred/desktopcouch/couchdb-conflicts
Merge into: lp://qastaging/desktopcouch
Diff against target: None lines
To merge this branch: bzr merge lp://qastaging/~thisfred/desktopcouch/couchdb-conflicts
Reviewer Review Type Date Requested Status
Elliot Murphy (community) Approve
Review via email: mp+8684@code.qastaging.launchpad.net

Commit message

[r=statik] Add new update_fields method.

To post a comment you must log in.
Revision history for this message
Eric Casteleijn (thisfred) wrote :

This provides a method 'update_fields' that allows guaranteed conflict free updating of certain fields in a record. This should be used everywhere that we don't care to handle conflicts ourselves. Caveat: Will overwrite values in the specified fields (but not other fields) rather than create conflict documents, which doesn't seem to be possible from couchdb-python.

3. By Eric Casteleijn

unchanged: attach bug

Revision history for this message
Elliot Murphy (statik) wrote :

looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'desktopcouch/records/server.py'
--- desktopcouch/records/server.py 2009-07-08 17:48:11 +0000
+++ desktopcouch/records/server.py 2009-07-13 12:22:21 +0000
@@ -21,10 +21,11 @@
21"""The Desktop Couch Records API."""21"""The Desktop Couch Records API."""
2222
23from couchdb import Server23from couchdb import Server
24from couchdb.client import ResourceNotFound24from couchdb.client import ResourceNotFound, ResourceConflict
2525
26from record import Record26from record import Record
2727
28
28class NoSuchDatabase(Exception):29class NoSuchDatabase(Exception):
29 "Exception for trying to use a non-existent database"30 "Exception for trying to use a non-existent database"
3031
@@ -67,23 +68,23 @@
67 '-p %s -s | cut -d" " -f7 | cut -d "," -f1) 2>/dev/null | ' + \68 '-p %s -s | cut -d" " -f7 | cut -d "," -f1) 2>/dev/null | ' + \
68 'grep "TCP " | grep LISTEN | ' + \69 'grep "TCP " | grep LISTEN | ' + \
69 'awk \'{print $8}\' | cut -d":" -f2'70 'awk \'{print $8}\' | cut -d":" -f2'
70 actual_lsof_cmd = lsofcmd % (local_files.FILE_INI, 71 actual_lsof_cmd = lsofcmd % (local_files.FILE_INI,
71 local_files.FILE_PID)72 local_files.FILE_PID)
72 stdout, stderr = subprocess.Popen(actual_lsof_cmd, shell=True,73 stdout, stderr = subprocess.Popen(actual_lsof_cmd, shell=True,
73 stdout=subprocess.PIPE).communicate()74 stdout=subprocess.PIPE).communicate()
74 port = stdout.strip()75 port = stdout.strip()
75 except:76 except:
76 port = 598477 port = 5984
77 if not port: 78 if not port:
78 port = 598479 port = 5984
79 return port80 return port
80 81
81 def query(self, map_fun, reduce_fun=None, language='javascript', 82 def query(self, map_fun, reduce_fun=None, language='javascript',
82 wrapper=None, **options):83 wrapper=None, **options):
83 """Pass-through to CouchDB query"""84 """Pass-through to CouchDB query"""
84 return self.db.query(map_fun, reduce_fun, language, 85 return self.db.query(map_fun, reduce_fun, language,
85 wrapper, **options)86 wrapper, **options)
86 87
87 def get_record(self, record_id):88 def get_record(self, record_id):
88 """Get a record from back end storage."""89 """Get a record from back end storage."""
89 try:90 try:
@@ -106,11 +107,24 @@
106 record_id = self._add_record(record_data)107 record_id = self._add_record(record_data)
107 return record_id108 return record_id
108109
110 def update_fields(self, doc_id, fields):
111 """Safely update a number of fields. 'fields' being a
112 dictionary with fieldname: value for only the fields we want
113 to change the value of.
114 """
115 while True:
116 doc = self.db[doc_id]
117 doc.update(fields)
118 try:
119 self.db[doc.id] = doc
120 except ResourceConflict:
121 continue
122 break
123
109 def _add_record(self, data):124 def _add_record(self, data):
110 """Add a new record to the storage backend."""125 """Add a new record to the storage backend."""
111 return self.db.create(data)126 return self.db.create(data)
112127
113 #FIXME: NEEDS TEST
114 def delete_record(self, record_id):128 def delete_record(self, record_id):
115 """Delete record with given id"""129 """Delete record with given id"""
116 record = self.db[record_id]130 record = self.db[record_id]
@@ -119,7 +133,6 @@
119 'deleted'] = True133 'deleted'] = True
120 self.db[record_id] = record134 self.db[record_id] = record
121135
122 #FIXME: NEEDS TEST
123 def record_exists(self, record_id):136 def record_exists(self, record_id):
124 """Check if record with given id exists"""137 """Check if record with given id exists"""
125 if record_id not in self.db:138 if record_id not in self.db:
126139
=== modified file 'desktopcouch/records/tests/test_server.py'
--- desktopcouch/records/tests/test_server.py 2009-07-08 17:48:11 +0000
+++ desktopcouch/records/tests/test_server.py 2009-07-13 12:22:21 +0000
@@ -80,3 +80,20 @@
80 self.assert_(self.database.record_exists(record_id))80 self.assert_(self.database.record_exists(record_id))
81 self.database.delete_record(record_id)81 self.database.delete_record(record_id)
82 self.assert_(not self.database.record_exists(record_id))82 self.assert_(not self.database.record_exists(record_id))
83
84 def test_update_fields(self):
85 """Test the update_fields method."""
86 dictionary = {'record_number': 0, 'field1': 1, 'field2': 2}
87 record = Record(dictionary, record_type="http://example.com/")
88 record_id = self.database.put_record(record)
89 # manipulate the database 'out of view'
90 non_working_copy = self.database.get_record(record_id)
91 non_working_copy['field2'] = 22
92 non_working_copy['field3'] = 3
93 self.database.put_record(non_working_copy)
94 self.database.update_fields(record_id, {'field1': 11})
95 working_copy = self.database.get_record(record_id)
96 self.assertEqual(0, working_copy['record_number'])
97 self.assertEqual(11, working_copy['field1'])
98 self.assertEqual(22, working_copy['field2'])
99 self.assertEqual(3, working_copy['field3'])

Subscribers

People subscribed via source and target branches