Merge lp:~jameinel/u1db/delete_doc into lp:u1db

Proposed by John A Meinel
Status: Merged
Merged at revision: 128
Proposed branch: lp:~jameinel/u1db/delete_doc
Merge into: lp:u1db
Diff against target: 217 lines (+47/-44)
5 files modified
u1db/__init__.py (+2/-3)
u1db/backends/inmemory.py (+8/-8)
u1db/backends/sqlite_backend.py (+10/-7)
u1db/tests/test_backends.py (+17/-14)
u1db/tests/test_sync.py (+10/-12)
To merge this branch: bzr merge lp:~jameinel/u1db/delete_doc
Reviewer Review Type Date Requested Status
Samuele Pedroni Approve
Review via email: mp+83408@code.launchpad.net

Description of the change

Implement Database.delete_doc(Document)

I also updated this test:
    def test_delete_doc(self):
        doc = self.db.create_doc(simple_doc)
        self.assertGetDoc(self.db, doc.doc_id, doc.rev, simple_doc, False)
        orig_rev = doc.rev
        self.db.delete_doc(doc)
        self.assertNotEqual(orig_rev, doc.rev)
        self.assertGetDoc(self.db, doc.doc_id, doc.rev, None, False)
        self.assertIsNot(None, self.db.get_doc(doc.doc_id))

Adding that last line is to be clear that get_doc() should return a document with content = None.
assertGetDoc was already doing so, but it may be clearer if we do an explicit check.

To post a comment you must log in.
Revision history for this message
Samuele Pedroni (pedronis) wrote :

looks good, interestingly if I do this change:

=== modified file 'u1db/backends/inmemory.py'
--- u1db/backends/inmemory.py 2011-11-25 15:19:55 +0000
+++ u1db/backends/inmemory.py 2011-11-25 18:30:55 +0000
@@ -81,7 +81,7 @@
         for index in self._indexes.itervalues():
             if old_content is not None:
                 index.remove_json(doc_id, old_content)
- if content not in (None, 'null'):
+ if content not in (None,):
                 index.add_json(doc_id, content)
         self._docs[doc_id] = (new_rev, content)
         self._transaction_log.append(doc_id)
@@ -133,7 +133,7 @@
     def delete_doc(self, doc):
         if doc.doc_id not in self._docs:
             raise KeyError
- if self._docs[doc.doc_id][1] in ('null', None):
+ if self._docs[doc.doc_id][1] in (None,):
             raise KeyError
         doc.content = None
         self.put_doc(doc)

no tests fail as well

review: Approve
Revision history for this message
Samuele Pedroni (pedronis) wrote :

you'll get conflicts on RevisionConflict vs the old InvalidDocRev!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'u1db/__init__.py'
2--- u1db/__init__.py 2011-11-23 13:46:56 +0000
3+++ u1db/__init__.py 2011-11-25 15:23:27 +0000
4@@ -119,10 +119,9 @@
5 """
6 raise NotImplementedError(self.force_doc_sync_conflict)
7
8- def delete_doc(self, doc_id, old_doc_rev):
9+ def delete_doc(self, doc):
10 """Mark a document as deleted.
11- (might be equivalent to PUT(nil)). Will abort if the document is now
12- 'newer' than old_doc_rev.
13+ Will abort if the current revision doesn't match doc.rev.
14 """
15 raise NotImplementedError(self.delete_doc)
16
17
18=== modified file 'u1db/backends/inmemory.py'
19--- u1db/backends/inmemory.py 2011-11-23 12:39:32 +0000
20+++ u1db/backends/inmemory.py 2011-11-25 15:23:27 +0000
21@@ -98,7 +98,7 @@
22
23 def get_doc(self, doc_id):
24 doc = self._get_doc(doc_id)
25- if doc is None or doc.content == 'null':
26+ if doc is None:
27 return None
28 doc.has_conflicts = (doc.doc_id in self._conflicts)
29 return doc
30@@ -130,13 +130,13 @@
31 self._conflicts[doc_id] = remaining_conflicts
32 return new_rev, bool(remaining_conflicts)
33
34- def delete_doc(self, doc_id, doc_rev):
35- if doc_id not in self._docs:
36- raise KeyError
37- if self._docs[doc_id][1] in ('null', None):
38- raise KeyError
39- doc = Document(doc_id, doc_rev, None)
40- return self.put_doc(doc)
41+ def delete_doc(self, doc):
42+ if doc.doc_id not in self._docs:
43+ raise KeyError
44+ if self._docs[doc.doc_id][1] in ('null', None):
45+ raise KeyError
46+ doc.content = None
47+ self.put_doc(doc)
48
49 def create_index(self, index_name, index_expression):
50 index = InMemoryIndex(index_name, index_expression)
51
52=== modified file 'u1db/backends/sqlite_backend.py'
53--- u1db/backends/sqlite_backend.py 2011-11-23 13:46:56 +0000
54+++ u1db/backends/sqlite_backend.py 2011-11-25 15:23:27 +0000
55@@ -240,7 +240,7 @@
56
57 def get_doc(self, doc_id):
58 doc = self._get_doc(doc_id)
59- if doc is None or doc.content == 'null':
60+ if doc is None:
61 return None
62 # TODO: A doc which appears deleted could still have conflicts...
63 doc.has_conflicts = self._has_conflicts(doc.doc_id)
64@@ -317,19 +317,22 @@
65 doc_ids.add(doc_id)
66 return cur_gen, doc_ids
67
68- def delete_doc(self, doc_id, doc_rev):
69+ def delete_doc(self, doc):
70 with self._db_handle:
71- old_doc = self._get_doc(doc_id)
72+ old_doc = self._get_doc(doc.doc_id)
73 if old_doc is None:
74 raise KeyError
75- if old_doc.rev != doc_rev:
76+ if old_doc.rev != doc.rev:
77 raise errors.InvalidDocRev()
78 if old_doc.content is None:
79 raise KeyError
80- if self._has_conflicts(doc_id):
81+ if self._has_conflicts(doc.doc_id):
82 raise errors.ConflictedDoc()
83- new_rev = self._allocate_doc_rev(doc_rev)
84- self._put_and_update_indexes(doc_id, old_doc, new_rev, None)
85+ new_rev = self._allocate_doc_rev(doc.rev)
86+ self._put_and_update_indexes(doc.doc_id,
87+ old_doc.content, new_rev, None)
88+ doc.rev = new_rev
89+ doc.content = None
90 return new_rev
91
92 def _get_conflicts(self, doc_id):
93
94=== modified file 'u1db/tests/test_backends.py'
95--- u1db/tests/test_backends.py 2011-11-23 13:46:56 +0000
96+++ u1db/tests/test_backends.py 2011-11-25 15:23:27 +0000
97@@ -182,26 +182,29 @@
98 def test_delete_doc(self):
99 doc = self.db.create_doc(simple_doc)
100 self.assertGetDoc(self.db, doc.doc_id, doc.rev, simple_doc, False)
101- deleted_rev = self.db.delete_doc(doc.doc_id, doc.rev)
102- self.assertNotEqual(None, deleted_rev)
103- self.assertGetDoc(self.db, doc.doc_id, deleted_rev, None, False)
104+ orig_rev = doc.rev
105+ self.db.delete_doc(doc)
106+ self.assertNotEqual(orig_rev, doc.rev)
107+ self.assertGetDoc(self.db, doc.doc_id, doc.rev, None, False)
108+ self.assertIsNot(None, self.db.get_doc(doc.doc_id))
109
110 def test_delete_doc_non_existant(self):
111+ doc = Document('non-existing', 'other:1', simple_doc)
112 self.assertRaises(KeyError,
113- self.db.delete_doc, 'non-existing', 'other:1')
114+ self.db.delete_doc, doc)
115
116 def test_delete_doc_already_deleted(self):
117 doc = self.db.create_doc(simple_doc)
118- new_rev = self.db.delete_doc(doc.doc_id, doc.rev)
119- self.assertRaises(KeyError, self.db.delete_doc, doc.doc_id, new_rev)
120- self.assertGetDoc(self.db, doc.doc_id, new_rev, None, False)
121+ self.db.delete_doc(doc)
122+ self.assertRaises(KeyError, self.db.delete_doc, doc)
123+ self.assertGetDoc(self.db, doc.doc_id, doc.rev, None, False)
124
125 def test_delete_doc_bad_rev(self):
126- doc = self.db.create_doc(simple_doc)
127- self.assertGetDoc(self.db, doc.doc_id, doc.rev, simple_doc, False)
128- self.assertRaises(errors.InvalidDocRev,
129- self.db.delete_doc, doc.doc_id, 'other:1')
130- self.assertGetDoc(self.db, doc.doc_id, doc.rev, simple_doc, False)
131+ doc1 = self.db.create_doc(simple_doc)
132+ self.assertGetDoc(self.db, doc1.doc_id, doc1.rev, simple_doc, False)
133+ doc2 = Document(doc1.doc_id, 'other:1', simple_doc)
134+ self.assertRaises(errors.InvalidDocRev, self.db.delete_doc, doc2)
135+ self.assertGetDoc(self.db, doc1.doc_id, doc1.rev, simple_doc, False)
136
137 def test_put_updates_transaction_log(self):
138 doc = self.db.create_doc(simple_doc)
139@@ -215,7 +218,7 @@
140 def test_delete_updates_transaction_log(self):
141 doc = self.db.create_doc(simple_doc)
142 db_gen, _ = self.db.whats_changed()
143- self.db.delete_doc(doc.doc_id, doc.rev)
144+ self.db.delete_doc(doc)
145 self.assertEqual((2, set([doc.doc_id])), self.db.whats_changed(db_gen))
146
147 def test_whats_changed_initial_database(self):
148@@ -422,7 +425,7 @@
149 self.db.create_index('test-idx', ['key'])
150 self.assertEqual(sorted([doc, doc2]),
151 sorted(self.db.get_from_index('test-idx', [('value',)])))
152- self.db.delete_doc(doc.doc_id, doc.rev)
153+ self.db.delete_doc(doc)
154 self.assertEqual([doc2],
155 self.db.get_from_index('test-idx', [('value',)]))
156
157
158=== modified file 'u1db/tests/test_sync.py'
159--- u1db/tests/test_sync.py 2011-11-22 11:09:00 +0000
160+++ u1db/tests/test_sync.py 2011-11-25 15:23:27 +0000
161@@ -309,24 +309,24 @@
162 doc_id = doc1.doc_id
163 self.db1.create_index('test-idx', ['key'])
164 self.sync(self.db1, self.db2)
165- doc2_rev = doc1.rev
166+ doc2 = Document(doc1.doc_id, doc1.rev, doc1.content)
167 new_doc = '{"key": "altval"}'
168 doc1.content = new_doc
169 self.db1.put_doc(doc1)
170- doc2_rev = self.db2.delete_doc(doc_id, doc2_rev)
171+ self.db2.delete_doc(doc2)
172 self.assertEqual([doc_id, doc_id], self.db1._get_transaction_log())
173 self.sync(self.db1, self.db2)
174 self.assertEqual({'receive': {'docs': [(doc_id, doc1.rev)],
175 'from_id': 'test1',
176 'from_gen': 2, 'last_known_gen': 1},
177 'return': {'new_docs': [],
178- 'conf_docs': [(doc_id, doc2_rev)],
179+ 'conf_docs': [(doc_id, doc2.rev)],
180 'last_gen': 2}},
181 self.db2._last_exchange_log)
182 self.assertEqual([doc_id, doc_id, doc_id],
183 self.db1._get_transaction_log())
184- self.assertGetDoc(self.db1, doc_id, doc2_rev, None, True)
185- self.assertGetDoc(self.db2, doc_id, doc2_rev, None, False)
186+ self.assertGetDoc(self.db1, doc_id, doc2.rev, None, True)
187+ self.assertGetDoc(self.db2, doc_id, doc2.rev, None, False)
188 self.assertEqual([], self.db1.get_from_index('test-idx', [('value',)]))
189
190 def test_sync_local_race_conflicted(self):
191@@ -364,7 +364,8 @@
192 self.db2.create_index('test-idx', ['key'])
193 self.db3 = self.create_database('test3')
194 self.sync(self.db1, self.db3)
195- deleted_rev = self.db1.delete_doc(doc_id, doc1_rev)
196+ self.db1.delete_doc(doc1)
197+ deleted_rev = doc1.rev
198 self.sync(self.db1, self.db2)
199 self.assertEqual({'receive': {'docs': [(doc_id, deleted_rev)],
200 'from_id': 'test1',
201@@ -398,13 +399,10 @@
202
203 def test_delete_refuses_for_conflicted(self):
204 doc1 = self.db1.create_doc(simple_doc)
205- doc_id = doc1.doc_id
206- content1 = '{"key": "altval"}'
207- doc2 = self.db2.create_doc(content1, doc_id=doc_id)
208+ doc2 = self.db2.create_doc(nested_doc, doc_id=doc1.doc_id)
209 self.sync(self.db1, self.db2)
210- self.assertGetDoc(self.db1, doc_id, doc2.rev, content1, True)
211- self.assertRaises(errors.ConflictedDoc,
212- self.db1.delete_doc, doc_id, doc2.rev)
213+ self.assertGetDoc(self.db1, doc2.doc_id, doc2.rev, nested_doc, True)
214+ self.assertRaises(errors.ConflictedDoc, self.db1.delete_doc, doc2)
215
216 def test_get_doc_conflicts_unconflicted(self):
217 doc = self.db1.create_doc(simple_doc)

Subscribers

People subscribed via source and target branches