Merge lp:~chipaca/u1db/fail-on-dupe-indexes-homogeneously into lp:u1db

Proposed by John Lenton
Status: Merged
Approved by: John Lenton
Approved revision: 297
Merged at revision: 298
Proposed branch: lp:~chipaca/u1db/fail-on-dupe-indexes-homogeneously
Merge into: lp:u1db
Diff against target: 131 lines (+30/-4)
7 files modified
include/u1db/u1db.h (+1/-0)
src/u1db.c (+8/-2)
u1db/backends/inmemory.py (+2/-0)
u1db/backends/sqlite_backend.py (+6/-2)
u1db/errors.py (+4/-0)
u1db/tests/c_backend_wrapper.pyx (+3/-0)
u1db/tests/test_backends.py (+6/-0)
To merge this branch: bzr merge lp:~chipaca/u1db/fail-on-dupe-indexes-homogeneously
Reviewer Review Type Date Requested Status
John A Meinel (community) Approve
Review via email: mp+106506@code.launchpad.net

Description of the change

create_index now fails with more or less the same error across all backends.

To post a comment you must log in.
Revision history for this message
John A Meinel (jameinel) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 5/20/2012 2:59 AM, John Lenton wrote:
> John Lenton has proposed merging
> lp:~chipaca/u1db/fail-on-dupe-indexes-homogeneously into lp:u1db.
>
> Requested reviews: Ubuntu One hackers (ubuntuone-hackers)
>
> For more details, see:
> https://code.launchpad.net/~chipaca/u1db/fail-on-dupe-indexes-homogeneously/+merge/106506
>
> create_index now fails with more or less the same error across all
> backends.

I'm happy to get consistency, but I believe that if the index being
created is identical to what is already there, we want it to be a
no-op and to pass. So create becomes sort of an "ensure".

In the immediate term, though, we could certainly land this for
consistency between backends.

John
=:->
 review: approve
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk+46EgACgkQJdeBCYSNAAPrXQCfQcqgGTusTQbpFHUu4v8P7x4X
2x8An2KvPX4cZTLj8Cp/KrTyzXvjXb8k
=doqB
-----END PGP SIGNATURE-----

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.h'
2--- include/u1db/u1db.h 2012-05-18 15:12:42 +0000
3+++ include/u1db/u1db.h 2012-05-20 00:58:21 +0000
4@@ -65,6 +65,7 @@
5 #define U1DB_UNHANDLED_CHARACTERS -14
6 #define U1DB_MISSING_FIELD_SPECIFIER -15
7 #define U1DB_INVALID_FIELD_SPECIFIER -16
8+#define U1DB_DUPLICATE_INDEX_NAME -17
9 #define U1DB_INTERNAL_ERROR -999
10
11 // Used by put_doc_if_newer
12
13=== modified file 'src/u1db.c'
14--- src/u1db.c 2012-05-19 07:47:05 +0000
15+++ src/u1db.c 2012-05-20 00:58:21 +0000
16@@ -1673,7 +1673,7 @@
17 "INSERT INTO index_definitions VALUES (?, ?, ?)", -1,
18 &statement, NULL);
19 if (status != SQLITE_OK) {
20- return status;
21+ goto finish;
22 }
23 status = sqlite3_bind_text(statement, 1, index_name, -1, SQLITE_TRANSIENT);
24 if (status != SQLITE_OK) { goto finish; }
25@@ -1684,7 +1684,13 @@
26 SQLITE_TRANSIENT);
27 if (status != SQLITE_OK) { goto finish; }
28 status = sqlite3_step(statement);
29- if (status != SQLITE_DONE) { goto finish; }
30+ if (status != SQLITE_DONE) {
31+ if (status == SQLITE_CONSTRAINT) {
32+ // duplicate index definition
33+ status = U1DB_DUPLICATE_INDEX_NAME;
34+ }
35+ goto finish;
36+ }
37 status = sqlite3_reset(statement);
38 if (status != SQLITE_OK) { goto finish; }
39 }
40
41=== modified file 'u1db/backends/inmemory.py'
42--- u1db/backends/inmemory.py 2012-05-18 15:12:42 +0000
43+++ u1db/backends/inmemory.py 2012-05-20 00:58:21 +0000
44@@ -171,6 +171,8 @@
45 self.put_doc(doc)
46
47 def create_index(self, index_name, index_expression):
48+ if index_name in self._indexes:
49+ raise errors.IndexNameTakenError
50 index = InMemoryIndex(index_name, index_expression)
51 for doc_id, (doc_rev, doc) in self._docs.iteritems():
52 if doc is not None:
53
54=== modified file 'u1db/backends/sqlite_backend.py'
55--- u1db/backends/sqlite_backend.py 2012-05-18 15:12:42 +0000
56+++ u1db/backends/sqlite_backend.py 2012-05-20 00:58:21 +0000
57@@ -20,6 +20,7 @@
58 import os
59 import simplejson
60 from sqlite3 import dbapi2
61+import sys
62 import time
63 import uuid
64
65@@ -693,8 +694,11 @@
66 cur_fields = self._get_indexed_fields()
67 definition = [(index_name, idx, field)
68 for idx, field in enumerate(index_expression)]
69- c.executemany("INSERT INTO index_definitions VALUES (?, ?, ?)",
70- definition)
71+ try:
72+ c.executemany("INSERT INTO index_definitions VALUES (?, ?, ?)",
73+ definition)
74+ except dbapi2.IntegrityError as e:
75+ raise errors.IndexNameTakenError, e, sys.exc_info()[2]
76 new_fields = set([f for f in index_expression
77 if f not in cur_fields])
78 if new_fields:
79
80=== modified file 'u1db/errors.py'
81--- u1db/errors.py 2012-04-24 13:40:36 +0000
82+++ u1db/errors.py 2012-05-20 00:58:21 +0000
83@@ -69,6 +69,10 @@
84 wire_description = "database does not exist"
85
86
87+class IndexNameTakenError(U1DBError):
88+ """The given index name is already taken."""
89+
90+
91 class IndexDefinitionParseError(U1DBError):
92 """The index definition cannot be parsed."""
93
94
95=== modified file 'u1db/tests/c_backend_wrapper.pyx'
96--- u1db/tests/c_backend_wrapper.pyx 2012-05-18 15:12:42 +0000
97+++ u1db/tests/c_backend_wrapper.pyx 2012-05-20 00:58:21 +0000
98@@ -117,6 +117,7 @@
99 int U1DB_INVALID_JSON
100 int U1DB_INVALID_VALUE_FOR_INDEX
101 int U1DB_BROKEN_SYNC_STREAM
102+ int U1DB_DUPLICATE_INDEX_NAME
103 int U1DB_INTERNAL_ERROR
104
105 int U1DB_INSERTED
106@@ -564,6 +565,8 @@
107 raise errors.BrokenSyncStream()
108 if status == U1DB_CONFLICTED:
109 raise errors.ConflictedDoc()
110+ if status == U1DB_DUPLICATE_INDEX_NAME:
111+ raise errors.IndexNameTakenError()
112 raise RuntimeError('%s (status: %s)' % (context, status))
113
114
115
116=== modified file 'u1db/tests/test_backends.py'
117--- u1db/tests/test_backends.py 2012-05-19 07:47:05 +0000
118+++ u1db/tests/test_backends.py 2012-05-20 00:58:21 +0000
119@@ -665,6 +665,12 @@
120 self.assertEqual(
121 [doc], self.db.get_from_index('test-idx', [(u"valu\xe5",)]))
122
123+ def test_create_index_fails_if_name_taken(self):
124+ self.db.create_index('test-idx', ['key'])
125+ self.assertRaises(errors.IndexNameTakenError,
126+ self.db.create_index,
127+ 'test-idx', ['stuff'])
128+
129 def test_create_index_after_deleting_document(self):
130 doc = self.db.create_doc(simple_doc)
131 doc2 = self.db.create_doc(simple_doc)

Subscribers

People subscribed via source and target branches