def test_get_nested_value_nested():
    from google.cloud.firestore_v1 import field_path

    assert field_path.get_nested_value("top1.middle2",
                                       DATA) is DATA["top1"]["middle2"]
    assert (field_path.get_nested_value("top1.middle2.bottom3", DATA) is
            DATA["top1"]["middle2"]["bottom3"])
def test_get_nested_value_bad_type():
    from google.cloud.firestore_v1 import field_path
    from google.cloud.firestore_v1.field_path import _FIELD_PATH_WRONG_TYPE

    with pytest.raises(KeyError) as exc_info:
        field_path.get_nested_value("top6.middle7", DATA)

    err_msg = _FIELD_PATH_WRONG_TYPE.format("top6", "middle7")
    assert exc_info.value.args == (err_msg, )
def test_get_nested_value_missing_key():
    from google.cloud.firestore_v1 import field_path
    from google.cloud.firestore_v1.field_path import _FIELD_PATH_MISSING_KEY

    with pytest.raises(KeyError) as exc_info:
        field_path.get_nested_value("top1.middle2.nope", DATA)

    err_msg = _FIELD_PATH_MISSING_KEY.format("nope", "top1.middle2")
    assert exc_info.value.args == (err_msg, )
def test_get_nested_value_missing_top_level():
    from google.cloud.firestore_v1 import field_path
    from google.cloud.firestore_v1.field_path import _FIELD_PATH_MISSING_TOP

    path = "top8"
    with pytest.raises(KeyError) as exc_info:
        field_path.get_nested_value(path, DATA)

    err_msg = _FIELD_PATH_MISSING_TOP.format(path)
    assert exc_info.value.args == (err_msg, )
    def _normalize_cursor(self, cursor, orders) -> Optional[Tuple[Any, Any]]:
        """Helper: convert cursor to a list of values based on orders."""
        if cursor is None:
            return

        if not orders:
            raise ValueError(_NO_ORDERS_FOR_CURSOR)

        document_fields, before = cursor

        order_keys = [order.field.field_path for order in orders]

        if isinstance(document_fields, document.DocumentSnapshot):
            snapshot = document_fields
            document_fields = snapshot.to_dict()
            document_fields["__name__"] = snapshot.reference

        if isinstance(document_fields, dict):
            # Transform to list using orders
            values = []
            data = document_fields

            # It isn't required that all order by have a cursor.
            # However, we need to be sure they are specified in order without gaps
            for order_key in order_keys[:len(data)]:
                try:
                    if order_key in data:
                        values.append(data[order_key])
                    else:
                        values.append(
                            field_path_module.get_nested_value(
                                order_key, data))
                except KeyError:
                    msg = _MISSING_ORDER_BY.format(order_key, data)
                    raise ValueError(msg)

            document_fields = values

        if document_fields and len(document_fields) > len(orders):
            msg = _MISMATCH_CURSOR_W_ORDER_BY.format(document_fields,
                                                     order_keys)
            raise ValueError(msg)

        _transform_bases = (transforms.Sentinel, transforms._ValueList)

        for index, key_field in enumerate(zip(order_keys, document_fields)):
            key, field = key_field

            if isinstance(field, _transform_bases):
                msg = _INVALID_CURSOR_TRANSFORM
                raise ValueError(msg)

            if key == "__name__" and isinstance(field, str):
                document_fields[index] = self._parent.document(field)

        return document_fields, before
Exemple #6
0
    def _normalize_cursor(self, cursor, orders):
        """Helper: convert cursor to a list of values based on orders."""
        if cursor is None:
            return

        if not orders:
            raise ValueError(_NO_ORDERS_FOR_CURSOR)

        document_fields, before = cursor

        order_keys = [order.field.field_path for order in orders]

        if isinstance(document_fields, document.DocumentSnapshot):
            snapshot = document_fields
            document_fields = snapshot.to_dict()
            document_fields["__name__"] = snapshot.reference

        if isinstance(document_fields, dict):
            # Transform to list using orders
            values = []
            data = document_fields
            for order_key in order_keys:
                try:
                    if order_key in data:
                        values.append(data[order_key])
                    else:
                        values.append(
                            field_path_module.get_nested_value(
                                order_key, data))
                except KeyError:
                    msg = _MISSING_ORDER_BY.format(order_key, data)
                    raise ValueError(msg)
            document_fields = values

        if len(document_fields) != len(orders):
            msg = _MISMATCH_CURSOR_W_ORDER_BY.format(document_fields,
                                                     order_keys)
            raise ValueError(msg)

        _transform_bases = (transforms.Sentinel, transforms._ValueList)

        for index, key_field in enumerate(zip(order_keys, document_fields)):
            key, field = key_field

            if isinstance(field, _transform_bases):
                msg = _INVALID_CURSOR_TRANSFORM
                raise ValueError(msg)

            if key == "__name__" and isinstance(field, six.string_types):
                document_fields[index] = self._parent.document(field)

        return document_fields, before
    def _normalize_cursor(self, cursor, orders):
        """Helper: convert cursor to a list of values based on orders."""
        if cursor is None:
            return

        if not orders:
            raise ValueError(_NO_ORDERS_FOR_CURSOR)

        document_fields, before = cursor

        order_keys = [order.field.field_path for order in orders]

        if isinstance(document_fields, document.DocumentSnapshot):
            snapshot = document_fields
            document_fields = snapshot.to_dict()
            document_fields["__name__"] = snapshot.reference

        if isinstance(document_fields, dict):
            # Transform to list using orders
            values = []
            data = document_fields
            for order_key in order_keys:
                try:
                    values.append(field_path_module.get_nested_value(order_key, data))
                except KeyError:
                    msg = _MISSING_ORDER_BY.format(order_key, data)
                    raise ValueError(msg)
            document_fields = values

        if len(document_fields) != len(orders):
            msg = _MISMATCH_CURSOR_W_ORDER_BY.format(document_fields, order_keys)
            raise ValueError(msg)

        _transform_bases = (transforms.Sentinel, transforms._ValueList)

        for index, key_field in enumerate(zip(order_keys, document_fields)):
            key, field = key_field

            if isinstance(field, _transform_bases):
                msg = _INVALID_CURSOR_TRANSFORM
                raise ValueError(msg)

            if key == "__name__" and isinstance(field, six.string_types):
                document_fields[index] = self._parent.document(field)

        return document_fields, before
    def get(self, field_path):
        """Get a value from the snapshot data.

        If the data is nested, for example:

        .. code-block:: python

           >>> snapshot.to_dict()
           {
               'top1': {
                   'middle2': {
                       'bottom3': 20,
                       'bottom4': 22,
                   },
                   'middle5': True,
               },
               'top6': b'\x00\x01 foo',
           }

        a **field path** can be used to access the nested data. For
        example:

        .. code-block:: python

           >>> snapshot.get('top1')
           {
               'middle2': {
                   'bottom3': 20,
                   'bottom4': 22,
               },
               'middle5': True,
           }
           >>> snapshot.get('top1.middle2')
           {
               'bottom3': 20,
               'bottom4': 22,
           }
           >>> snapshot.get('top1.middle2.bottom3')
           20

        See :meth:`~google.cloud.firestore_v1.client.Client.field_path` for
        more information on **field paths**.

        A copy is returned since the data may contain mutable values,
        but the data stored in the snapshot must remain immutable.

        Args:
            field_path (str): A field path (``.``-delimited list of
                field names).

        Returns:
            Any or None:
                (A copy of) the value stored for the ``field_path`` or
                None if snapshot document does not exist.

        Raises:
            KeyError: If the ``field_path`` does not match nested data
                in the snapshot.
        """
        if not self._exists:
            return None
        nested_data = field_path_module.get_nested_value(field_path, self._data)
        return copy.deepcopy(nested_data)
    def get(self, field_path: str) -> Any:
        """Get a value from the snapshot data.

        If the data is nested, for example:

        .. code-block:: python

           >>> snapshot.to_dict()
           {
               'top1': {
                   'middle2': {
                       'bottom3': 20,
                       'bottom4': 22,
                   },
                   'middle5': True,
               },
               'top6': b'\x00\x01 foo',
           }

        a **field path** can be used to access the nested data. For
        example:

        .. code-block:: python

           >>> snapshot.get('top1')
           {
               'middle2': {
                   'bottom3': 20,
                   'bottom4': 22,
               },
               'middle5': True,
           }
           >>> snapshot.get('top1.middle2')
           {
               'bottom3': 20,
               'bottom4': 22,
           }
           >>> snapshot.get('top1.middle2.bottom3')
           20

        See :meth:`~google.cloud.firestore_v1.client.Client.field_path` for
        more information on **field paths**.

        A copy is returned since the data may contain mutable values,
        but the data stored in the snapshot must remain immutable.

        Args:
            field_path (str): A field path (``.``-delimited list of
                field names).

        Returns:
            Any or None:
                (A copy of) the value stored for the ``field_path`` or
                None if snapshot document does not exist.

        Raises:
            KeyError: If the ``field_path`` does not match nested data
                in the snapshot.
        """
        if not self._exists:
            return None
        nested_data = field_path_module.get_nested_value(
            field_path, self._data)
        return copy.deepcopy(nested_data)
def test_get_nested_value_simple():
    from google.cloud.firestore_v1 import field_path

    assert field_path.get_nested_value("top1", DATA) is DATA["top1"]
Exemple #11
0
    def _call_fut(path, data):
        from google.cloud.firestore_v1 import field_path

        return field_path.get_nested_value(path, data)
    def _call_fut(path, data):
        from google.cloud.firestore_v1 import field_path

        return field_path.get_nested_value(path, data)