예제 #1
0
    def order_by(self,
                 field_path: str,
                 direction: str = ASCENDING) -> "BaseQuery":
        """Modify the query to add an order clause on a specific field.

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

        Successive :meth:`~google.cloud.firestore_v1.query.Query.order_by`
        calls will further refine the ordering of results returned by the query
        (i.e. the new "order by" fields will be added to existing ones).

        Args:
            field_path (str): A field path (``.``-delimited list of
                field names) on which to order the query results.
            direction (Optional[str]): The direction to order by. Must be one
                of :attr:`ASCENDING` or :attr:`DESCENDING`, defaults to
                :attr:`ASCENDING`.

        Returns:
            :class:`~google.cloud.firestore_v1.query.Query`:
            An ordered query. Acts as a copy of the current query, modified
            with the newly added "order by" constraint.

        Raises:
            ValueError: If ``field_path`` is invalid.
            ValueError: If ``direction`` is not one of :attr:`ASCENDING` or
                :attr:`DESCENDING`.
        """
        field_path_module.split_field_path(field_path)  # raises

        order_pb = self._make_order(field_path, direction)

        new_orders = self._orders + (order_pb, )
        return self._copy(orders=new_orders)
예제 #2
0
    def select(self, field_paths: Iterable[str]) -> "BaseQuery":
        """Project documents matching query to a limited set of fields.

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

        If the current query already has a projection set (i.e. has already
        called :meth:`~google.cloud.firestore_v1.query.Query.select`), this
        will overwrite it.

        Args:
            field_paths (Iterable[str, ...]): An iterable of field paths
                (``.``-delimited list of field names) to use as a projection
                of document fields in the query results.

        Returns:
            :class:`~google.cloud.firestore_v1.query.Query`:
            A "projected" query. Acts as a copy of the current query,
            modified with the newly added projection.
        Raises:
            ValueError: If any ``field_path`` is invalid.
        """
        field_paths = list(field_paths)
        for field_path in field_paths:
            field_path_module.split_field_path(field_path)  # raises

        new_projection = query.StructuredQuery.Projection(fields=[
            query.StructuredQuery.FieldReference(field_path=field_path)
            for field_path in field_paths
        ])
        return self._copy(projection=new_projection)
예제 #3
0
    def order_by(self, field_path, direction=ASCENDING):
        """Modify the query to add an order clause on a specific field.

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

        Successive :meth:`~google.cloud.firestore_v1.query.Query.order_by`
        calls will further refine the ordering of results returned by the query
        (i.e. the new "order by" fields will be added to existing ones).

        Args:
            field_path (str): A field path (``.``-delimited list of
                field names) on which to order the query results.
            direction (Optional[str]): The direction to order by. Must be one
                of :attr:`ASCENDING` or :attr:`DESCENDING`, defaults to
                :attr:`ASCENDING`.

        Returns:
            :class:`~google.cloud.firestore_v1.query.Query`:
            An ordered query. Acts as a copy of the current query, modified
            with the newly added "order by" constraint.

        Raises:
            ValueError: If ``field_path`` is invalid.
            ValueError: If ``direction`` is not one of :attr:`ASCENDING` or
                :attr:`DESCENDING`.
        """
        field_path_module.split_field_path(field_path)  # raises

        order_pb = self._make_order(field_path, direction)

        new_orders = self._orders + (order_pb,)
        return self.__class__(
            self._parent,
            projection=self._projection,
            field_filters=self._field_filters,
            orders=new_orders,
            limit=self._limit,
            offset=self._offset,
            start_at=self._start_at,
            end_at=self._end_at,
            all_descendants=self._all_descendants,
        )
예제 #4
0
    def select(self, field_paths):
        """Project documents matching query to a limited set of fields.

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

        If the current query already has a projection set (i.e. has already
        called :meth:`~google.cloud.firestore_v1.query.Query.select`), this
        will overwrite it.

        Args:
            field_paths (Iterable[str, ...]): An iterable of field paths
                (``.``-delimited list of field names) to use as a projection
                of document fields in the query results.

        Returns:
            :class:`~google.cloud.firestore_v1.query.Query`:
            A "projected" query. Acts as a copy of the current query,
            modified with the newly added projection.
        Raises:
            ValueError: If any ``field_path`` is invalid.
        """
        field_paths = list(field_paths)
        for field_path in field_paths:
            field_path_module.split_field_path(field_path)  # raises

        new_projection = query_pb2.StructuredQuery.Projection(
            fields=[
                query_pb2.StructuredQuery.FieldReference(field_path=field_path)
                for field_path in field_paths
            ]
        )
        return self.__class__(
            self._parent,
            projection=new_projection,
            field_filters=self._field_filters,
            orders=self._orders,
            limit=self._limit,
            offset=self._offset,
            start_at=self._start_at,
            end_at=self._end_at,
            all_descendants=self._all_descendants,
        )
예제 #5
0
    def order_by(self, field_path, direction=ASCENDING):
        """Modify the query to add an order clause on a specific field.

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

        Successive :meth:`~.firestore_v1.query.Query.order_by` calls
        will further refine the ordering of results returned by the query
        (i.e. the new "order by" fields will be added to existing ones).

        Args:
            field_path (str): A field path (``.``-delimited list of
                field names) on which to order the query results.
            direction (Optional[str]): The direction to order by. Must be one
                of :attr:`ASCENDING` or :attr:`DESCENDING`, defaults to
                :attr:`ASCENDING`.

        Returns:
            ~.firestore_v1.query.Query: An ordered query. Acts as a
            copy of the current query, modified with the newly added
            "order by" constraint.

        Raises:
            ValueError: If ``field_path`` is invalid.
            ValueError: If ``direction`` is not one of :attr:`ASCENDING` or
                :attr:`DESCENDING`.
        """
        field_path_module.split_field_path(field_path)  # raises

        order_pb = self._make_order(field_path, direction)

        new_orders = self._orders + (order_pb, )
        return self.__class__(
            self._parent,
            projection=self._projection,
            field_filters=self._field_filters,
            orders=new_orders,
            limit=self._limit,
            offset=self._offset,
            start_at=self._start_at,
            end_at=self._end_at,
            all_descendants=self._all_descendants,
        )
예제 #6
0
    def select(self, field_paths):
        """Project documents matching query to a limited set of fields.

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

        If the current query already has a projection set (i.e. has already
        called :meth:`~.firestore_v1.query.Query.select`), this
        will overwrite it.

        Args:
            field_paths (Iterable[str, ...]): An iterable of field paths
                (``.``-delimited list of field names) to use as a projection
                of document fields in the query results.

        Returns:
            ~.firestore_v1.query.Query: A "projected" query. Acts as
            a copy of the current query, modified with the newly added
            projection.
        Raises:
            ValueError: If any ``field_path`` is invalid.
        """
        field_paths = list(field_paths)
        for field_path in field_paths:
            field_path_module.split_field_path(field_path)  # raises

        new_projection = query_pb2.StructuredQuery.Projection(fields=[
            query_pb2.StructuredQuery.FieldReference(field_path=field_path)
            for field_path in field_paths
        ])
        return self.__class__(
            self._parent,
            projection=new_projection,
            field_filters=self._field_filters,
            orders=self._orders,
            limit=self._limit,
            offset=self._offset,
            start_at=self._start_at,
            end_at=self._end_at,
            all_descendants=self._all_descendants,
        )
예제 #7
0
    def where(self, field_path, op_string, value):
        """Filter the query on a field.

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

        Returns a new :class:`~google.cloud.firestore_v1.query.Query` that
        filters on a specific field path, according to an operation (e.g.
        ``==`` or "equals") and a particular value to be paired with that
        operation.

        Args:
            field_path (str): A field path (``.``-delimited list of
                field names) for the field to filter on.
            op_string (str): A comparison operation in the form of a string.
                Acceptable values are ``<``, ``<=``, ``==``, ``>=``
                and ``>``.
            value (Any): The value to compare the field against in the filter.
                If ``value`` is :data:`None` or a NaN, then ``==`` is the only
                allowed operation.

        Returns:
            :class:`~google.cloud.firestore_v1.query.Query`:
            A filtered query. Acts as a copy of the current query,
            modified with the newly added filter.

        Raises:
            ValueError: If ``field_path`` is invalid.
            ValueError: If ``value`` is a NaN or :data:`None` and
                ``op_string`` is not ``==``.
        """
        field_path_module.split_field_path(field_path)  # raises

        if value is None:
            if op_string != _EQ_OP:
                raise ValueError(_BAD_OP_NAN_NULL)
            filter_pb = query_pb2.StructuredQuery.UnaryFilter(
                field=query_pb2.StructuredQuery.FieldReference(field_path=field_path),
                op=enums.StructuredQuery.UnaryFilter.Operator.IS_NULL,
            )
        elif _isnan(value):
            if op_string != _EQ_OP:
                raise ValueError(_BAD_OP_NAN_NULL)
            filter_pb = query_pb2.StructuredQuery.UnaryFilter(
                field=query_pb2.StructuredQuery.FieldReference(field_path=field_path),
                op=enums.StructuredQuery.UnaryFilter.Operator.IS_NAN,
            )
        elif isinstance(value, (transforms.Sentinel, transforms._ValueList)):
            raise ValueError(_INVALID_WHERE_TRANSFORM)
        else:
            filter_pb = query_pb2.StructuredQuery.FieldFilter(
                field=query_pb2.StructuredQuery.FieldReference(field_path=field_path),
                op=_enum_from_op_string(op_string),
                value=_helpers.encode_value(value),
            )

        new_filters = self._field_filters + (filter_pb,)
        return self.__class__(
            self._parent,
            projection=self._projection,
            field_filters=new_filters,
            orders=self._orders,
            limit=self._limit,
            offset=self._offset,
            start_at=self._start_at,
            end_at=self._end_at,
            all_descendants=self._all_descendants,
        )
예제 #8
0
def test_split_field_path_w_half_quoted_field():
    from google.cloud.firestore_v1 import field_path

    with pytest.raises(ValueError):
        field_path.split_field_path("`c*de")
예제 #9
0
def test_split_field_path_w_missing_dot():
    from google.cloud.firestore_v1 import field_path

    with pytest.raises(ValueError):
        field_path.split_field_path("a`c*de`f")
예제 #10
0
def test_split_field_path_w_quoted_field_escaped_backtick():
    from google.cloud.firestore_v1 import field_path

    assert field_path.split_field_path(r"`c*\`de`") == [r"`c*\`de`"]
예제 #11
0
def test_split_field_path_w_quoted_field():
    from google.cloud.firestore_v1 import field_path

    assert field_path.split_field_path("a.b.`c*de`") == ["a", "b", "`c*de`"]
예제 #12
0
def test_split_field_path_w_dotted_field():
    from google.cloud.firestore_v1 import field_path

    assert field_path.split_field_path("a.b.cde") == ["a", "b", "cde"]
예제 #13
0
def test_split_field_path_w_simple_field():
    from google.cloud.firestore_v1 import field_path

    assert field_path.split_field_path("a") == ["a"]
예제 #14
0
def test_split_field_path_w_empty():
    from google.cloud.firestore_v1 import field_path

    assert field_path.split_field_path("") == []
예제 #15
0
    def _call_fut(path):
        from google.cloud.firestore_v1 import field_path

        return field_path.split_field_path(path)
    def _call_fut(path):
        from google.cloud.firestore_v1 import field_path

        return field_path.split_field_path(path)
예제 #17
0
    def where(self, field_path: str, op_string: str, value) -> "BaseQuery":
        """Filter the query on a field.

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

        Returns a new :class:`~google.cloud.firestore_v1.query.Query` that
        filters on a specific field path, according to an operation (e.g.
        ``==`` or "equals") and a particular value to be paired with that
        operation.

        Args:
            field_path (str): A field path (``.``-delimited list of
                field names) for the field to filter on.
            op_string (str): A comparison operation in the form of a string.
                Acceptable values are ``<``, ``<=``, ``==``, ``>=``, ``>``,
                ``in``, ``array_contains`` and ``array_contains_any``.
            value (Any): The value to compare the field against in the filter.
                If ``value`` is :data:`None` or a NaN, then ``==`` is the only
                allowed operation.

        Returns:
            :class:`~google.cloud.firestore_v1.query.Query`:
            A filtered query. Acts as a copy of the current query,
            modified with the newly added filter.

        Raises:
            ValueError: If ``field_path`` is invalid.
            ValueError: If ``value`` is a NaN or :data:`None` and
                ``op_string`` is not ``==``.
        """
        field_path_module.split_field_path(field_path)  # raises

        if value is None:
            if op_string != _EQ_OP:
                raise ValueError(_BAD_OP_NAN_NULL)
            filter_pb = query.StructuredQuery.UnaryFilter(
                field=query.StructuredQuery.FieldReference(field_path=field_path),
                op=StructuredQuery.UnaryFilter.Operator.IS_NULL,
            )
        elif _isnan(value):
            if op_string != _EQ_OP:
                raise ValueError(_BAD_OP_NAN_NULL)
            filter_pb = query.StructuredQuery.UnaryFilter(
                field=query.StructuredQuery.FieldReference(field_path=field_path),
                op=StructuredQuery.UnaryFilter.Operator.IS_NAN,
            )
        elif isinstance(value, (transforms.Sentinel, transforms._ValueList)):
            raise ValueError(_INVALID_WHERE_TRANSFORM)
        else:
            filter_pb = query.StructuredQuery.FieldFilter(
                field=query.StructuredQuery.FieldReference(field_path=field_path),
                op=_enum_from_op_string(op_string),
                value=_helpers.encode_value(value),
            )

        new_filters = self._field_filters + (filter_pb,)
        return self.__class__(
            self._parent,
            projection=self._projection,
            field_filters=new_filters,
            orders=self._orders,
            limit=self._limit,
            offset=self._offset,
            limit_to_last=self._limit_to_last,
            start_at=self._start_at,
            end_at=self._end_at,
            all_descendants=self._all_descendants,
        )
예제 #18
0
def test_split_field_path_w_leading_dot():
    from google.cloud.firestore_v1 import field_path

    with pytest.raises(ValueError):
        field_path.split_field_path(".a.b.c")