U
    $FZh2                     @  s   d Z ddlmZ ddlmZmZmZmZmZ ddl	m
Z
mZ ddl	mZ ddlmZmZ ddlmZmZmZmZmZmZmZmZ ddlmZ dd	lmZ erdd
lmZ ddl m!Z! ddl"m#Z# G dd dej$eZ%G dd deZ&dddddZ'dS )zEHelpers for applying Google Cloud Firestore changes in a transaction.    )annotations)TYPE_CHECKINGAnyCallable	GeneratorOptional)
exceptionsgapic_v1)retry)_helpersbatch)_CANT_BEGIN_CANT_COMMIT_CANT_ROLLBACK_EXCEED_ATTEMPTS_TEMPLATE_WRITE_READ_ONLYMAX_ATTEMPTSBaseTransaction_BaseTransactional)DocumentReference)Query)DocumentSnapshot)ExplainOptions)StreamGeneratorc                      s   e Zd ZdZedfdd fddZddd fd	d
Zd"dddddZddddZddddZ	e
jjdfdddddddZe
jjdfddddddddd d!Z  ZS )#TransactionaD  Accumulate read-and-write operations to be sent in a transaction.

    Args:
        client (:class:`~google.cloud.firestore_v1.client.Client`):
            The client that created this transaction.
        max_attempts (Optional[int]): The maximum number of attempts for
            the transaction (i.e. allowing retries). Defaults to
            :attr:`~google.cloud.firestore_v1.transaction.MAX_ATTEMPTS`.
        read_only (Optional[bool]): Flag indicating if the transaction
            should be read-only or should allow writes. Defaults to
            :data:`False`.
    FNonereturnc                   s"   t t| | t| || d S N)superr   __init__r   )selfclientZmax_attemptsZ	read_only	__class__ l/home/aprabhat/apps/x.techxrdev.in/venv/lib/python3.8/site-packages/google/cloud/firestore_v1/transaction.pyr    :   s    zTransaction.__init__list)	write_pbsr   c                   s"   | j rtttt| | dS )a
  Add `Write`` protobufs to this transaction.

        Args:
            write_pbs (List[google.cloud.firestore_v1.                write.Write]): A list of write protobufs to be added.

        Raises:
            ValueError: If this transaction is read-only.
        N)
_read_only
ValueErrorr   r   r   _add_write_pbs)r!   r(   r#   r%   r&   r+   >   s    
zTransaction._add_write_pbsNzbytes | None)retry_idr   c                 C  sL   | j rt| j}t|| jjj| jj| 	|d| jj
d}|j| _dS )zBegin the transaction.

        Args:
            retry_id (Optional[bytes]): Transaction ID of a transaction to be
                retried.

        Raises:
            ValueError: If the current transaction has already begun.
        )databaseoptionsrequestmetadataN)in_progressr   format_idr*   _client_firestore_apiZbegin_transaction_database_stringZ_options_protobuf_rpc_metadatatransaction)r!   r,   msgZtransaction_responser%   r%   r&   _beginM   s    
zTransaction._beginc                 C  sD   | j sttz&| jjj| jj| jd| jj	d W 5 |   X dS )zRoll back the transaction.

        Raises:
            ValueError: If no transaction is in progress.
            google.api_core.exceptions.GoogleAPICallError: If the rollback fails.
        )r-   r9   r/   N)
r2   r*   r   	_clean_upr5   r6   rollbackr7   r4   r8   )r!   r%   r%   r&   	_rollbackd   s    
	zTransaction._rollbackc                 C  sV   | j stt| jjj| jj| j| jd| jj	d}| 
  t|j| _|j| _| jS )a  Transactionally commit the changes accumulated.

        Returns:
            List[:class:`google.cloud.firestore_v1.write.WriteResult`, ...]:
            The write results corresponding to the changes committed, returned
            in the same order as the changes were applied to this transaction.
            A write result contains an ``update_time`` field.

        Raises:
            ValueError: If no transaction is in progress.
        )r-   Zwritesr9   r/   )r2   r*   r   r5   r6   commitr7   Z
_write_pbsr4   r8   r<   r'   Zwrite_resultsZcommit_time)r!   Zcommit_responser%   r%   r&   _commit{   s    	zTransaction._commitzretries.Retry | object | Nonezfloat | Nonez&Generator[DocumentSnapshot, Any, None])
referencesr
   timeoutr   c                 C  s$   t ||}| jj|fd| i|S )ao  Retrieves multiple documents from Firestore.

        Args:
            references (List[.DocumentReference, ...]): Iterable of document
                references to be retrieved.
            retry (google.api_core.retry.Retry): Designation of what errors, if any,
                should be retried.  Defaults to a system-specified policy.
            timeout (float): The timeout for this request.  Defaults to a
                system-specified value.

        Yields:
            .DocumentSnapshot: The next document snapshot that fulfills the
            query, or :data:`None` if the document does not exist.
        r9   )r   make_retry_timeout_kwargsr5   get_all)r!   rA   r
   rB   kwargsr%   r%   r&   rD      s    zTransaction.get_all)explain_optionszDocumentReference | QueryzOptional[float]zOptional[ExplainOptions]zJStreamGenerator[DocumentSnapshot] | Generator[DocumentSnapshot, Any, None])ref_or_queryr
   rB   rF   r   c                C  sz   t ||}t|tr@|dk	r&td| jj|gfd| i|S t|trn|dk	rZ||d< |jf d| i|S tddS )a  Retrieve a document or a query result from the database.

        Args:
            ref_or_query (DocumentReference | Query):
                The document references or query object to return.
            retry (google.api_core.retry.Retry): Designation of what errors, if any,
                should be retried.  Defaults to a system-specified policy.
            timeout (float): The timeout for this request.  Defaults to a
                system-specified value.
            explain_options
                (Optional[:class:`~google.cloud.firestore_v1.query_profile.ExplainOptions`]):
                Options to enable query profiling for this query. When set,
                explain_metrics will be available on the returned generator.
                Can only be used when running a query, not a document reference.

        Yields:
            .DocumentSnapshot: The next document snapshot that fulfills the
            query, or :data:`None` if the document does not exist.

        Raises:
            ValueError: if `ref_or_query` is not one of the supported types, or
            explain_options is provided when `ref_or_query` is a document
            reference.
        Nz^When type of `ref_or_query` is `AsyncDocumentReference`, `explain_options` cannot be provided.r9   rF   zIValue for argument "ref_or_query" must be a DocumentReference or a Query.)	r   rC   
isinstancer   r*   r5   rD   r   stream)r!   rG   r
   rB   rF   rE   r%   r%   r&   get   s     

zTransaction.get)N)__name__
__module____qualname____doc__r   r    r+   r;   r>   r@   r	   methodDEFAULTrD   rJ   __classcell__r%   r%   r#   r&   r   ,   s    r   c                      sD   e Zd ZdZdd fddZdddd	d
ZddddZ  ZS )_TransactionalaY  Provide a callable object to use as a transactional decorater.

    This is surfaced via
    :func:`~google.cloud.firestore_v1.transaction.transactional`.

    Args:
        to_wrap (Callable[[:class:`~google.cloud.firestore_v1.transaction.Transaction`, ...], Any]):
            A callable that should be run (and retried) in a transaction.
    r   r   c                   s   t t| | d S r   )r   rR   r    )r!   to_wrapr#   r%   r&   r       s    z_Transactional.__init__r   r   )r9   r   c                 O  sB   |   |j| jd |j| _| jdkr0| j| _| j|f||S )am  Begin transaction and call the wrapped callable.

        Args:
            transaction
                (:class:`~google.cloud.firestore_v1.transaction.Transaction`):
                A transaction to execute the callable within.
            args (Tuple[Any, ...]): The extra positional arguments to pass
                along to the wrapped callable.
            kwargs (Dict[str, Any]): The extra keyword arguments to pass
                along to the wrapped callable.

        Returns:
            Any: result of the wrapped callable.

        Raises:
            Exception: Any failure caused by ``to_wrap``.
        )r,   N)r<   r;   r,   r4   Z
current_idrS   )r!   r9   argsrE   r%   r%   r&   _pre_commit   s    
z_Transactional._pre_commit)r9   c           
      O  s   |    |jstjnd}d}zxt|jD ]R}| j|f||}z|  |W   W S  |k
rx } z|}W 5 d}~X Y q(X q(t	|j}	t
|	|W n tk
r   |   Y nX dS )a  Execute the wrapped callable within a transaction.

        Args:
            transaction
                (:class:`~google.cloud.firestore_v1.transaction.Transaction`):
                A transaction to execute the callable within.
            args (Tuple[Any, ...]): The extra positional arguments to pass
                along to the wrapped callable.
            kwargs (Dict[str, Any]): The extra keyword arguments to pass
                along to the wrapped callable.

        Returns:
            Any: The result of the wrapped callable.

        Raises:
            ValueError: If the transaction does not succeed in
                ``max_attempts``.
        r%   N)_resetr)   r   ZAbortedrangeZ_max_attemptsrU   r@   r   r3   r*   BaseExceptionr>   )
r!   r9   rT   rE   Zretryable_exceptionslast_excattemptresultexcr:   r%   r%   r&   __call__  s"    	z_Transactional.__call__)rK   rL   rM   rN   r    rU   r]   rQ   r%   r%   r#   r&   rR      s   
rR   r   )rS   r   c                 C  s   t | S )a  Decorate a callable so that it runs in a transaction.

    Args:
        to_wrap
            (Callable[[:class:`~google.cloud.firestore_v1.transaction.Transaction`, ...], Any]):
            A callable that should be run (and retried) in a transaction.

    Returns:
        Callable[[:class:`~google.cloud.firestore_v1.transaction.Transaction`, ...], Any]:
        the wrapped callable.
    )rR   )rS   r%   r%   r&   transactional=  s    r^   N)(rN   
__future__r   typingr   r   r   r   r   Zgoogle.api_corer   r	   r
   retriesZgoogle.cloud.firestore_v1r   r   Z*google.cloud.firestore_v1.base_transactionr   r   r   r   r   r   r   r   Z"google.cloud.firestore_v1.documentr   Zgoogle.cloud.firestore_v1.queryr   Z'google.cloud.firestore_v1.base_documentr   Z'google.cloud.firestore_v1.query_profiler   Z*google.cloud.firestore_v1.stream_generatorr   Z
WriteBatchr   rR   r^   r%   r%   r%   r&   <module>   s    (
 6\