a
    ù!f  ã                   @   s$   d Z ddlmZ G dd„ deƒZdS )z5Create / interact with gcloud datastore transactions.é    )ÚBatchc                       s\   e Zd ZdZ‡ fdd„Zedd„ ƒZ‡ fdd„Z‡ fdd	„Z‡ fd
d„Z	‡ fdd„Z
‡  ZS )ÚTransactiona¢	  An abstraction representing datastore Transactions.

    Transactions can be used to build up a bulk mutation and ensure all
    or none succeed (transactionally).

    For example, the following snippet of code will put the two ``save``
    operations (either ``insert`` or ``upsert``) into the same
    mutation, and execute those within a transaction::

      >>> from gcloud import datastore
      >>> client = datastore.Client()
      >>> with client.transaction():
      ...     client.put_multi([entity1, entity2])

    Because it derives from :class:`Batch <.datastore.batch.Batch>`,
    :class:`Transaction` also provides :meth:`put` and :meth:`delete` methods::

      >>> with client.transaction() as xact:
      ...     xact.put(entity1)
      ...     xact.delete(entity2.key)

    By default, the transaction is rolled back if the transaction block
    exits with an error::

      >>> with client.transaction():
      ...     do_some_work()
      ...     raise SomeException()  # rolls back

    If the transaction block exists without an exception, it will commit
    by default.

    .. warning:: Inside a transaction, automatically assigned IDs for
       entities will not be available at save time!  That means, if you
       try::

         >>> with client.transaction():
         ...     entity = datastore.Entity(key=client.key('Thing'))
         ...     client.put(entity)

       ``entity`` won't have a complete key until the transaction is
       committed.

       Once you exit the transaction (or call :meth:`commit`), the
       automatically generated ID will be assigned to the entity::

         >>> with client.transaction():
         ...     entity = datastore.Entity(key=client.key('Thing'))
         ...     client.put(entity)
         ...     print(entity.key.is_partial)  # There is no ID on this key.
         ...
         True
         >>> print(entity.key.is_partial)  # There *is* an ID.
         False

    If you don't want to use the context manager you can initialize a
    transaction manually::

      >>> transaction = client.transaction()
      >>> transaction.begin()
      >>>
      >>> entity = datastore.Entity(key=client.key('Thing'))
      >>> transaction.put(entity)
      >>>
      >>> if error:
      ...     transaction.rollback()
      ... else:
      ...     transaction.commit()

    :type client: :class:`gcloud.datastore.client.Client`
    :param client: the client used to connect to datastore.
    c                    s   t t| ƒ |¡ d | _d S )N)Úsuperr   Ú__init__Ú_id)ÚselfÚclient©Ú	__class__© ú]/var/www/html/python-backend/venv/lib/python3.9/site-packages/gcloud/datastore/transaction.pyr   ]   s    zTransaction.__init__c                 C   s   | j S )ztGetter for the transaction ID.

        :rtype: string
        :returns: The ID of the current transaction.
        )r   ©r   r   r   r   Úida   s    zTransaction.idc                    s    t t| ƒ ¡ }t|tƒr|S dS )a&  Return the topmost transaction.

        .. note::

            If the topmost element on the stack is not a transaction,
            returns None.

        :rtype: :class:`gcloud.datastore.transaction.Transaction` or None
        :returns: The current transaction (if any are active).
        N)r   r   ÚcurrentÚ
isinstance)r   Útopr	   r   r   r   j   s    
zTransaction.currentc                    s"   t t| ƒ ¡  | j | j¡| _dS )a  Begins a transaction.

        This method is called automatically when entering a with
        statement, however it can be called explicitly if you don't want
        to use a context manager.

        :raises: :class:`ValueError` if the transaction has already begun.
        N)r   r   ÚbeginÚ
connectionZbegin_transactionÚprojectr   r   r	   r   r   r   y   s    	zTransaction.beginc              	      sF   z*| j  | j| j¡ W tt| ƒ ¡  d| _ntt| ƒ ¡  d| _0 dS )zÚRolls back the current transaction.

        This method has necessary side-effects:

        - Sets the current connection's transaction reference to None.
        - Sets the current transaction's ID to None.
        N)r   Úrollbackr   r   r   r   r   r	   r   r   r   …   s    þzTransaction.rollbackc                    s&   zt t| ƒ ¡  W d| _nd| _0 dS )a-  Commits the transaction.

        This is called automatically upon exiting a with statement,
        however it can be called explicitly if you don't want to use a
        context manager.

        This method has necessary side-effects:

        - Sets the current transaction's ID to None.
        N)r   r   Úcommitr   r   r	   r   r   r   ”   s    zTransaction.commit)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Úpropertyr   r   r   r   r   Ú__classcell__r   r   r	   r   r      s   H
r   N)r   Zgcloud.datastore.batchr   r   r   r   r   r   Ú<module>   s   