Skip to content

Commit edfd5e2

Browse files
committed
Merge pull request #541 from dhermes/fix-513
Preserving indexed=False from parsed proto `Value`s.
2 parents be8f5fb + 7720cc0 commit edfd5e2

File tree

2 files changed

+76
-4
lines changed

2 files changed

+76
-4
lines changed

gcloud/datastore/helpers.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
1717
The non-private functions are part of the API.
1818
"""
19+
1920
__all__ = ('entity_from_protobuf', 'key_from_protobuf')
2021

2122
import calendar
@@ -45,12 +46,30 @@ def entity_from_protobuf(pb):
4546
:returns: The entity derived from the protobuf.
4647
"""
4748
key = key_from_protobuf(pb.key)
48-
entity = Entity(key=key)
49+
entity_props = {}
50+
exclude_from_indexes = []
4951

5052
for property_pb in pb.property:
5153
value = _get_value_from_property_pb(property_pb)
52-
entity[property_pb.name] = value
53-
54+
entity_props[property_pb.name] = value
55+
56+
# Check if property_pb.value was indexed. Lists need to be
57+
# special-cased and we require all `indexed` values in a list agree.
58+
if isinstance(value, list):
59+
indexed_values = set(value_pb.indexed
60+
for value_pb in property_pb.value.list_value)
61+
if len(indexed_values) != 1:
62+
raise ValueError('For a list_value, subvalues must either all '
63+
'be indexed or all excluded from indexes.')
64+
65+
if not indexed_values.pop():
66+
exclude_from_indexes.append(property_pb.name)
67+
else:
68+
if not property_pb.value.indexed:
69+
exclude_from_indexes.append(property_pb.name)
70+
71+
entity = Entity(key=key, exclude_from_indexes=exclude_from_indexes)
72+
entity.update(entity_props)
5473
return entity
5574

5675

gcloud/datastore/test_helpers.py

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,68 @@ def test_it(self):
4242
prop_pb = entity_pb.property.add()
4343
prop_pb.name = 'foo'
4444
prop_pb.value.string_value = 'Foo'
45+
46+
unindexed_prop_pb = entity_pb.property.add()
47+
unindexed_prop_pb.name = 'bar'
48+
unindexed_prop_pb.value.integer_value = 10
49+
unindexed_prop_pb.value.indexed = False
50+
51+
list_prop_pb1 = entity_pb.property.add()
52+
list_prop_pb1.name = 'baz'
53+
list_pb1 = list_prop_pb1.value.list_value
54+
55+
unindexed_value_pb = list_pb1.add()
56+
unindexed_value_pb.integer_value = 11
57+
unindexed_value_pb.indexed = False
58+
59+
list_prop_pb2 = entity_pb.property.add()
60+
list_prop_pb2.name = 'qux'
61+
list_pb2 = list_prop_pb2.value.list_value
62+
63+
indexed_value_pb = list_pb2.add()
64+
indexed_value_pb.integer_value = 12
65+
indexed_value_pb.indexed = True
66+
4567
entity = self._callFUT(entity_pb)
4668
self.assertEqual(entity.kind, _KIND)
47-
self.assertEqual(entity['foo'], 'Foo')
69+
self.assertEqual(entity.exclude_from_indexes,
70+
frozenset(['bar', 'baz']))
71+
entity_props = dict(entity)
72+
self.assertEqual(entity_props,
73+
{'foo': 'Foo', 'bar': 10, 'baz': [11], 'qux': [12]})
74+
75+
# Also check the key.
4876
key = entity.key
4977
self.assertEqual(key.dataset_id, _DATASET_ID)
5078
self.assertEqual(key.namespace, None)
5179
self.assertEqual(key.kind, _KIND)
5280
self.assertEqual(key.id, _ID)
5381

82+
def test_mismatched_value_indexed(self):
83+
from gcloud.datastore import _datastore_v1_pb2 as datastore_pb
84+
85+
_DATASET_ID = 'DATASET'
86+
_KIND = 'KIND'
87+
_ID = 1234
88+
entity_pb = datastore_pb.Entity()
89+
entity_pb.key.partition_id.dataset_id = _DATASET_ID
90+
entity_pb.key.path_element.add(kind=_KIND, id=_ID)
91+
92+
list_prop_pb = entity_pb.property.add()
93+
list_prop_pb.name = 'baz'
94+
list_pb = list_prop_pb.value.list_value
95+
96+
unindexed_value_pb1 = list_pb.add()
97+
unindexed_value_pb1.integer_value = 10
98+
unindexed_value_pb1.indexed = False
99+
100+
unindexed_value_pb2 = list_pb.add()
101+
unindexed_value_pb2.integer_value = 11
102+
unindexed_value_pb2.indexed = True
103+
104+
with self.assertRaises(ValueError):
105+
self._callFUT(entity_pb)
106+
54107

55108
class Test_key_from_protobuf(unittest2.TestCase):
56109

0 commit comments

Comments
 (0)