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)
Exemplo n.º 2
0
    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])
Exemplo n.º 3
0
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)