Merge lp:~thisfred/u1db/combine-mapping-3 into lp:u1db

Proposed by Eric Casteleijn
Status: Merged
Approved by: Eric Casteleijn
Approved revision: 369
Merged at revision: 363
Proposed branch: lp:~thisfred/u1db/combine-mapping-3
Merge into: lp:u1db
Prerequisite: lp:~thisfred/u1db/combine-mapping-2
Diff against target: 186 lines (+85/-3)
5 files modified
src/u1db_query.c (+20/-3)
u1db/query_parser.py (+21/-0)
u1db/tests/c_backend_wrapper.pyx (+6/-0)
u1db/tests/test_backends.py (+32/-0)
u1db/tests/test_query_parser.py (+6/-0)
To merge this branch: bzr merge lp:~thisfred/u1db/combine-mapping-3
Reviewer Review Type Date Requested Status
Samuele Pedroni Approve
Review via email: mp+116526@code.launchpad.net

This proposal supersedes a proposal from 2012-07-24.

Commit message

Added the combine() mapping.

Description of the change

Added the combine() mapping.

To post a comment you must log in.
lp:~thisfred/u1db/combine-mapping-3 updated
368. By Eric Casteleijn

removed debug prints

369. By Eric Casteleijn

removed debugging

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/u1db_query.c'
--- src/u1db_query.c 2012-07-25 20:48:18 +0000
+++ src/u1db_query.c 2012-07-26 12:03:19 +0000
@@ -213,6 +213,7 @@
213static int op_split_words(213static int op_split_words(
214 parse_tree *tree, json_object *obj, string_list *result);214 parse_tree *tree, json_object *obj, string_list *result);
215static int op_bool(parse_tree *tree, json_object *obj, string_list *result);215static int op_bool(parse_tree *tree, json_object *obj, string_list *result);
216static int op_combine(parse_tree *tree, json_object *obj, string_list *result);
216217
217static const int JUST_EXPRESSION[1] = {EXPRESSION};218static const int JUST_EXPRESSION[1] = {EXPRESSION};
218static const int EXPRESSION_INTEGER[2] = {EXPRESSION, INTEGER};219static const int EXPRESSION_INTEGER[2] = {EXPRESSION, INTEGER};
@@ -228,7 +229,8 @@
228 op_lower, "lower", json_type_string, 1, JUST_EXPRESSION,229 op_lower, "lower", json_type_string, 1, JUST_EXPRESSION,
229 op_number, "number", json_type_int, 2, EXPRESSION_INTEGER,230 op_number, "number", json_type_int, 2, EXPRESSION_INTEGER,
230 op_split_words, "split_words", json_type_string, 1, JUST_EXPRESSION,231 op_split_words, "split_words", json_type_string, 1, JUST_EXPRESSION,
231 op_bool, "bool", json_type_boolean, 1, JUST_EXPRESSION};232 op_bool, "bool", json_type_boolean, 1, JUST_EXPRESSION,
233 op_combine, "combine", json_type_string, -1, JUST_EXPRESSION};
232234
233static int235static int
234extract_field_values(json_object *obj, const string_list *field_path,236extract_field_values(json_object *obj, const string_list *field_path,
@@ -443,6 +445,21 @@
443}445}
444446
445static int447static int
448op_combine(parse_tree *tree, json_object *obj, string_list *result)
449{
450 parse_tree *node = NULL;
451 int status = U1DB_OK;
452
453 node = tree->first_child;
454 for (node = tree->first_child; node != NULL; node = node->next_sibling) {
455 status = get_values(node, obj, result);
456 if (status != U1DB_OK)
457 return status;
458 }
459 return status;
460}
461
462static int
446op_split_words(parse_tree *tree, json_object *obj, string_list *result)463op_split_words(parse_tree *tree, json_object *obj, string_list *result)
447{464{
448 string_list_item *item = NULL;465 string_list_item *item = NULL;
@@ -1265,13 +1282,13 @@
1265 while (expression[*start] == ' ')1282 while (expression[*start] == ' ')
1266 (*start)++;1283 (*start)++;
1267 size = *idx - *start;1284 size = *idx - *start;
1268 if (!size)
1269 return U1DB_OK;
1270 term = expression + *start;1285 term = expression + *start;
1271 (*idx)++;1286 (*idx)++;
1272 while (expression[*idx] == ' ')1287 while (expression[*idx] == ' ')
1273 (*idx)++;1288 (*idx)++;
1274 *start = *idx;1289 *start = *idx;
1290 if (!size)
1291 return U1DB_OK;
1275 if (size) {1292 if (size) {
1276 status = append_child(result);1293 status = append_child(result);
1277 if (status != U1DB_OK) {1294 if (status != U1DB_OK) {
12781295
=== modified file 'u1db/query_parser.py'
--- u1db/query_parser.py 2012-07-25 19:10:50 +0000
+++ u1db/query_parser.py 2012-07-26 12:03:19 +0000
@@ -207,6 +207,26 @@
207 return list(result)207 return list(result)
208208
209209
210class Combine(Transformation):
211 """Combine multiple expressions into a single index."""
212
213 name = "combine"
214 # variable number of args
215 arity = -1
216
217 def __init__(self, *inner):
218 super(Combine, self).__init__(inner)
219
220 def get(self, raw_doc):
221 inner_values = []
222 for inner in self.inner:
223 inner_values.extend(inner.get(raw_doc))
224 return self.transform(inner_values)
225
226 def transform(self, values):
227 return values
228
229
210class IsNull(Transformation):230class IsNull(Transformation):
211 """Indicate whether the input is None.231 """Indicate whether the input is None.
212232
@@ -348,3 +368,4 @@
348Parser.register_transormation(Number)368Parser.register_transormation(Number)
349Parser.register_transormation(Bool)369Parser.register_transormation(Bool)
350Parser.register_transormation(IsNull)370Parser.register_transormation(IsNull)
371Parser.register_transormation(Combine)
351372
=== modified file 'u1db/tests/c_backend_wrapper.pyx'
--- u1db/tests/c_backend_wrapper.pyx 2012-07-23 18:00:03 +0000
+++ u1db/tests/c_backend_wrapper.pyx 2012-07-26 12:03:19 +0000
@@ -138,6 +138,8 @@
138 int U1DB_INDEX_DOES_NOT_EXIST138 int U1DB_INDEX_DOES_NOT_EXIST
139 int U1DB_INVALID_GENERATION139 int U1DB_INVALID_GENERATION
140 int U1DB_INVALID_TRANSACTION_ID140 int U1DB_INVALID_TRANSACTION_ID
141 int U1DB_INVALID_TRANSFORMATION_FUNCTION
142 int U1DB_UNKNOWN_OPERATION
141 int U1DB_INTERNAL_ERROR143 int U1DB_INTERNAL_ERROR
142 int U1DB_TARGET_UNAVAILABLE144 int U1DB_TARGET_UNAVAILABLE
143145
@@ -612,6 +614,10 @@
612 raise errors.DocumentTooBig614 raise errors.DocumentTooBig
613 if status == U1DB_USER_QUOTA_EXCEEDED:615 if status == U1DB_USER_QUOTA_EXCEEDED:
614 raise errors.UserQuotaExceeded616 raise errors.UserQuotaExceeded
617 if status == U1DB_INVALID_TRANSFORMATION_FUNCTION:
618 raise errors.IndexDefinitionParseError
619 if status == U1DB_UNKNOWN_OPERATION:
620 raise errors.IndexDefinitionParseError
615 raise RuntimeError('%s (status: %s)' % (context, status))621 raise RuntimeError('%s (status: %s)' % (context, status))
616622
617623
618624
=== modified file 'u1db/tests/test_backends.py'
--- u1db/tests/test_backends.py 2012-07-24 16:22:38 +0000
+++ u1db/tests/test_backends.py 2012-07-26 12:03:19 +0000
@@ -1456,6 +1456,13 @@
1456 self.db.create_index('test-idx', 'sub.foo.bar.baz.qux.fnord')1456 self.db.create_index('test-idx', 'sub.foo.bar.baz.qux.fnord')
1457 self.assertEqual([], self.db.get_from_index('test-idx', '*'))1457 self.assertEqual([], self.db.get_from_index('test-idx', '*'))
14581458
1459 def test_nested_unknown_operation(self):
1460 self.db.create_doc_from_json(nested_doc)
1461 # sub exists, but sub.foo does not:
1462 self.assertRaises(
1463 errors.IndexDefinitionParseError, self.db.create_index, 'test-idx',
1464 'unknown_operation(field1)')
1465
1459 def test_index_list1(self):1466 def test_index_list1(self):
1460 self.db.create_index("index", "name")1467 self.db.create_index("index", "name")
1461 content = '{"name": ["foo", "bar"]}'1468 content = '{"name": ["foo", "bar"]}'
@@ -1617,6 +1624,31 @@
1617 rows = self.db.get_from_index("index", "*")1624 rows = self.db.get_from_index("index", "*")
1618 self.assertEqual([], rows)1625 self.assertEqual([], rows)
16191626
1627 def test_get_from_index_with_combine(self):
1628 self.db.create_index("index", "combine(foo, bar)")
1629 content = '{"foo": "value1", "bar": "value2"}'
1630 doc = self.db.create_doc_from_json(content)
1631 rows = self.db.get_from_index("index", "value1")
1632 self.assertEqual([doc], rows)
1633 rows = self.db.get_from_index("index", "value2")
1634 self.assertEqual([doc], rows)
1635
1636 def test_get_complex_combine(self):
1637 self.db.create_index(
1638 "index", "combine(number(foo, 5), lower(bar), split_words(baz))")
1639 content = '{"foo": 12, "bar": "ALLCAPS", "baz": "qux nox"}'
1640 doc = self.db.create_doc_from_json(content)
1641 content = '{"foo": "not a number", "bar": "something"}'
1642 doc2 = self.db.create_doc_from_json(content)
1643 rows = self.db.get_from_index("index", "00012")
1644 self.assertEqual([doc], rows)
1645 rows = self.db.get_from_index("index", "allcaps")
1646 self.assertEqual([doc], rows)
1647 rows = self.db.get_from_index("index", "nox")
1648 self.assertEqual([doc], rows)
1649 rows = self.db.get_from_index("index", "something")
1650 self.assertEqual([doc2], rows)
1651
1620 def test_get_index_keys_from_index(self):1652 def test_get_index_keys_from_index(self):
1621 self.db.create_index('test-idx', 'key')1653 self.db.create_index('test-idx', 'key')
1622 content1 = '{"key": "value1"}'1654 content1 = '{"key": "value1"}'
16231655
=== modified file 'u1db/tests/test_query_parser.py'
--- u1db/tests/test_query_parser.py 2012-07-25 16:20:27 +0000
+++ u1db/tests/test_query_parser.py 2012-07-26 12:03:19 +0000
@@ -59,6 +59,12 @@
59 self.parser.parse('lower(split_words(field1))'),59 self.parser.parse('lower(split_words(field1))'),
60 query_parser.Lower)60 query_parser.Lower)
6161
62 def test_nested_branching_mapping(self):
63 self.assertIsInstance(
64 self.parser.parse(
65 'combine(lower(field1), split_words(field2), '
66 'number(field3, 5))'), query_parser.Combine)
67
62 def test_single_mapping_multiple_fields(self):68 def test_single_mapping_multiple_fields(self):
63 self.assertIsInstance(69 self.assertIsInstance(
64 self.parser.parse('number(field1, 5)'), query_parser.Number)70 self.parser.parse('number(field1, 5)'), query_parser.Number)

Subscribers

People subscribed via source and target branches