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)
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)
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, )
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, )
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, )
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, )
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, )
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")
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")
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`"]
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`"]
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"]
def test_split_field_path_w_simple_field(): from google.cloud.firestore_v1 import field_path assert field_path.split_field_path("a") == ["a"]
def test_split_field_path_w_empty(): from google.cloud.firestore_v1 import field_path assert field_path.split_field_path("") == []
def _call_fut(path): from google.cloud.firestore_v1 import field_path return field_path.split_field_path(path)
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, )
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")