Merge lp:~thisfred/u1db/improve_get_from_index into lp:u1db
- improve_get_from_index
- Merge into trunk
Proposed by
Eric Casteleijn
Status: | Merged |
---|---|
Approved by: | Eric Casteleijn |
Approved revision: | 324 |
Merged at revision: | 321 |
Proposed branch: | lp:~thisfred/u1db/improve_get_from_index |
Merge into: | lp:u1db |
Diff against target: |
878 lines (+190/-213) 10 files modified
u1db/__init__.py (+4/-4) u1db/backends/inmemory.py (+7/-10) u1db/backends/sqlite_backend.py (+38/-41) u1db/commandline/client.py (+1/-1) u1db/tests/c_backend_wrapper.pyx (+29/-30) u1db/tests/test_backends.py (+93/-104) u1db/tests/test_c_backend.py (+2/-2) u1db/tests/test_inmemory.py (+2/-2) u1db/tests/test_sync.py (+9/-13) u1todo/u1todo.py (+5/-6) |
To merge this branch: | bzr merge lp:~thisfred/u1db/improve_get_from_index |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
John Lenton (community) | Approve | ||
Review via email: mp+108220@code.launchpad.net |
Commit message
changed get_from_index signature to take any number of arguments for the column values
Description of the change
changed get_from_index signature to take any number of arguments for the column values
Note that this does not touch the C implementation, which already uses varargs, which in fact we may want to change. The bug tracking that issue is lp:1006954
To post a comment you must log in.
Revision history for this message
John Lenton (chipaca) : | # |
review:
Approve
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 2012-05-31 16:31:31 +0000 |
3 | +++ u1db/__init__.py 2012-05-31 18:55:27 +0000 |
4 | @@ -177,7 +177,7 @@ |
5 | """ |
6 | raise NotImplementedError(self.list_indexes) |
7 | |
8 | - def get_from_index(self, index_name, key_values): |
9 | + def get_from_index(self, index_name, *key_values): |
10 | """Return documents that match the keys supplied. |
11 | |
12 | You must supply exactly the same number of values as has been defined |
13 | @@ -190,9 +190,9 @@ |
14 | |
15 | :return: List of [Document] |
16 | :param index_name: The index to query |
17 | - :param key_values: A list of tuple of values to match. eg, if you have |
18 | - an index with 3 field,s then you would have: |
19 | - [(x-val1, x-val2, x-val3), (y-val1, y-val2, y-val3), ...]) |
20 | + :param key_values: tuples of values to match. eg, if you have |
21 | + an index with 3 fields then you would have: |
22 | + (x-val1, x-val2, x-val3), (y-val1, y-val2, y-val3), ... |
23 | """ |
24 | raise NotImplementedError(self.get_from_index) |
25 | |
26 | |
27 | === modified file 'u1db/backends/inmemory.py' |
28 | --- u1db/backends/inmemory.py 2012-05-31 16:31:31 +0000 |
29 | +++ u1db/backends/inmemory.py 2012-05-31 18:55:27 +0000 |
30 | @@ -210,7 +210,7 @@ |
31 | definitions.append((idx._name, idx._definition)) |
32 | return definitions |
33 | |
34 | - def get_from_index(self, index_name, key_values): |
35 | + def get_from_index(self, index_name, *key_values): |
36 | try: |
37 | index = self._indexes[index_name] |
38 | except KeyError: |
39 | @@ -337,16 +337,13 @@ |
40 | return -1 |
41 | return last |
42 | |
43 | - def lookup(self, key_values): |
44 | + def lookup(self, values): |
45 | """Find docs that match the values.""" |
46 | - result = [] |
47 | - for values in key_values: |
48 | - last = self._find_non_wildcards(values) |
49 | - if last == -1: |
50 | - result.extend(self._lookup_exact(values)) |
51 | - else: |
52 | - result.extend(self._lookup_prefix(values[:last])) |
53 | - return result |
54 | + last = self._find_non_wildcards(values) |
55 | + if last == -1: |
56 | + return self._lookup_exact(values) |
57 | + else: |
58 | + return self._lookup_prefix(values[:last]) |
59 | |
60 | def keys(self): |
61 | """Find the indexed keys.""" |
62 | |
63 | === modified file 'u1db/backends/sqlite_backend.py' |
64 | --- u1db/backends/sqlite_backend.py 2012-05-31 16:31:31 +0000 |
65 | +++ u1db/backends/sqlite_backend.py 2012-05-31 18:55:27 +0000 |
66 | @@ -576,7 +576,7 @@ |
67 | assert value[-1] == '*' |
68 | return value[:-1] + '%' |
69 | |
70 | - def get_from_index(self, index_name, key_values): |
71 | + def get_from_index(self, index_name, *key_values): |
72 | definition = self._get_index_definition(index_name) |
73 | # First, build the definition. We join the document_fields table |
74 | # against itself, as many times as the 'width' of our definition. |
75 | @@ -596,50 +596,47 @@ |
76 | + (" AND d%d.value LIKE ? ESCAPE '.'" % (i,)) |
77 | for i in range(len(definition))] |
78 | c = self._db_handle.cursor() |
79 | - result = [] |
80 | is_wildcard = False |
81 | - for key_value in key_values: |
82 | - # Merge the lists together, so that: |
83 | - # [field1, field2, field3], [val1, val2, val3] |
84 | - # Becomes: |
85 | - # (field1, val1, field2, val2, field3, val3) |
86 | - args = [] |
87 | - where = [] |
88 | - if len(key_value) != len(definition): |
89 | - raise errors.InvalidValueForIndex() |
90 | - for idx, (field, value) in enumerate(zip(definition, key_value)): |
91 | - args.append(field) |
92 | - if value.endswith('*'): |
93 | - if value == '*': |
94 | - where.append(wildcard_where[idx]) |
95 | - else: |
96 | - # This is a glob match |
97 | - if is_wildcard: |
98 | - # We can't have a partial wildcard following |
99 | - # another wildcard |
100 | - raise errors.InvalidGlobbing |
101 | - where.append(like_where[idx]) |
102 | - args.append(self._transform_glob(value)) |
103 | - is_wildcard = True |
104 | + # Merge the lists together, so that: |
105 | + # [field1, field2, field3], [val1, val2, val3] |
106 | + # Becomes: |
107 | + # (field1, val1, field2, val2, field3, val3) |
108 | + args = [] |
109 | + where = [] |
110 | + if len(key_values) != len(definition): |
111 | + raise errors.InvalidValueForIndex() |
112 | + for idx, (field, value) in enumerate(zip(definition, key_values)): |
113 | + args.append(field) |
114 | + if value.endswith('*'): |
115 | + if value == '*': |
116 | + where.append(wildcard_where[idx]) |
117 | else: |
118 | + # This is a glob match |
119 | if is_wildcard: |
120 | + # We can't have a partial wildcard following |
121 | + # another wildcard |
122 | raise errors.InvalidGlobbing |
123 | - where.append(exact_where[idx]) |
124 | - args.append(value) |
125 | - statement = ( |
126 | - "SELECT d.doc_id, d.doc_rev, d.content FROM document d, %s " |
127 | - "WHERE %s ORDER BY %s;" % ( |
128 | - ', '.join(tables), ' AND '.join(where), |
129 | - ', '.join( |
130 | - ['d%d.value' % i for i in range(len(definition))]))) |
131 | - try: |
132 | - c.execute(statement, tuple(args)) |
133 | - except dbapi2.OperationalError, e: |
134 | - raise dbapi2.OperationalError(str(e) + |
135 | - '\nstatement: %s\nargs: %s\n' % (statement, args)) |
136 | - res = c.fetchall() |
137 | - result.extend([self._factory(r[0], r[1], r[2]) for r in res]) |
138 | - return result |
139 | + where.append(like_where[idx]) |
140 | + args.append(self._transform_glob(value)) |
141 | + is_wildcard = True |
142 | + else: |
143 | + if is_wildcard: |
144 | + raise errors.InvalidGlobbing |
145 | + where.append(exact_where[idx]) |
146 | + args.append(value) |
147 | + statement = ( |
148 | + "SELECT d.doc_id, d.doc_rev, d.content FROM document d, %s " |
149 | + "WHERE %s ORDER BY %s;" % ( |
150 | + ', '.join(tables), ' AND '.join(where), |
151 | + ', '.join( |
152 | + ['d%d.value' % i for i in range(len(definition))]))) |
153 | + try: |
154 | + c.execute(statement, tuple(args)) |
155 | + except dbapi2.OperationalError, e: |
156 | + raise dbapi2.OperationalError(str(e) + |
157 | + '\nstatement: %s\nargs: %s\n' % (statement, args)) |
158 | + res = c.fetchall() |
159 | + return [self._factory(r[0], r[1], r[2]) for r in res] |
160 | |
161 | def get_index_keys(self, index): |
162 | c = self._db_handle.cursor() |
163 | |
164 | === modified file 'u1db/commandline/client.py' |
165 | --- u1db/commandline/client.py 2012-05-30 21:45:09 +0000 |
166 | +++ u1db/commandline/client.py 2012-05-31 18:55:27 +0000 |
167 | @@ -432,7 +432,7 @@ |
168 | def run(self, database, index, values): |
169 | try: |
170 | db = self._open(database, create=False) |
171 | - docs = db.get_from_index(index, [values]) |
172 | + docs = db.get_from_index(index, *values) |
173 | except errors.DatabaseDoesNotExist: |
174 | self.stderr.write("Database does not exist.\n") |
175 | except errors.IndexDoesNotExist: |
176 | |
177 | === modified file 'u1db/tests/c_backend_wrapper.pyx' |
178 | --- u1db/tests/c_backend_wrapper.pyx 2012-05-30 21:45:09 +0000 |
179 | +++ u1db/tests/c_backend_wrapper.pyx 2012-05-31 18:55:27 +0000 |
180 | @@ -1062,42 +1062,41 @@ |
181 | handle_status("delete_index", |
182 | u1db_delete_index(self._db, index_name)) |
183 | |
184 | - def get_from_index(self, index_name, key_values): |
185 | + def get_from_index(self, index_name, *key_values): |
186 | cdef CQuery query |
187 | cdef int status |
188 | extra = [] |
189 | query = self._query_init(index_name) |
190 | res = [] |
191 | status = U1DB_OK |
192 | - for entry in key_values: |
193 | - if len(entry) == 0: |
194 | - status = u1db_get_from_index(self._db, query._query, |
195 | - <void*>res, _append_doc_to_list, 0, NULL) |
196 | - elif len(entry) == 1: |
197 | - status = u1db_get_from_index(self._db, query._query, |
198 | - <void*>res, _append_doc_to_list, 1, |
199 | - _ensure_str(entry[0], extra)) |
200 | - elif len(entry) == 2: |
201 | - status = u1db_get_from_index(self._db, query._query, |
202 | - <void*>res, _append_doc_to_list, 2, |
203 | - _ensure_str(entry[0], extra), |
204 | - _ensure_str(entry[1], extra)) |
205 | - elif len(entry) == 3: |
206 | - status = u1db_get_from_index(self._db, query._query, |
207 | - <void*>res, _append_doc_to_list, 3, |
208 | - _ensure_str(entry[0], extra), |
209 | - _ensure_str(entry[1], extra), |
210 | - _ensure_str(entry[2], extra)) |
211 | - elif len(entry) == 4: |
212 | - status = u1db_get_from_index(self._db, query._query, |
213 | - <void*>res, _append_doc_to_list, 4, |
214 | - _ensure_str(entry[0], extra), |
215 | - _ensure_str(entry[1], extra), |
216 | - _ensure_str(entry[2], extra), |
217 | - _ensure_str(entry[3], extra)) |
218 | - else: |
219 | - status = U1DB_NOT_IMPLEMENTED |
220 | - handle_status("get_from_index", status) |
221 | + if len(key_values) == 0: |
222 | + status = u1db_get_from_index(self._db, query._query, |
223 | + <void*>res, _append_doc_to_list, 0, NULL) |
224 | + elif len(key_values) == 1: |
225 | + status = u1db_get_from_index(self._db, query._query, |
226 | + <void*>res, _append_doc_to_list, 1, |
227 | + _ensure_str(key_values[0], extra)) |
228 | + elif len(key_values) == 2: |
229 | + status = u1db_get_from_index(self._db, query._query, |
230 | + <void*>res, _append_doc_to_list, 2, |
231 | + _ensure_str(key_values[0], extra), |
232 | + _ensure_str(key_values[1], extra)) |
233 | + elif len(key_values) == 3: |
234 | + status = u1db_get_from_index(self._db, query._query, |
235 | + <void*>res, _append_doc_to_list, 3, |
236 | + _ensure_str(key_values[0], extra), |
237 | + _ensure_str(key_values[1], extra), |
238 | + _ensure_str(key_values[2], extra)) |
239 | + elif len(key_values) == 4: |
240 | + status = u1db_get_from_index(self._db, query._query, |
241 | + <void*>res, _append_doc_to_list, 4, |
242 | + _ensure_str(key_values[0], extra), |
243 | + _ensure_str(key_values[1], extra), |
244 | + _ensure_str(key_values[2], extra), |
245 | + _ensure_str(key_values[3], extra)) |
246 | + else: |
247 | + status = U1DB_NOT_IMPLEMENTED |
248 | + handle_status("get_from_index", status) |
249 | return res |
250 | |
251 | def get_index_keys(self, index_name): |
252 | |
253 | === modified file 'u1db/tests/test_backends.py' |
254 | --- u1db/tests/test_backends.py 2012-05-31 16:39:27 +0000 |
255 | +++ u1db/tests/test_backends.py 2012-05-31 18:55:27 +0000 |
256 | @@ -727,8 +727,7 @@ |
257 | def test_create_index_on_non_ascii_field_name(self): |
258 | doc = self.db.create_doc(simplejson.dumps({u'\xe5': 'value'})) |
259 | self.db.create_index('test-idx', u'\xe5') |
260 | - self.assertEqual([doc], |
261 | - self.db.get_from_index('test-idx', [('value',)])) |
262 | + self.assertEqual([doc], self.db.get_from_index('test-idx', 'value')) |
263 | |
264 | def test_list_indexes_with_non_ascii_field_names(self): |
265 | self.db.create_index('test-idx', u'\xe5') |
266 | @@ -738,20 +737,18 @@ |
267 | def test_create_index_evaluates_it(self): |
268 | doc = self.db.create_doc(simple_doc) |
269 | self.db.create_index('test-idx', 'key') |
270 | - self.assertEqual([doc], |
271 | - self.db.get_from_index('test-idx', [('value',)])) |
272 | + self.assertEqual([doc], self.db.get_from_index('test-idx', 'value')) |
273 | |
274 | def test_wildcard_matches_unicode_value(self): |
275 | doc = self.db.create_doc(simplejson.dumps({"key": u"valu\xe5"})) |
276 | self.db.create_index('test-idx', 'key') |
277 | - self.assertEqual( |
278 | - [doc], self.db.get_from_index('test-idx', [('*',)])) |
279 | + self.assertEqual([doc], self.db.get_from_index('test-idx', '*')) |
280 | |
281 | def test_retrieve_unicode_value_from_index(self): |
282 | doc = self.db.create_doc(simplejson.dumps({"key": u"valu\xe5"})) |
283 | self.db.create_index('test-idx', 'key') |
284 | self.assertEqual( |
285 | - [doc], self.db.get_from_index('test-idx', [(u"valu\xe5",)])) |
286 | + [doc], self.db.get_from_index('test-idx', u"valu\xe5")) |
287 | |
288 | def test_create_index_fails_if_name_taken(self): |
289 | self.db.create_index('test-idx', 'key') |
290 | @@ -769,8 +766,7 @@ |
291 | doc2 = self.db.create_doc(simple_doc) |
292 | self.db.delete_doc(doc2) |
293 | self.db.create_index('test-idx', 'key') |
294 | - self.assertEqual([doc], |
295 | - self.db.get_from_index('test-idx', [('value',)])) |
296 | + self.assertEqual([doc], self.db.get_from_index('test-idx', 'value')) |
297 | |
298 | def test_delete_index(self): |
299 | self.db.create_index('test-idx', 'key') |
300 | @@ -781,40 +777,32 @@ |
301 | def test_create_adds_to_index(self): |
302 | self.db.create_index('test-idx', 'key') |
303 | doc = self.db.create_doc(simple_doc) |
304 | - self.assertEqual([doc], |
305 | - self.db.get_from_index('test-idx', [('value',)])) |
306 | + self.assertEqual([doc], self.db.get_from_index('test-idx', 'value')) |
307 | |
308 | def test_get_from_index_unmatched(self): |
309 | self.db.create_doc(simple_doc) |
310 | self.db.create_index('test-idx', 'key') |
311 | - self.assertEqual( |
312 | - [], self.db.get_from_index('test-idx', [('novalue',)])) |
313 | + self.assertEqual([], self.db.get_from_index('test-idx', 'novalue')) |
314 | |
315 | def test_create_index_multiple_exact_matches(self): |
316 | doc = self.db.create_doc(simple_doc) |
317 | doc2 = self.db.create_doc(simple_doc) |
318 | self.db.create_index('test-idx', 'key') |
319 | - self.assertEqual(sorted([doc, doc2]), |
320 | - sorted(self.db.get_from_index('test-idx', [('value',)]))) |
321 | + self.assertEqual( |
322 | + sorted([doc, doc2]), |
323 | + sorted(self.db.get_from_index('test-idx', 'value'))) |
324 | |
325 | def test_get_from_index(self): |
326 | doc = self.db.create_doc(simple_doc) |
327 | self.db.create_index('test-idx', 'key') |
328 | - self.assertEqual([doc], |
329 | - self.db.get_from_index('test-idx', [('value',)])) |
330 | - |
331 | - def test_get_from_index_some_matches(self): |
332 | - doc = self.db.create_doc(simple_doc) |
333 | - self.db.create_index('test-idx', 'key') |
334 | - self.assertEqual([doc], |
335 | - self.db.get_from_index('test-idx', [('value',), ('novalue',)])) |
336 | + self.assertEqual([doc], self.db.get_from_index('test-idx', 'value')) |
337 | |
338 | def test_get_from_index_multi(self): |
339 | content = '{"key": "value", "key2": "value2"}' |
340 | doc = self.db.create_doc(content) |
341 | self.db.create_index('test-idx', 'key', 'key2') |
342 | - self.assertEqual([doc], |
343 | - self.db.get_from_index('test-idx', [('value', 'value2')])) |
344 | + self.assertEqual( |
345 | + [doc], self.db.get_from_index('test-idx', 'value', 'value2')) |
346 | |
347 | def test_get_from_index_multi_ordered(self): |
348 | doc1 = self.db.create_doc('{"key": "value3", "key2": "value4"}') |
349 | @@ -822,13 +810,13 @@ |
350 | doc3 = self.db.create_doc('{"key": "value2", "key2": "value2"}') |
351 | doc4 = self.db.create_doc('{"key": "value1", "key2": "value1"}') |
352 | self.db.create_index('test-idx', 'key', 'key2') |
353 | - self.assertEqual([doc4, doc3, doc2, doc1], |
354 | - self.db.get_from_index('test-idx', [('v*', '*')])) |
355 | + self.assertEqual( |
356 | + [doc4, doc3, doc2, doc1], |
357 | + self.db.get_from_index('test-idx', 'v*', '*')) |
358 | |
359 | def test_get_from_index_fails_if_no_index(self): |
360 | - self.assertRaises(errors.IndexDoesNotExist, |
361 | - self.db.get_from_index, |
362 | - 'foo', []) |
363 | + self.assertRaises( |
364 | + errors.IndexDoesNotExist, self.db.get_from_index, 'foo') |
365 | |
366 | def test_get_index_keys_fails_if_no_index(self): |
367 | self.assertRaises(errors.IndexDoesNotExist, |
368 | @@ -845,39 +833,41 @@ |
369 | new_content = '{"key": "altval"}' |
370 | doc.set_json(new_content) |
371 | self.db.put_doc(doc) |
372 | - self.assertEqual([], |
373 | - self.db.get_from_index('test-idx', [('value',)])) |
374 | - self.assertEqual([doc], |
375 | - self.db.get_from_index('test-idx', [('altval',)])) |
376 | + self.assertEqual([], self.db.get_from_index('test-idx', 'value')) |
377 | + self.assertEqual([doc], self.db.get_from_index('test-idx', 'altval')) |
378 | |
379 | def test_delete_updates_index(self): |
380 | doc = self.db.create_doc(simple_doc) |
381 | doc2 = self.db.create_doc(simple_doc) |
382 | self.db.create_index('test-idx', 'key') |
383 | - self.assertEqual(sorted([doc, doc2]), |
384 | - sorted(self.db.get_from_index('test-idx', [('value',)]))) |
385 | + self.assertEqual( |
386 | + sorted([doc, doc2]), |
387 | + sorted(self.db.get_from_index('test-idx', 'value'))) |
388 | self.db.delete_doc(doc) |
389 | - self.assertEqual([doc2], |
390 | - self.db.get_from_index('test-idx', [('value',)])) |
391 | + self.assertEqual([doc2], self.db.get_from_index('test-idx', 'value')) |
392 | |
393 | def test_get_from_index_illegal_number_of_entries(self): |
394 | self.db.create_index('test-idx', 'k1', 'k2') |
395 | - self.assertRaises(errors.InvalidValueForIndex, |
396 | - self.db.get_from_index, 'test-idx', [()]) |
397 | - self.assertRaises(errors.InvalidValueForIndex, |
398 | - self.db.get_from_index, 'test-idx', [('v1',)]) |
399 | - self.assertRaises(errors.InvalidValueForIndex, |
400 | - self.db.get_from_index, 'test-idx', [('v1', 'v2', 'v3')]) |
401 | + self.assertRaises( |
402 | + errors.InvalidValueForIndex, self.db.get_from_index, 'test-idx') |
403 | + self.assertRaises( |
404 | + errors.InvalidValueForIndex, |
405 | + self.db.get_from_index, 'test-idx', 'v1') |
406 | + self.assertRaises( |
407 | + errors.InvalidValueForIndex, |
408 | + self.db.get_from_index, 'test-idx', 'v1', 'v2', 'v3') |
409 | |
410 | def test_get_from_index_illegal_wildcard_order(self): |
411 | self.db.create_index('test-idx', 'k1', 'k2') |
412 | - self.assertRaises(errors.InvalidGlobbing, |
413 | - self.db.get_from_index, 'test-idx', [('*', 'v2')]) |
414 | + self.assertRaises( |
415 | + errors.InvalidGlobbing, |
416 | + self.db.get_from_index, 'test-idx', '*', 'v2') |
417 | |
418 | def test_get_from_index_illegal_glob_after_wildcard(self): |
419 | self.db.create_index('test-idx', 'k1', 'k2') |
420 | - self.assertRaises(errors.InvalidGlobbing, |
421 | - self.db.get_from_index, 'test-idx', [('*', 'v*')]) |
422 | + self.assertRaises( |
423 | + errors.InvalidGlobbing, |
424 | + self.db.get_from_index, 'test-idx', '*', 'v*') |
425 | |
426 | def test_get_all_from_index(self): |
427 | self.db.create_index('test-idx', 'key') |
428 | @@ -888,8 +878,9 @@ |
429 | diff_value_doc = '{"key": "diff value"}' |
430 | doc4 = self.db.create_doc(diff_value_doc) |
431 | # This is essentially a 'prefix' match, but we match every entry. |
432 | - self.assertEqual(sorted([doc1, doc2, doc4]), |
433 | - sorted(self.db.get_from_index('test-idx', [('*',)]))) |
434 | + self.assertEqual( |
435 | + sorted([doc1, doc2, doc4]), |
436 | + sorted(self.db.get_from_index('test-idx', '*'))) |
437 | |
438 | def test_get_all_from_index_ordered(self): |
439 | self.db.create_index('test-idx', 'key') |
440 | @@ -898,36 +889,33 @@ |
441 | doc3 = self.db.create_doc('{"key": "value a"}') |
442 | doc4 = self.db.create_doc('{"key": "value m"}') |
443 | # This is essentially a 'prefix' match, but we match every entry. |
444 | - self.assertEqual([doc3, doc2, doc4, doc1], |
445 | - self.db.get_from_index('test-idx', [('*',)])) |
446 | + self.assertEqual( |
447 | + [doc3, doc2, doc4, doc1], self.db.get_from_index('test-idx', '*')) |
448 | |
449 | def test_put_updates_when_adding_key(self): |
450 | doc = self.db.create_doc("{}") |
451 | self.db.create_index('test-idx', 'key') |
452 | - self.assertEqual([], |
453 | - self.db.get_from_index('test-idx', [('*',)])) |
454 | + self.assertEqual([], self.db.get_from_index('test-idx', '*')) |
455 | doc.set_json(simple_doc) |
456 | self.db.put_doc(doc) |
457 | - self.assertEqual([doc], |
458 | - self.db.get_from_index('test-idx', [('*',)])) |
459 | + self.assertEqual([doc], self.db.get_from_index('test-idx', '*')) |
460 | |
461 | def test_get_from_index_empty_string(self): |
462 | self.db.create_index('test-idx', 'key') |
463 | doc1 = self.db.create_doc(simple_doc) |
464 | content2 = '{"key": ""}' |
465 | doc2 = self.db.create_doc(content2) |
466 | - self.assertEqual([doc2], |
467 | - self.db.get_from_index('test-idx', [('',)])) |
468 | + self.assertEqual([doc2], self.db.get_from_index('test-idx', '')) |
469 | # Empty string matches the wildcard. |
470 | - self.assertEqual(sorted([doc1, doc2]), |
471 | - sorted(self.db.get_from_index('test-idx', [('*',)]))) |
472 | + self.assertEqual( |
473 | + sorted([doc1, doc2]), |
474 | + sorted(self.db.get_from_index('test-idx', '*'))) |
475 | |
476 | def test_get_from_index_not_null(self): |
477 | self.db.create_index('test-idx', 'key') |
478 | doc1 = self.db.create_doc(simple_doc) |
479 | self.db.create_doc('{"key": null}') |
480 | - self.assertEqual([doc1], |
481 | - self.db.get_from_index('test-idx', [('*',)])) |
482 | + self.assertEqual([doc1], self.db.get_from_index('test-idx', '*')) |
483 | |
484 | def test_get_partial_from_index(self): |
485 | content1 = '{"k1": "v1", "k2": "v2"}' |
486 | @@ -940,8 +928,9 @@ |
487 | doc3 = self.db.create_doc(content3) |
488 | self.db.create_doc(content4) |
489 | self.db.create_index('test-idx', 'k1', 'k2') |
490 | - self.assertEqual(sorted([doc1, doc2, doc3]), |
491 | - sorted(self.db.get_from_index('test-idx', [("v1", "*")]))) |
492 | + self.assertEqual( |
493 | + sorted([doc1, doc2, doc3]), |
494 | + sorted(self.db.get_from_index('test-idx', "v1", "*"))) |
495 | |
496 | def test_get_glob_match(self): |
497 | # Note: the exact glob syntax is probably subject to change |
498 | @@ -955,61 +944,63 @@ |
499 | doc2 = self.db.create_doc(content2) |
500 | doc3 = self.db.create_doc(content3) |
501 | self.db.create_doc(content4) |
502 | - self.assertEqual(sorted([doc1, doc2, doc3]), |
503 | - sorted(self.db.get_from_index('test-idx', [("v1", "v*")]))) |
504 | + self.assertEqual( |
505 | + sorted([doc1, doc2, doc3]), |
506 | + sorted(self.db.get_from_index('test-idx', "v1", "v*"))) |
507 | |
508 | def test_nested_index(self): |
509 | doc = self.db.create_doc(nested_doc) |
510 | self.db.create_index('test-idx', 'sub.doc') |
511 | - self.assertEqual([doc], |
512 | - self.db.get_from_index('test-idx', [('underneath',)])) |
513 | + self.assertEqual( |
514 | + [doc], self.db.get_from_index('test-idx', 'underneath')) |
515 | doc2 = self.db.create_doc(nested_doc) |
516 | self.assertEqual( |
517 | sorted([doc, doc2]), |
518 | - sorted(self.db.get_from_index('test-idx', [('underneath',)]))) |
519 | + sorted(self.db.get_from_index('test-idx', 'underneath'))) |
520 | |
521 | def test_nested_nonexistent(self): |
522 | self.db.create_doc(nested_doc) |
523 | # sub exists, but sub.foo does not: |
524 | self.db.create_index('test-idx', 'sub.foo') |
525 | - self.assertEqual([], self.db.get_from_index('test-idx', [('*',)])) |
526 | + self.assertEqual([], self.db.get_from_index('test-idx', '*')) |
527 | |
528 | def test_nested_nonexistent2(self): |
529 | self.db.create_doc(nested_doc) |
530 | # sub exists, but sub.foo does not: |
531 | self.db.create_index('test-idx', 'sub.foo.bar.baz.qux.fnord') |
532 | - self.assertEqual([], self.db.get_from_index('test-idx', [('*',)])) |
533 | + self.assertEqual([], self.db.get_from_index('test-idx', '*')) |
534 | |
535 | def test_index_list1(self): |
536 | self.db.create_index("index", "name") |
537 | content = '{"name": ["foo", "bar"]}' |
538 | doc = self.db.create_doc(content) |
539 | - rows = self.db.get_from_index("index", [("bar", )]) |
540 | + rows = self.db.get_from_index("index", "bar") |
541 | self.assertEqual([doc], rows) |
542 | |
543 | def test_index_list2(self): |
544 | self.db.create_index("index", "name") |
545 | content = '{"name": ["foo", "bar"]}' |
546 | doc = self.db.create_doc(content) |
547 | - rows = self.db.get_from_index("index", [("foo", )]) |
548 | + rows = self.db.get_from_index("index", "foo") |
549 | self.assertEqual([doc], rows) |
550 | |
551 | def test_get_from_index_case_sensitive(self): |
552 | self.db.create_index('test-idx', 'key') |
553 | doc1 = self.db.create_doc(simple_doc) |
554 | - self.assertEqual([], self.db.get_from_index('test-idx', [('V*',)])) |
555 | - self.assertEqual([doc1], |
556 | - self.db.get_from_index('test-idx', [('v*',)])) |
557 | + self.assertEqual([], self.db.get_from_index('test-idx', 'V*')) |
558 | + self.assertEqual([doc1], self.db.get_from_index('test-idx', 'v*')) |
559 | |
560 | def test_get_from_index_illegal_glob_before_value(self): |
561 | self.db.create_index('test-idx', 'k1', 'k2') |
562 | - self.assertRaises(errors.InvalidGlobbing, |
563 | - self.db.get_from_index, 'test-idx', [('v*', 'v2')]) |
564 | + self.assertRaises( |
565 | + errors.InvalidGlobbing, |
566 | + self.db.get_from_index, 'test-idx', 'v*', 'v2') |
567 | |
568 | def test_get_from_index_illegal_glob_after_glob(self): |
569 | self.db.create_index('test-idx', 'k1', 'k2') |
570 | - self.assertRaises(errors.InvalidGlobbing, |
571 | - self.db.get_from_index, 'test-idx', [('v*', 'v*')]) |
572 | + self.assertRaises( |
573 | + errors.InvalidGlobbing, |
574 | + self.db.get_from_index, 'test-idx', 'v*', 'v*') |
575 | |
576 | def test_get_from_index_with_sql_wildcards(self): |
577 | self.db.create_index('test-idx', 'key') |
578 | @@ -1021,31 +1012,29 @@ |
579 | doc3 = self.db.create_doc(content3) |
580 | # The '%' in the search should be treated literally, not as a sql |
581 | # globbing character. |
582 | - self.assertEqual([doc1], |
583 | - self.db.get_from_index('test-idx', [('va%*',)])) |
584 | + self.assertEqual([doc1], self.db.get_from_index('test-idx', 'va%*')) |
585 | # Same for '_' |
586 | - self.assertEqual([doc3], |
587 | - self.db.get_from_index('test-idx', [('va_*',)])) |
588 | + self.assertEqual([doc3], self.db.get_from_index('test-idx', 'va_*')) |
589 | |
590 | def test_get_from_index_with_lower(self): |
591 | self.db.create_index("index", "lower(name)") |
592 | content = '{"name": "Foo"}' |
593 | doc = self.db.create_doc(content) |
594 | - rows = self.db.get_from_index("index", [("foo", )]) |
595 | + rows = self.db.get_from_index("index", "foo") |
596 | self.assertEqual([doc], rows) |
597 | |
598 | def test_get_from_index_with_lower_matches_same_case(self): |
599 | self.db.create_index("index", "lower(name)") |
600 | content = '{"name": "foo"}' |
601 | doc = self.db.create_doc(content) |
602 | - rows = self.db.get_from_index("index", [("foo", )]) |
603 | + rows = self.db.get_from_index("index", "foo") |
604 | self.assertEqual([doc], rows) |
605 | |
606 | def test_index_lower_doesnt_match_different_case(self): |
607 | self.db.create_index("index", "lower(name)") |
608 | content = '{"name": "Foo"}' |
609 | self.db.create_doc(content) |
610 | - rows = self.db.get_from_index("index", [("Foo", )]) |
611 | + rows = self.db.get_from_index("index", "Foo") |
612 | self.assertEqual([], rows) |
613 | |
614 | def test_index_lower_doesnt_match_other_index(self): |
615 | @@ -1053,63 +1042,63 @@ |
616 | self.db.create_index("other_index", "name") |
617 | content = '{"name": "Foo"}' |
618 | self.db.create_doc(content) |
619 | - rows = self.db.get_from_index("index", [("Foo", )]) |
620 | + rows = self.db.get_from_index("index", "Foo") |
621 | self.assertEqual(0, len(rows)) |
622 | |
623 | def test_index_split_words_match_first(self): |
624 | self.db.create_index("index", "split_words(name)") |
625 | content = '{"name": "foo bar"}' |
626 | doc = self.db.create_doc(content) |
627 | - rows = self.db.get_from_index("index", [("foo", )]) |
628 | + rows = self.db.get_from_index("index", "foo") |
629 | self.assertEqual([doc], rows) |
630 | |
631 | def test_index_split_words_match_second(self): |
632 | self.db.create_index("index", "split_words(name)") |
633 | content = '{"name": "foo bar"}' |
634 | doc = self.db.create_doc(content) |
635 | - rows = self.db.get_from_index("index", [("bar", )]) |
636 | + rows = self.db.get_from_index("index", "bar") |
637 | self.assertEqual([doc], rows) |
638 | |
639 | def test_index_split_words_match_both(self): |
640 | self.db.create_index("index", "split_words(name)") |
641 | content = '{"name": "foo foo"}' |
642 | doc = self.db.create_doc(content) |
643 | - rows = self.db.get_from_index("index", [("foo", )]) |
644 | + rows = self.db.get_from_index("index", "foo") |
645 | self.assertEqual([doc], rows) |
646 | |
647 | def test_index_split_words_double_space(self): |
648 | self.db.create_index("index", "split_words(name)") |
649 | content = '{"name": "foo bar"}' |
650 | doc = self.db.create_doc(content) |
651 | - rows = self.db.get_from_index("index", [("bar", )]) |
652 | + rows = self.db.get_from_index("index", "bar") |
653 | self.assertEqual([doc], rows) |
654 | |
655 | def test_index_split_words_leading_space(self): |
656 | self.db.create_index("index", "split_words(name)") |
657 | content = '{"name": " foo bar"}' |
658 | doc = self.db.create_doc(content) |
659 | - rows = self.db.get_from_index("index", [("foo", )]) |
660 | + rows = self.db.get_from_index("index", "foo") |
661 | self.assertEqual([doc], rows) |
662 | |
663 | def test_index_split_words_trailing_space(self): |
664 | self.db.create_index("index", "split_words(name)") |
665 | content = '{"name": "foo bar "}' |
666 | doc = self.db.create_doc(content) |
667 | - rows = self.db.get_from_index("index", [("bar", )]) |
668 | + rows = self.db.get_from_index("index", "bar") |
669 | self.assertEqual([doc], rows) |
670 | |
671 | def test_get_from_index_with_number(self): |
672 | self.db.create_index("index", "number(foo, 5)") |
673 | content = '{"foo": 12}' |
674 | doc = self.db.create_doc(content) |
675 | - rows = self.db.get_from_index("index", [("00012", )]) |
676 | + rows = self.db.get_from_index("index", "00012") |
677 | self.assertEqual([doc], rows) |
678 | |
679 | def test_get_from_index_with_number_bigger_than_padding(self): |
680 | self.db.create_index("index", "number(foo, 5)") |
681 | content = '{"foo": 123456}' |
682 | doc = self.db.create_doc(content) |
683 | - rows = self.db.get_from_index("index", [("123456", )]) |
684 | + rows = self.db.get_from_index("index", "123456") |
685 | self.assertEqual([doc], rows) |
686 | |
687 | def test_number_mapping_ignores_non_numbers(self): |
688 | @@ -1118,28 +1107,28 @@ |
689 | doc1 = self.db.create_doc(content) |
690 | content = '{"foo": "this is not a maigret painting"}' |
691 | self.db.create_doc(content) |
692 | - rows = self.db.get_from_index("index", [("*", )]) |
693 | + rows = self.db.get_from_index("index", "*") |
694 | self.assertEqual([doc1], rows) |
695 | |
696 | def test_get_from_index_with_bool(self): |
697 | self.db.create_index("index", "bool(foo)") |
698 | content = '{"foo": true}' |
699 | doc = self.db.create_doc(content) |
700 | - rows = self.db.get_from_index("index", [("1", )]) |
701 | + rows = self.db.get_from_index("index", "1") |
702 | self.assertEqual([doc], rows) |
703 | |
704 | def test_get_from_index_with_bool_false(self): |
705 | self.db.create_index("index", "bool(foo)") |
706 | content = '{"foo": false}' |
707 | doc = self.db.create_doc(content) |
708 | - rows = self.db.get_from_index("index", [("0", )]) |
709 | + rows = self.db.get_from_index("index", "0") |
710 | self.assertEqual([doc], rows) |
711 | |
712 | def test_get_from_index_with_non_bool(self): |
713 | self.db.create_index("index", "bool(foo)") |
714 | content = '{"foo": 42}' |
715 | self.db.create_doc(content) |
716 | - rows = self.db.get_from_index("index", [("*", )]) |
717 | + rows = self.db.get_from_index("index", "*") |
718 | self.assertEqual([], rows) |
719 | |
720 | def test_get_index_keys_from_index(self): |
721 | @@ -1197,7 +1186,7 @@ |
722 | self.db.create_index('test-idx', 'key') |
723 | self.assertTrue( |
724 | isinstance( |
725 | - self.db.get_from_index('test-idx', [('value',)])[0], |
726 | + self.db.get_from_index('test-idx', 'value')[0], |
727 | TestAlternativeDocument)) |
728 | |
729 | def test_sync_exchange_updates_indexes(self): |
730 | @@ -1216,9 +1205,9 @@ |
731 | docs_by_gen, 'other-replica', last_known_generation=0, |
732 | return_doc_cb=ignore) |
733 | self.assertGetDoc(self.db, doc.doc_id, other_rev, new_content, False) |
734 | - self.assertEqual([doc_other], |
735 | - self.db.get_from_index('test-idx', [('altval',)])) |
736 | - self.assertEqual([], self.db.get_from_index('test-idx', [('value',)])) |
737 | + self.assertEqual( |
738 | + [doc_other], self.db.get_from_index('test-idx', 'altval')) |
739 | + self.assertEqual([], self.db.get_from_index('test-idx', 'value')) |
740 | |
741 | |
742 | # Use a custom loader to apply the scenarios at load time. |
743 | |
744 | === modified file 'u1db/tests/test_c_backend.py' |
745 | --- u1db/tests/test_c_backend.py 2012-05-31 16:10:38 +0000 |
746 | +++ u1db/tests/test_c_backend.py 2012-05-31 18:55:27 +0000 |
747 | @@ -99,14 +99,14 @@ |
748 | self.db = c_backend_wrapper.CDatabase(':memory:') |
749 | doc = self.db.create_doc(tests.simple_doc) |
750 | self.db.create_index("key-idx", "key") |
751 | - docs = self.db.get_from_index('key-idx', [('value',)]) |
752 | + docs = self.db.get_from_index('key-idx', 'value') |
753 | self.assertEqual([doc], docs) |
754 | |
755 | def test_get_from_index_2(self): |
756 | self.db = c_backend_wrapper.CDatabase(':memory:') |
757 | doc = self.db.create_doc(tests.nested_doc) |
758 | self.db.create_index("multi-idx", "key", "sub.doc") |
759 | - docs = self.db.get_from_index('multi-idx', [('value', 'underneath')]) |
760 | + docs = self.db.get_from_index('multi-idx', 'value', 'underneath') |
761 | self.assertEqual([doc], docs) |
762 | |
763 | def test_get_index_keys(self): |
764 | |
765 | === modified file 'u1db/tests/test_inmemory.py' |
766 | --- u1db/tests/test_inmemory.py 2012-05-23 10:57:02 +0000 |
767 | +++ u1db/tests/test_inmemory.py 2012-05-31 18:55:27 +0000 |
768 | @@ -104,13 +104,13 @@ |
769 | def test_lookup(self): |
770 | idx = inmemory.InMemoryIndex('idx-name', ['key']) |
771 | idx.add_json('doc-id', simple_doc) |
772 | - self.assertEqual(['doc-id'], idx.lookup([('value',)])) |
773 | + self.assertEqual(['doc-id'], idx.lookup(['value'])) |
774 | |
775 | def test_lookup_multi(self): |
776 | idx = inmemory.InMemoryIndex('idx-name', ['key']) |
777 | idx.add_json('doc-id', simple_doc) |
778 | idx.add_json('doc2-id', simple_doc) |
779 | - self.assertEqual(['doc-id', 'doc2-id'], idx.lookup([('value',)])) |
780 | + self.assertEqual(['doc-id', 'doc2-id'], idx.lookup(['value'])) |
781 | |
782 | def test__find_non_wildcards(self): |
783 | idx = inmemory.InMemoryIndex('idx-name', ['k1', 'k2', 'k3']) |
784 | |
785 | === modified file 'u1db/tests/test_sync.py' |
786 | --- u1db/tests/test_sync.py 2012-05-30 21:45:09 +0000 |
787 | +++ u1db/tests/test_sync.py 2012-05-31 18:55:27 +0000 |
788 | @@ -461,8 +461,7 @@ |
789 | {'receive': {'docs': [], 'last_known_gen': 0}, |
790 | 'return': {'docs': [(doc.doc_id, doc.rev)], |
791 | 'last_gen': 1}}) |
792 | - self.assertEqual([doc], |
793 | - self.db1.get_from_index('test-idx', [('value',)])) |
794 | + self.assertEqual([doc], self.db1.get_from_index('test-idx', 'value')) |
795 | |
796 | def test_sync_pulling_doesnt_update_other_if_changed(self): |
797 | doc = self.db2.create_doc(simple_doc) |
798 | @@ -551,9 +550,8 @@ |
799 | self.assertTransactionLog([doc_id, doc_id], self.db1) |
800 | self.assertGetDoc(self.db1, doc_id, doc2_rev, new_doc, True) |
801 | self.assertGetDoc(self.db2, doc_id, doc2_rev, new_doc, False) |
802 | - self.assertEqual([doc2], |
803 | - self.db1.get_from_index('test-idx', [('altval',)])) |
804 | - self.assertEqual([], self.db1.get_from_index('test-idx', [('value',)])) |
805 | + self.assertEqual([doc2], self.db1.get_from_index('test-idx', 'altval')) |
806 | + self.assertEqual([], self.db1.get_from_index('test-idx', 'value')) |
807 | |
808 | def test_sync_sees_remote_delete_conflicted(self): |
809 | doc1 = self.db1.create_doc(simple_doc) |
810 | @@ -577,7 +575,7 @@ |
811 | self.assertGetDocIncludeDeleted(self.db1, doc_id, doc2.rev, None, True) |
812 | self.assertGetDocIncludeDeleted( |
813 | self.db2, doc_id, doc2.rev, None, False) |
814 | - self.assertEqual([], self.db1.get_from_index('test-idx', [('value',)])) |
815 | + self.assertEqual([], self.db1.get_from_index('test-idx', 'value')) |
816 | |
817 | def test_sync_local_race_conflicted(self): |
818 | doc = self.db1.create_doc(simple_doc) |
819 | @@ -602,11 +600,9 @@ |
820 | self.sync(self.db1, self.db2, trace_hook=after_whatschanged) |
821 | self.assertEqual([True], triggered) |
822 | self.assertGetDoc(self.db1, doc_id, doc2_rev2, content2, True) |
823 | - self.assertEqual([doc], |
824 | - self.db1.get_from_index('test-idx', [('altval',)])) |
825 | - self.assertEqual([], self.db1.get_from_index('test-idx', [('value',)])) |
826 | - self.assertEqual([], self.db1.get_from_index('test-idx', |
827 | - [('localval',)])) |
828 | + self.assertEqual([doc], self.db1.get_from_index('test-idx', 'altval')) |
829 | + self.assertEqual([], self.db1.get_from_index('test-idx', 'value')) |
830 | + self.assertEqual([], self.db1.get_from_index('test-idx', 'localval')) |
831 | |
832 | def test_sync_propagates_deletes(self): |
833 | doc1 = self.db1.create_doc(simple_doc) |
834 | @@ -628,8 +624,8 @@ |
835 | self.db1, doc_id, deleted_rev, None, False) |
836 | self.assertGetDocIncludeDeleted( |
837 | self.db2, doc_id, deleted_rev, None, False) |
838 | - self.assertEqual([], self.db1.get_from_index('test-idx', [('value',)])) |
839 | - self.assertEqual([], self.db2.get_from_index('test-idx', [('value',)])) |
840 | + self.assertEqual([], self.db1.get_from_index('test-idx', 'value')) |
841 | + self.assertEqual([], self.db2.get_from_index('test-idx', 'value')) |
842 | self.sync(self.db2, self.db3) |
843 | self.assertLastExchangeLog(self.db3, |
844 | {'receive': {'docs': [(doc_id, deleted_rev)], |
845 | |
846 | === modified file 'u1todo/u1todo.py' |
847 | --- u1todo/u1todo.py 2012-05-30 21:45:09 +0000 |
848 | +++ u1todo/u1todo.py 2012-05-31 18:55:27 +0000 |
849 | @@ -86,15 +86,15 @@ |
850 | # No tags specified, so return all tasks. |
851 | return self.get_all_tasks() |
852 | # Get all tasks for the first tag. |
853 | - results = dict((doc.doc_id, doc) for doc in |
854 | - self.db.get_from_index(TAGS_INDEX, [(tags[0],)])) |
855 | + results = dict( |
856 | + (doc.doc_id, doc) for doc in |
857 | + self.db.get_from_index(TAGS_INDEX, tags[0])) |
858 | # Now loop over the rest of the tags (if any) and remove from the |
859 | # results any document that does not have that particular tag. |
860 | for tag in tags[1:]: |
861 | # Get the ids of all documents with this tag. |
862 | ids = [ |
863 | - doc.doc_id for doc in |
864 | - self.db.get_from_index(TAGS_INDEX, [(tag,)])] |
865 | + doc.doc_id for doc in self.db.get_from_index(TAGS_INDEX, tag)] |
866 | for key in results.keys(): |
867 | if key not in ids: |
868 | # Remove the document from result, because it does not have |
869 | @@ -157,8 +157,7 @@ |
870 | # Since the DONE_INDEX indexes anything that has a value in the field |
871 | # "done", and all tasks do (either True or False), it's a good way to |
872 | # get all tasks out of the database. |
873 | - return [ |
874 | - Task(doc) for doc in self.db.get_from_index(DONE_INDEX, ["*"])] |
875 | + return [Task(doc) for doc in self.db.get_from_index(DONE_INDEX, "*")] |
876 | |
877 | |
878 | class Task(object): |