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

Proposed by John A Meinel
Status: Merged
Merged at revision: 295
Proposed branch: lp:~jameinel/u1db/put_doc_if_newer_private_999574
Merge into: lp:u1db
Prerequisite: lp:~jameinel/u1db/whats_changed_999574
Diff against target: 396 lines (+77/-44)
13 files modified
include/u1db/u1db_internal.h (+3/-1)
src/u1db.c (+15/-7)
src/u1db_http_sync_target.c (+12/-6)
src/u1db_sync_target.c (+2/-2)
u1db/__init__.py (+3/-1)
u1db/backends/__init__.py (+2/-2)
u1db/backends/sqlite_backend.py (+3/-2)
u1db/sync.py (+4/-2)
u1db/tests/c_backend_wrapper.pyx (+9/-4)
u1db/tests/test_backends.py (+15/-10)
u1db/tests/test_c_backend.py (+1/-1)
u1db/tests/test_https.py (+2/-2)
u1db/tests/test_remote_sync_target.py (+6/-4)
To merge this branch: bzr merge lp:~jameinel/u1db/put_doc_if_newer_private_999574
Reviewer Review Type Date Requested Status
John O'Brien (community) Approve
Review via email: mp+106361@code.launchpad.net

Description of the change

This exposes the transaction_id stuff in put_doc_if_newer. This still is not a complete implementation, as it gets None as the trans_id from the sync code.

However, it is a step further, and should avoid more enormous diffs to review.

To post a comment you must log in.
310. By John A Meinel

Do the right thing with a const issue for the tmp variable.

311. By John A Meinel

Catch the other https tests.

Revision history for this message
John O'Brien (jdobrien) wrote :

+1 tastes great, less filling.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/u1db/u1db_internal.h'
2--- include/u1db/u1db_internal.h 2012-05-18 14:08:24 +0000
3+++ include/u1db/u1db_internal.h 2012-05-18 14:08:24 +0000
4@@ -182,6 +182,7 @@
5 * this document came from. (Can be NULL)
6 * @param replica_gen Generation of the replica. Only meaningful if
7 * replica_uid is set.
8+ * @param replica_trans_id Transaction id associated with generation.
9 * @param state (OUT) Return one of:
10 * U1DB_INSERTED The document is newer than what we have
11 * U1DB_SUPERSEDED We already have a newer document than what was passed
12@@ -193,7 +194,8 @@
13 */
14 int u1db__put_doc_if_newer(u1database *db, u1db_document *doc,
15 int save_conflict, const char *replica_uid,
16- int replica_gen, int *state, int *at_gen);
17+ int replica_gen, const char *replica_trans_id,
18+ int *state, int *at_gen);
19
20 /**
21 * Internal API, Get the global database rev.
22
23=== modified file 'src/u1db.c'
24--- src/u1db.c 2012-05-18 14:08:24 +0000
25+++ src/u1db.c 2012-05-18 14:08:24 +0000
26@@ -723,8 +723,8 @@
27
28 int
29 u1db__put_doc_if_newer(u1database *db, u1db_document *doc, int save_conflict,
30- const char *replica_uid, int replica_gen, int *state,
31- int *at_gen)
32+ const char *replica_uid, int replica_gen,
33+ const char *replica_trans_id, int *state, int *at_gen)
34 {
35 const char *stored_content = NULL, *stored_doc_rev = NULL;
36 int status = U1DB_INVALID_PARAMETER, store = 0;
37@@ -810,7 +810,8 @@
38 (stored_doc_rev != NULL));
39 }
40 if (status == U1DB_OK && replica_uid != NULL) {
41- status = u1db__set_sync_info(db, replica_uid, replica_gen, "T-sid");
42+ status = u1db__set_sync_info(db, replica_uid, replica_gen,
43+ replica_trans_id);
44 }
45 if (status == U1DB_OK && at_gen != NULL) {
46 status = u1db__get_generation(db, at_gen);
47@@ -1341,16 +1342,23 @@
48 status = SQLITE_OK;
49 *generation = 0;
50 *trans_id = strdup("");
51+ if (*trans_id == NULL) {
52+ status = U1DB_NOMEM;
53+ }
54 } else if (status == SQLITE_ROW) {
55 *generation = sqlite3_column_int(statement, 0);
56 // Note: We may want to handle the column containing NULL
57 tmp = (const char *)sqlite3_column_text(statement, 1);
58- *trans_id = strdup(tmp);
59+ if (tmp == NULL) {
60+ *trans_id = NULL;
61+ } else {
62+ *trans_id = strdup(tmp);
63+ if (*trans_id == NULL) {
64+ status = U1DB_NOMEM;
65+ }
66+ }
67 status = SQLITE_OK;
68 }
69- if (*trans_id == NULL) {
70- status = U1DB_NOMEM;
71- }
72 finish:
73 sqlite3_finalize(statement);
74 return status;
75
76=== modified file 'src/u1db_http_sync_target.c'
77--- src/u1db_http_sync_target.c 2012-05-18 14:08:24 +0000
78+++ src/u1db_http_sync_target.c 2012-05-18 14:08:24 +0000
79@@ -362,6 +362,7 @@
80 struct _http_state *state;
81 struct _http_request req = {0};
82 char *url = NULL;
83+ const char *tmp = NULL;
84 int status;
85 long http_code;
86 struct curl_slist *headers = NULL;
87@@ -455,12 +456,17 @@
88 *source_gen = json_object_get_int(obj);
89 obj = json_object_object_get(json, "source_transaction_id");
90 if (obj == NULL) {
91- status = U1DB_INVALID_HTTP_RESPONSE;
92- goto finish;
93- }
94- *trans_id = strdup(json_object_get_string(obj));
95- if (*trans_id == NULL) {
96- status = U1DB_NOMEM;
97+ *trans_id = NULL;
98+ } else {
99+ tmp = json_object_get_string(obj);
100+ if (tmp == NULL) {
101+ *trans_id = NULL;
102+ } else {
103+ *trans_id = strdup(tmp);
104+ if (*trans_id == NULL) {
105+ status = U1DB_NOMEM;
106+ }
107+ }
108 }
109 finish:
110 if (req.header_buffer != NULL) {
111
112=== modified file 'src/u1db_sync_target.c'
113--- src/u1db_sync_target.c 2012-05-18 14:08:24 +0000
114+++ src/u1db_sync_target.c 2012-05-18 14:08:24 +0000
115@@ -280,7 +280,7 @@
116 }
117 // fprintf(stderr, "Inserting %s from source\n", doc->doc_id);
118 status = u1db__put_doc_if_newer(se->db, doc, 0, se->source_replica_uid,
119- source_gen, &insert_state, &at_gen);
120+ source_gen, NULL, &insert_state, &at_gen);
121 if (insert_state == U1DB_INSERTED || insert_state == U1DB_CONVERGED) {
122 lh_table_insert(se->seen_ids, strdup(doc->doc_id), (void *)(intptr_t)at_gen);
123 } else {
124@@ -437,7 +437,7 @@
125 state = (struct _return_doc_state *)context;
126
127 status = u1db__put_doc_if_newer(state->db, doc, 1, state->target_uid, gen,
128- &insert_state, NULL);
129+ NULL, &insert_state, NULL);
130 u1db_free_doc(&doc);
131 if (status == U1DB_OK) {
132 if (insert_state == U1DB_INSERTED || insert_state == U1DB_CONFLICTED) {
133
134=== modified file 'u1db/__init__.py'
135--- u1db/__init__.py 2012-05-18 14:08:24 +0000
136+++ u1db/__init__.py 2012-05-18 14:08:24 +0000
137@@ -248,7 +248,7 @@
138 raise NotImplementedError(self._set_sync_info)
139
140 def _put_doc_if_newer(self, doc, save_conflict, replica_uid=None,
141- replica_gen=None):
142+ replica_gen=None, replica_trans_id=None):
143 """Insert/update document into the database with a given revision.
144
145 This api is used during synchronization operations.
146@@ -273,6 +273,8 @@
147 :param replica_gen: The generation of the replica corresponding to the
148 this document. The replica arguments are optional, but are used
149 during synchronization.
150+ :param replica_trans_id: The transaction_id associated with the
151+ generation.
152 :return: (state, at_gen) - If we don't have doc_id already,
153 or if doc_rev supersedes the existing document revision,
154 then the content will be inserted, and state is 'inserted'.
155
156=== modified file 'u1db/backends/__init__.py'
157--- u1db/backends/__init__.py 2012-05-18 14:08:24 +0000
158+++ u1db/backends/__init__.py 2012-05-18 14:08:24 +0000
159@@ -91,7 +91,7 @@
160 return result
161
162 def _put_doc_if_newer(self, doc, save_conflict, replica_uid=None,
163- replica_gen=None):
164+ replica_gen=None, replica_trans_id=None):
165 cur_doc = self._get_doc(doc.doc_id)
166 doc_vcr = VectorClockRev(doc.rev)
167 if cur_doc is None:
168@@ -115,7 +115,7 @@
169 if save_conflict:
170 self._force_doc_sync_conflict(doc)
171 if replica_uid is not None and replica_gen is not None:
172- self._do_set_sync_info(replica_uid, replica_gen, 'T-sid')
173+ self._do_set_sync_info(replica_uid, replica_gen, replica_trans_id)
174 return state, self._get_generation()
175
176 def _ensure_maximal_rev(self, cur_rev, extra_revs):
177
178=== modified file 'u1db/backends/sqlite_backend.py'
179--- u1db/backends/sqlite_backend.py 2012-05-18 14:08:24 +0000
180+++ u1db/backends/sqlite_backend.py 2012-05-18 14:08:24 +0000
181@@ -438,11 +438,12 @@
182 other_transaction_id))
183
184 def _put_doc_if_newer(self, doc, save_conflict, replica_uid=None,
185- replica_gen=None):
186+ replica_gen=None, replica_trans_id=None):
187 with self._db_handle:
188 return super(SQLiteDatabase, self)._put_doc_if_newer(doc,
189 save_conflict=save_conflict,
190- replica_uid=replica_uid, replica_gen=replica_gen)
191+ replica_uid=replica_uid, replica_gen=replica_gen,
192+ replica_trans_id=replica_trans_id)
193
194 def _add_conflict(self, c, doc_id, my_doc_rev, my_content):
195 c.execute("INSERT INTO conflicts VALUES (?, ?, ?)",
196
197=== modified file 'u1db/sync.py'
198--- u1db/sync.py 2012-05-18 14:08:24 +0000
199+++ u1db/sync.py 2012-05-18 14:08:24 +0000
200@@ -53,7 +53,8 @@
201 # Increases self.num_inserted depending whether the document
202 # was effectively inserted.
203 state, _ = self.source._put_doc_if_newer(doc, save_conflict=True,
204- replica_uid=self.target_replica_uid, replica_gen=replica_gen)
205+ replica_uid=self.target_replica_uid, replica_gen=replica_gen,
206+ replica_trans_id=None)
207 if state == 'inserted':
208 self.num_inserted += 1
209 elif state == 'converged':
210@@ -166,7 +167,8 @@
211 :return: None
212 """
213 state, at_gen = self._db._put_doc_if_newer(doc, save_conflict=False,
214- replica_uid=self.source_replica_uid, replica_gen=source_gen)
215+ replica_uid=self.source_replica_uid, replica_gen=source_gen,
216+ replica_trans_id=None)
217 if state == 'inserted':
218 self.seen_ids[doc.doc_id] = at_gen
219 elif state == 'converged':
220
221=== modified file 'u1db/tests/c_backend_wrapper.pyx'
222--- u1db/tests/c_backend_wrapper.pyx 2012-05-18 14:08:24 +0000
223+++ u1db/tests/c_backend_wrapper.pyx 2012-05-18 14:08:24 +0000
224@@ -78,7 +78,8 @@
225 int u1db_put_doc(u1database *db, u1db_document *doc)
226 int u1db__put_doc_if_newer(u1database *db, u1db_document *doc,
227 int save_conflict, char *replica_uid,
228- int replica_gen, int *state, int *at_gen)
229+ int replica_gen, char *replica_trans_id,
230+ int *state, int *at_gen)
231 int u1db_resolve_doc(u1database *db, u1db_document *doc,
232 int n_revs, const_char_ptr *revs)
233 int u1db_delete_doc(u1database *db, u1db_document *doc)
234@@ -868,21 +869,25 @@
235 return doc.rev
236
237 def _put_doc_if_newer(self, CDocument doc, save_conflict, replica_uid=None,
238- replica_gen=None):
239- cdef char *c_uid
240+ replica_gen=None, replica_trans_id=None):
241+ cdef char *c_uid, *c_trans_id
242 cdef int gen, state = 0, at_gen = -1
243
244 if replica_uid is None:
245 c_uid = NULL
246 else:
247 c_uid = replica_uid
248+ if replica_trans_id is None:
249+ c_trans_id = NULL
250+ else:
251+ c_trans_id = replica_trans_id
252 if replica_gen is None:
253 gen = 0
254 else:
255 gen = replica_gen
256 handle_status("Failed to _put_doc_if_newer",
257 u1db__put_doc_if_newer(self._db, doc._doc, save_conflict,
258- c_uid, gen, &state, &at_gen))
259+ c_uid, gen, c_trans_id, &state, &at_gen))
260 if state == U1DB_INSERTED:
261 return 'inserted', at_gen
262 elif state == U1DB_SUPERSEDED:
263
264=== modified file 'u1db/tests/test_backends.py'
265--- u1db/tests/test_backends.py 2012-05-18 14:08:24 +0000
266+++ u1db/tests/test_backends.py 2012-05-18 14:08:24 +0000
267@@ -301,22 +301,25 @@
268 nested_doc)
269 self.assertEqual('inserted',
270 self.db._put_doc_if_newer(doc2, save_conflict=False,
271- replica_uid='other', replica_gen=2)[0])
272- self.assertEqual(2, self.db._get_sync_gen_info('other')[0])
273+ replica_uid='other', replica_gen=2,
274+ replica_trans_id='T-id2')[0])
275+ self.assertEqual((2, 'T-id2'), self.db._get_sync_gen_info('other'))
276 # Compare to the old rev, should be superseded
277 doc2 = self.make_document(doc1.doc_id, doc1.rev, nested_doc)
278 self.assertEqual('superseded',
279 self.db._put_doc_if_newer(doc2, save_conflict=False,
280- replica_uid='other', replica_gen=3)[0])
281- self.assertEqual(3, self.db._get_sync_gen_info('other')[0])
282+ replica_uid='other', replica_gen=3,
283+ replica_trans_id='T-id3')[0])
284+ self.assertEqual((3, 'T-id3'), self.db._get_sync_gen_info('other'))
285 # A conflict that isn't saved still records the sync gen, because we
286 # don't need to see it again
287 doc2 = self.make_document(doc1.doc_id, doc1.rev + '|fourth:1',
288 nested_doc)
289 self.assertEqual('conflicted',
290 self.db._put_doc_if_newer(doc2, save_conflict=False,
291- replica_uid='other', replica_gen=4)[0])
292- self.assertEqual(4, self.db._get_sync_gen_info('other')[0])
293+ replica_uid='other', replica_gen=4,
294+ replica_trans_id='T-id4')[0])
295+ self.assertEqual((4, 'T-id4'), self.db._get_sync_gen_info('other'))
296
297 def test__get_sync_gen_info(self):
298 self.assertEqual((0, ''), self.db._get_sync_gen_info('other-db'))
299@@ -579,18 +582,20 @@
300
301 def test_put_doc_if_newer_replica_uid(self):
302 doc1 = self.db.create_doc(simple_doc)
303- self.db._set_sync_info('other', 1, 'T-sid')
304+ self.db._set_sync_info('other', 1, 'T-id')
305 doc2 = self.make_document(doc1.doc_id, doc1.rev + '|other:1',
306 nested_doc)
307 self.db._put_doc_if_newer(doc2, save_conflict=True,
308- replica_uid='other', replica_gen=2)
309+ replica_uid='other', replica_gen=2,
310+ replica_trans_id='T-id2')
311 # Conflict vs the current update
312 doc2 = self.make_document(doc1.doc_id, doc1.rev + '|third:3',
313 nested_doc)
314 self.assertEqual('conflicted',
315 self.db._put_doc_if_newer(doc2, save_conflict=True,
316- replica_uid='other', replica_gen=3)[0])
317- self.assertEqual(3, self.db._get_sync_gen_info('other')[0])
318+ replica_uid='other', replica_gen=3,
319+ replica_trans_id='T-id3')[0])
320+ self.assertEqual((3, 'T-id3'), self.db._get_sync_gen_info('other'))
321
322 def test_put_refuses_to_update_conflicted(self):
323 doc1 = self.db.create_doc(simple_doc)
324
325=== modified file 'u1db/tests/test_c_backend.py'
326--- u1db/tests/test_c_backend.py 2012-05-18 14:08:24 +0000
327+++ u1db/tests/test_c_backend.py 2012-05-18 14:08:24 +0000
328@@ -201,7 +201,7 @@
329 exc.insert_doc_from_source(doc, 10)
330 self.assertGetDoc(self.db, 'doc-id', 'replica:1', tests.simple_doc,
331 False)
332- self.assertEqual((10, 'T-sid'),
333+ self.assertEqual((10, None),
334 self.db._get_sync_gen_info('source-uid'))
335 self.assertEqual(['doc-id'], exc.get_seen_ids())
336
337
338=== modified file 'u1db/tests/test_https.py'
339--- u1db/tests/test_https.py 2012-05-18 14:08:24 +0000
340+++ u1db/tests/test_https.py 2012-05-18 14:08:24 +0000
341@@ -96,7 +96,7 @@
342 db = self.request_state._create_database('test')
343 remote_target = self.getSyncTarget('localhost', 'test')
344 try:
345- remote_target.record_sync_info('other-id', 2)
346+ remote_target.record_sync_info('other-id', 2, 'T-id')
347 except ssl.SSLError, e:
348 self.assertIn("certificate verify failed", str(e))
349 else:
350@@ -111,7 +111,7 @@
351 self.patch(http_client, 'CA_CERTS', self.cacert_pem)
352 remote_target = self.getSyncTarget('127.0.0.1', 'test')
353 self.assertRaises(http_client.CertificateError,
354- remote_target.record_sync_info, 'other-id', 2)
355+ remote_target.record_sync_info, 'other-id', 2, 'T-id')
356
357
358 load_tests = tests.load_with_scenarios
359
360=== modified file 'u1db/tests/test_remote_sync_target.py'
361--- u1db/tests/test_remote_sync_target.py 2012-05-18 14:08:24 +0000
362+++ u1db/tests/test_remote_sync_target.py 2012-05-18 14:08:24 +0000
363@@ -202,11 +202,13 @@
364 _put_doc_if_newer = db._put_doc_if_newer
365 trigger_ids = ['doc-here2']
366 def bomb_put_doc_if_newer(doc, save_conflict,
367- replica_uid=None, replica_gen=None):
368+ replica_uid=None, replica_gen=None,
369+ replica_trans_id=None):
370 if doc.doc_id in trigger_ids:
371 raise Exception
372 return _put_doc_if_newer(doc, save_conflict=save_conflict,
373- replica_uid=replica_uid, replica_gen=replica_gen)
374+ replica_uid=replica_uid, replica_gen=replica_gen,
375+ replica_trans_id=replica_trans_id)
376 self.patch(db, '_put_doc_if_newer', bomb_put_doc_if_newer)
377 remote_target = self.getSyncTarget('test')
378 other_changes = []
379@@ -222,7 +224,7 @@
380 return_doc_cb=receive_doc)
381 self.assertGetDoc(db, 'doc-here', 'replica:1', '{"value": "here"}',
382 False)
383- self.assertEqual((10, 'T-sid'), db._get_sync_gen_info('replica'))
384+ self.assertEqual((10, None), db._get_sync_gen_info('replica'))
385 self.assertEqual([], other_changes)
386 # retry
387 trigger_ids = []
388@@ -232,7 +234,7 @@
389 return_doc_cb=receive_doc)
390 self.assertGetDoc(db, 'doc-here2', 'replica:1', '{"value": "here2"}',
391 False)
392- self.assertEqual((11, 'T-sid'), db._get_sync_gen_info('replica'))
393+ self.assertEqual((11, None), db._get_sync_gen_info('replica'))
394 self.assertEqual(2, new_gen)
395 # bounced back to us
396 self.assertEqual([('doc-here', 'replica:1', '{"value": "here"}', 1)],

Subscribers

People subscribed via source and target branches