def test_nested_map(self): from google.cloud.firestore_v1beta1.proto import document_pb2 actual_value1 = 1009876 actual_value2 = u'hey you guys' actual_value3 = 90.875 map_pb1 = document_pb2.MapValue(fields={ 'lowest': _value_pb(integer_value=actual_value1), 'aside': _value_pb(string_value=actual_value2), }) map_pb2 = document_pb2.MapValue(fields={ 'middle': _value_pb(map_value=map_pb1), 'aside': _value_pb(boolean_value=True), }) map_pb3 = document_pb2.MapValue(fields={ 'highest': _value_pb(map_value=map_pb2), 'aside': _value_pb(double_value=actual_value3), }) value = _value_pb(map_value=map_pb3) expected = { 'highest': { 'middle': { 'lowest': actual_value1, 'aside': actual_value2, }, 'aside': True, }, 'aside': actual_value3, } self.assertEqual(self._call_fut(value), expected)
def test_update(self): from google.cloud.firestore_v1beta1.proto import common_pb2 from google.cloud.firestore_v1beta1.proto import document_pb2 from google.cloud.firestore_v1beta1.proto import write_pb2 client = _make_client() batch = self._make_one(client) self.assertEqual(batch._write_pbs, []) reference = client.document('cats', 'cradle') field_path = 'head.foot' value = u'knees toes shoulders' field_updates = {field_path: value} ret_val = batch.update(reference, field_updates) self.assertIsNone(ret_val) map_pb = document_pb2.MapValue(fields={ 'foot': _value_pb(string_value=value), }) new_write_pb = write_pb2.Write( update=document_pb2.Document( name=reference._document_path, fields={'head': _value_pb(map_value=map_pb)}, ), update_mask=common_pb2.DocumentMask(field_paths=[field_path]), current_document=common_pb2.Precondition(exists=True), ) self.assertEqual(batch._write_pbs, [new_write_pb])
def encode_value(value): """Converts a native Python value into a Firestore protobuf ``Value``. Args: value (Union[NoneType, bool, int, float, datetime.datetime, \ str, bytes, dict, ~google.cloud.Firestore.GeoPoint]): A native Python value to convert to a protobuf field. Returns: ~google.cloud.firestore_v1beta1.types.Value: A value encoded as a Firestore protobuf. Raises: TypeError: If the ``value`` is not one of the accepted types. """ if value is None: return document_pb2.Value(null_value=struct_pb2.NULL_VALUE) # Must come before six.integer_types since ``bool`` is an integer subtype. if isinstance(value, bool): return document_pb2.Value(boolean_value=value) if isinstance(value, six.integer_types): return document_pb2.Value(integer_value=value) if isinstance(value, float): return document_pb2.Value(double_value=value) if isinstance(value, datetime.datetime): return document_pb2.Value( timestamp_value=_datetime_to_pb_timestamp(value)) if isinstance(value, six.text_type): return document_pb2.Value(string_value=value) if isinstance(value, six.binary_type): return document_pb2.Value(bytes_value=value) # NOTE: We avoid doing an isinstance() check for a Document # here to avoid import cycles. document_path = getattr(value, '_document_path', None) if document_path is not None: return document_pb2.Value(reference_value=document_path) if isinstance(value, GeoPoint): return document_pb2.Value(geo_point_value=value.to_protobuf()) if isinstance(value, list): value_list = [encode_value(element) for element in value] value_pb = document_pb2.ArrayValue(values=value_list) return document_pb2.Value(array_value=value_pb) if isinstance(value, dict): value_dict = encode_dict(value) value_pb = document_pb2.MapValue(fields=value_dict) return document_pb2.Value(map_value=value_pb) raise TypeError( 'Cannot convert to a Firestore Value', value, 'Invalid type', type(value))
def _helper(self, option=None, do_transform=False, **write_kwargs): from google.cloud.firestore_v1beta1.gapic import enums from google.cloud.firestore_v1beta1.proto import common_pb2 from google.cloud.firestore_v1beta1.proto import document_pb2 from google.cloud.firestore_v1beta1.proto import write_pb2 from google.cloud.firestore_v1beta1.client import Client from google.cloud.firestore_v1beta1.constants import SERVER_TIMESTAMP document_path = _make_ref_string( u'toy', u'car', u'onion', u'garlic') field_path1 = 'bitez.yum' value = b'\x00\x01' field_path2 = 'blog.internet' field_updates = {field_path1: value} if do_transform: field_updates[field_path2] = SERVER_TIMESTAMP # NOTE: ``Client.write_option()`` is a ``@staticmethod`` so # we don't need a client instance. write_pbs = self._call_fut( Client, document_path, field_updates, option) map_pb = document_pb2.MapValue(fields={ 'yum': _value_pb(bytes_value=value), }) expected_update_pb = write_pb2.Write( update=document_pb2.Document( name=document_path, fields={'bitez': _value_pb(map_value=map_pb)}, ), update_mask=common_pb2.DocumentMask(field_paths=[field_path1]), **write_kwargs ) expected_pbs = [expected_update_pb] if do_transform: server_val = enums.DocumentTransform.FieldTransform.ServerValue expected_transform_pb = write_pb2.Write( transform=write_pb2.DocumentTransform( document=document_path, field_transforms=[ write_pb2.DocumentTransform.FieldTransform( field_path=field_path2, set_to_server_value=server_val.REQUEST_TIME, ), ], ), ) expected_pbs.append(expected_transform_pb) self.assertEqual(write_pbs, expected_pbs)
def test_map(self): from google.cloud.firestore_v1beta1.proto import document_pb2 sub_value1 = _value_pb(integer_value=187680) sub_value2 = _value_pb(string_value=u'how low can you go?') map_pb = document_pb2.MapValue(fields={ 'first': sub_value1, 'second': sub_value2, }) value = _value_pb(map_value=map_pb) expected = { 'first': sub_value1.integer_value, 'second': sub_value2.string_value, } self.assertEqual(self._call_fut(value), expected)