コード例 #1
0
    def test_success(self):
        from google.cloud.firestore_v1beta1.gapic import enums
        from google.cloud.firestore_v1beta1.proto import query_pb2
        from google.cloud.firestore_v1beta1 import _helpers

        field_path1 = 'a'
        field_path2 = 'a.b'
        field_path3 = 'x'
        direction1 = enums.StructuredQuery.Direction.DESCENDING
        direction2 = enums.StructuredQuery.Direction.ASCENDING
        direction3 = enums.StructuredQuery.Direction.ASCENDING
        orders = (
            _make_order_pb(field_path1, direction1),
            _make_order_pb(field_path2, direction2),
            _make_order_pb(field_path3, direction3),
        )
        data = {
            'a': {
                'b': 10,
                'c': 1.5,
            },
            'x': True,
        }
        cursor_pair = data, True

        cursor_pb = self._call_fut(cursor_pair, orders)
        expected_pb = query_pb2.Cursor(
            values=[
                _helpers.encode_value(data['a']),
                _helpers.encode_value(data['a']['b']),
                _helpers.encode_value(data['x']),
            ],
            before=True,
        )
        self.assertEqual(cursor_pb, expected_pb)
コード例 #2
0
    def test_success(self):
        from google.cloud.firestore_v1beta1.gapic import enums
        from google.cloud.firestore_v1beta1.proto import query_pb2
        from google.cloud.firestore_v1beta1 import _helpers

        field_path1 = 'a'
        field_path2 = 'a.b'
        field_path3 = 'x'
        direction1 = enums.StructuredQuery.Direction.DESCENDING
        direction2 = enums.StructuredQuery.Direction.ASCENDING
        direction3 = enums.StructuredQuery.Direction.ASCENDING
        orders = (
            _make_order_pb(field_path1, direction1),
            _make_order_pb(field_path2, direction2),
            _make_order_pb(field_path3, direction3),
        )
        data = {
            'a': {
                'b': 10,
                'c': 1.5,
            },
            'x': True,
        }
        cursor_pair = data, True

        cursor_pb = self._call_fut(cursor_pair, orders)
        expected_pb = query_pb2.Cursor(
            values=[
                _helpers.encode_value(data['a']),
                _helpers.encode_value(data['a']['b']),
                _helpers.encode_value(data['x']),
            ],
            before=True,
        )
        self.assertEqual(cursor_pb, expected_pb)
コード例 #3
0
    def _comparator(self, doc1, doc2):
        _orders = self._orders

        # Add implicit sorting by name, using the last specified direction.
        if len(_orders) == 0:
            lastDirection = Query.ASCENDING
        else:
            if _orders[-1].direction == 1:
                lastDirection = Query.ASCENDING
            else:
                lastDirection = Query.DESCENDING

        orderBys = list(_orders)

        order_pb = query_pb2.StructuredQuery.Order(
            field=query_pb2.StructuredQuery.FieldReference(field_path="id"),
            direction=_enum_from_direction(lastDirection),
        )
        orderBys.append(order_pb)

        for orderBy in orderBys:
            if orderBy.field.field_path == "id":
                # If ordering by docuent id, compare resource paths.
                comp = Order()._compare_to(doc1.reference._path, doc2.reference._path)
            else:
                if (
                    orderBy.field.field_path not in doc1._data
                    or orderBy.field.field_path not in doc2._data
                ):
                    raise ValueError(
                        "Can only compare fields that exist in the "
                        "DocumentSnapshot. Please include the fields you are "
                        "ordering on in your select() call."
                    )
                v1 = doc1._data[orderBy.field.field_path]
                v2 = doc2._data[orderBy.field.field_path]
                encoded_v1 = _helpers.encode_value(v1)
                encoded_v2 = _helpers.encode_value(v2)
                comp = Order().compare(encoded_v1, encoded_v2)

            if comp != 0:
                # 1 == Ascending, -1 == Descending
                return orderBy.direction * comp

        return 0
コード例 #4
0
    def _comparator(self, doc1, doc2):
        _orders = self._orders

        # Add implicit sorting by name, using the last specified direction.
        if len(_orders) == 0:
            lastDirection = Query.ASCENDING
        else:
            if _orders[-1].direction == 1:
                lastDirection = Query.ASCENDING
            else:
                lastDirection = Query.DESCENDING

        orderBys = list(_orders)

        order_pb = query_pb2.StructuredQuery.Order(
            field=query_pb2.StructuredQuery.FieldReference(field_path="id"),
            direction=_enum_from_direction(lastDirection),
        )
        orderBys.append(order_pb)

        for orderBy in orderBys:
            if orderBy.field.field_path == "id":
                # If ordering by docuent id, compare resource paths.
                comp = Order()._compare_to(doc1.reference._path, doc2.reference._path)
            else:
                if (
                    orderBy.field.field_path not in doc1._data
                    or orderBy.field.field_path not in doc2._data
                ):
                    raise ValueError(
                        "Can only compare fields that exist in the "
                        "DocumentSnapshot. Please include the fields you are "
                        "ordering on in your select() call."
                    )
                v1 = doc1._data[orderBy.field.field_path]
                v2 = doc2._data[orderBy.field.field_path]
                encoded_v1 = _helpers.encode_value(v1)
                encoded_v2 = _helpers.encode_value(v2)
                comp = Order().compare(encoded_v1, encoded_v2)

            if comp != 0:
                # 1 == Ascending, -1 == Descending
                return orderBy.direction * comp

        return 0
コード例 #5
0
    def _make_field_filter_pb(field_path, op_string, value):
        from google.cloud.firestore_v1beta1.proto import query_pb2
        from google.cloud.firestore_v1beta1 import _helpers
        from google.cloud.firestore_v1beta1.query import _enum_from_op_string

        return 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),
        )
コード例 #6
0
    def _make_field_filter_pb(field_path, op_string, value):
        from google.cloud.firestore_v1beta1.proto import query_pb2
        from google.cloud.firestore_v1beta1 import _helpers
        from google.cloud.firestore_v1beta1.query import _enum_from_op_string

        return 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),
        )
コード例 #7
0
def _cursor_pb(cursor_pair, orders):
    """Convert a cursor pair to a protobuf.

    If ``cursor_pair`` is :data:`None`, just returns :data:`None`.

    Args:
        cursor_pair (Optional[Tuple[dict, bool]]): Two-tuple of

            * a mapping of fields. Any field that is present in this mapping
              must also be present in ``orders``
            * a ``before`` flag

        orders (Tuple[google.cloud.proto.firestore.v1beta1.\
            query_pb2.StructuredQuery.Order, ...]]): The "order by" entries
            to use for a query. (We use this rather than a list of field path
            strings just because it is how a query stores calls
            to ``order_by``.)

    Returns:
        Optional[google.cloud.firestore_v1beta1.types.Cursor]: A
        protobuf cursor corresponding to the values.

    Raises:
        ValueError: If ``cursor_pair`` is not :data:`None`, but there are
            no ``orders``.
        ValueError: If one of the field paths in ``orders`` is not contained
            in the ``data`` (i.e. the first component of ``cursor_pair``).
    """
    if cursor_pair is None:
        return None

    if len(orders) == 0:
        raise ValueError(_NO_ORDERS_FOR_CURSOR)

    data, before = cursor_pair
    value_pbs = []
    for order in orders:
        field_path = order.field.field_path
        try:
            value = _helpers.get_nested_value(field_path, data)
        except KeyError:
            msg = _MISSING_ORDER_BY.format(field_path, data)
            raise ValueError(msg)

        value_pb = _helpers.encode_value(value)
        value_pbs.append(value_pb)

    return query_pb2.Cursor(values=value_pbs, before=before)
コード例 #8
0
def _cursor_pb(cursor_pair):
    """Convert a cursor pair to a protobuf.

    If ``cursor_pair`` is :data:`None`, just returns :data:`None`.

    Args:
        cursor_pair (Optional[Tuple[list, bool]]): Two-tuple of

            * a list of field values.
            * a ``before`` flag

    Returns:
        Optional[google.cloud.firestore_v1beta1.types.Cursor]: A
        protobuf cursor corresponding to the values.
    """
    if cursor_pair is not None:
        data, before = cursor_pair
        value_pbs = [_helpers.encode_value(value) for value in data]
        return query_pb2.Cursor(values=value_pbs, before=before)
コード例 #9
0
def _cursor_pb(cursor_pair):
    """Convert a cursor pair to a protobuf.

    If ``cursor_pair`` is :data:`None`, just returns :data:`None`.

    Args:
        cursor_pair (Optional[Tuple[list, bool]]): Two-tuple of

            * a list of field values.
            * a ``before`` flag

    Returns:
        Optional[google.cloud.firestore_v1beta1.types.Cursor]: A
        protobuf cursor corresponding to the values.
    """
    if cursor_pair is not None:
        data, before = cursor_pair
        value_pbs = [_helpers.encode_value(value) for value in data]
        return query_pb2.Cursor(values=value_pbs, before=before)
コード例 #10
0
def _boolean_value(b):
    return encode_value(b)
コード例 #11
0
def _object_value(keysAndValues):
    return encode_value(keysAndValues)
コード例 #12
0
def _array_value(values=[]):
    return encode_value(values)
コード例 #13
0
def _geoPoint_value(latitude, longitude):
    return encode_value(GeoPoint(latitude, longitude))
コード例 #14
0
def nullValue():
    return encode_value(None)
コード例 #15
0
def _int_value(value):
    return encode_value(value)
コード例 #16
0
    def where(self, field_path, op_string, value):
        """Filter the query on a field.

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

        Returns a new :class:`~google.cloud.firestore_v1beta1.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:
            ~.firestore_v1beta1.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,
        )
コード例 #17
0
def _array_value(values=[]):
    return encode_value(values)
コード例 #18
0
def nullValue():
    return encode_value(None)
コード例 #19
0
def _string_value(s):
    if not isinstance(s, six.text_type):
        s = six.u(s)
    return encode_value(s)
コード例 #20
0
def _double_value(d):
    return encode_value(d)
コード例 #21
0
    def where(self, field_path, op_string, value):
        """Filter the query on a field.

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

        Returns a new :class:`~.firestore_v1beta1.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:
            ~.firestore_v1beta1.query.Query: A filtered query. Acts as a
            copy of the current query, modified with the newly added filter.

        Raises:
            ValueError: If ``value`` is a NaN or :data:`None` and
                ``op_string`` is not ``==``.
        """
        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,
            )
        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,
        )
コード例 #22
0
def _int_value(l):
    return encode_value(l)
コード例 #23
0
def _boolean_value(b):
    return encode_value(b)
コード例 #24
0
def _blob_value(b):
    return encode_value(b)
コード例 #25
0
def _double_value(d):
    return encode_value(d)
コード例 #26
0
def _geoPoint_value(latitude, longitude):
    return encode_value(GeoPoint(latitude, longitude))
コード例 #27
0
def _int_value(l):
    return encode_value(l)
コード例 #28
0
def _object_value(keysAndValues):
    return encode_value(keysAndValues)
コード例 #29
0
def _string_value(s):
    if not isinstance(s, six.text_type):
        s = six.u(s)
    return encode_value(s)
コード例 #30
0
def _blob_value(b):
    return encode_value(b)
コード例 #31
0
    def _call_fut(value):
        from google.cloud.firestore_v1beta1._helpers import encode_value

        return encode_value(value)