def _normalize_cursor(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, dict): # Transform to list using orders values = [] data = document_fields for order_key in order_keys: try: values.append(_helpers.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 field in document_fields: if isinstance(field, _transform_bases): msg = _INVALID_CURSOR_TRANSFORM raise ValueError(msg) 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:`~.firestore_v1beta1.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: (A copy of) the value stored for the ``field_path``. Raises: KeyError: If the ``field_path`` does not match nested data in the snapshot. """ nested_data = _helpers.get_nested_value(field_path, self._data) return copy.deepcopy(nested_data)
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)
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, dict): # Transform to list using orders values = [] data = document_fields for order_key in order_keys: try: values.append(_helpers.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 "/" not in field: document_fields[index] = "{}/{}/{}".format( self._client._database_string, "/".join(self._parent._path), 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:`~.firestore_v1beta1.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 = _helpers.get_nested_value(field_path, self._data) return copy.deepcopy(nested_data)
def _call_fut(field_path, data): from google.cloud.firestore_v1beta1._helpers import get_nested_value return get_nested_value(field_path, data)