Skip to content

Commit

Permalink
Factor out value_pb bits from '_get_value_from_property_pb'.
Browse files Browse the repository at this point in the history
  • Loading branch information
tseaver committed Oct 16, 2014
1 parent 8bf8bad commit 0a2cd13
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 32 deletions.
54 changes: 36 additions & 18 deletions gcloud/datastore/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ def _get_protobuf_attribute_and_value(val):
return name + '_value', value


def _get_value_from_property_pb(pb):
"""Given a protobuf for a Property, get the correct value.
def _get_value_from_value_pb(value_pb):
"""Given a protobuf for a Value, get the correct value.
The Cloud Datastore Protobuf API returns a Property Protobuf
which has one value set and the rest blank.
Expand All @@ -82,40 +82,58 @@ def _get_value_from_property_pb(pb):
Some work is done to coerce the return value into a more useful type
(particularly in the case of a timestamp value, or a key value).
:type pb: :class:`gcloud.datastore.datastore_v1_pb2.Property`
:param pb: The Property Protobuf.
:type value_pb: :class:`gcloud.datastore.datastore_v1_pb2.Value`
:param value_pb: The Value Protobuf.
:returns: The value provided by the Protobuf.
"""

if pb.value.HasField('timestamp_microseconds_value'):
microseconds = pb.value.timestamp_microseconds_value
if value_pb.HasField('timestamp_microseconds_value'):
microseconds = value_pb.timestamp_microseconds_value
naive = (datetime.utcfromtimestamp(0) +
timedelta(microseconds=microseconds))
return naive.replace(tzinfo=pytz.utc)

elif pb.value.HasField('key_value'):
return Key.from_protobuf(pb.value.key_value)
elif value_pb.HasField('key_value'):
return Key.from_protobuf(value_pb.key_value)

elif pb.value.HasField('boolean_value'):
return pb.value.boolean_value
elif value_pb.HasField('boolean_value'):
return value_pb.boolean_value

elif pb.value.HasField('double_value'):
return pb.value.double_value
elif value_pb.HasField('double_value'):
return value_pb.double_value

elif pb.value.HasField('integer_value'):
return pb.value.integer_value
elif value_pb.HasField('integer_value'):
return value_pb.integer_value

elif pb.value.HasField('string_value'):
return pb.value.string_value
elif value_pb.HasField('string_value'):
return value_pb.string_value

elif pb.value.HasField('entity_value'):
return Entity.from_protobuf(pb.value.entity_value)
elif value_pb.HasField('entity_value'):
return Entity.from_protobuf(value_pb.entity_value)

else:
return None


def _get_value_from_property_pb(property_pb):
"""Given a protobuf for a Property, get the correct value.
The Cloud Datastore Protobuf API returns a Property Protobuf
which has one value set and the rest blank.
This function retrieves the the one value provided.
Some work is done to coerce the return value into a more useful type
(particularly in the case of a timestamp value, or a key value).
:type property_pb: :class:`gcloud.datastore.datastore_v1_pb2.Property`
:param property_pb: The Property Protobuf.
:returns: The value provided by the Protobuf.
"""
return _get_value_from_value_pb(property_pb.value)


def _set_protobuf_value(value_pb, val):
"""Assign 'val' to the correct subfield of 'value_pb'.
Expand Down
43 changes: 29 additions & 14 deletions gcloud/datastore/test__helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,19 @@ def test_object(self):
self.assertRaises(ValueError, self._callFUT, object())


class Test__get_value_from_property_pb(unittest2.TestCase):
class Test__get_value_from_value_pb(unittest2.TestCase):

def _callFUT(self, pb):
from gcloud.datastore._helpers import _get_value_from_property_pb
from gcloud.datastore._helpers import _get_value_from_value_pb

return _get_value_from_property_pb(pb)
return _get_value_from_value_pb(pb)

def _makePB(self, attr_name, value):
from gcloud.datastore.datastore_v1_pb2 import Property
from gcloud.datastore.datastore_v1_pb2 import Value

prop = Property()
setattr(prop.value, attr_name, value)
return prop
pb = Value()
setattr(pb, attr_name, value)
return pb

def test_datetime(self):
import calendar
Expand All @@ -119,17 +119,17 @@ def test_datetime(self):
self.assertEqual(self._callFUT(pb), utc)

def test_key(self):
from gcloud.datastore.datastore_v1_pb2 import Property
from gcloud.datastore.datastore_v1_pb2 import Value
from gcloud.datastore.dataset import Dataset
from gcloud.datastore.key import Key

_DATASET = 'DATASET'
_KIND = 'KIND'
_ID = 1234
_PATH = [{'kind': _KIND, 'id': _ID}]
pb = Property()
pb = Value()
expected = Key(dataset=Dataset(_DATASET), path=_PATH).to_protobuf()
pb.value.key_value.CopyFrom(expected)
pb.key_value.CopyFrom(expected)
found = self._callFUT(pb)
self.assertEqual(found.to_protobuf(), expected)

Expand All @@ -154,11 +154,11 @@ def test_unicode(self):
self.assertEqual(self._callFUT(pb), u'str')

def test_entity(self):
from gcloud.datastore.datastore_v1_pb2 import Property
from gcloud.datastore.datastore_v1_pb2 import Value
from gcloud.datastore.entity import Entity

pb = Property()
entity_pb = pb.value.entity_value
pb = Value()
entity_pb = pb.entity_value
prop_pb = entity_pb.property.add()
prop_pb.name = 'foo'
prop_pb.value.string_value = 'Foo'
Expand All @@ -167,10 +167,25 @@ def test_entity(self):
self.assertEqual(entity['foo'], 'Foo')

def test_unknown(self):
from gcloud.datastore.datastore_v1_pb2 import Value

pb = Value()
self.assertEqual(self._callFUT(pb), None) # XXX desirable?


class Test__get_value_from_property_pb(unittest2.TestCase):

def _callFUT(self, pb):
from gcloud.datastore._helpers import _get_value_from_property_pb

return _get_value_from_property_pb(pb)

def test_it(self):
from gcloud.datastore.datastore_v1_pb2 import Property

pb = Property()
self.assertEqual(self._callFUT(pb), None) # XXX desirable?
pb.value.string_value = 'value'
self.assertEqual(self._callFUT(pb), 'value')


class Test_set_protobuf_value(unittest2.TestCase):
Expand Down

0 comments on commit 0a2cd13

Please sign in to comment.