a
    ù!f)  ã                   @   s8   d Z ddlmZ ddlmZ G dd„ deƒZdd„ ZdS )	zûCreate / interact with a batch of updates / deletes.

Batches provide the ability to execute multiple operations
in a single request to the Cloud Datastore API.

See
https://cloud.google.com/datastore/docs/concepts/entities#Datastore_Batch_operations
é    )Úhelpers)Údatastore_pb2c                   @   s¼   e Zd ZdZdZdZdZdZdZdd„ Z	d	d
„ Z
edd„ ƒZedd„ ƒZedd„ ƒZdd„ Zdd„ Zdd„ Zedd„ ƒZdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ ZdS ))ÚBatchac  An abstraction representing a collected group of updates / deletes.

    Used to build up a bulk mutuation.

    For example, the following snippet of code will put the two ``save``
    operations and the ``delete`` operation into the same mutation, and send
    them to the server in a single API request::

      >>> from gcloud import datastore
      >>> client = datastore.Client()
      >>> batch = client.batch()
      >>> batch.put(entity1)
      >>> batch.put(entity2)
      >>> batch.delete(key3)
      >>> batch.commit()

    You can also use a batch as a context manager, in which case
    :meth:`commit` will be called automatically if its block exits without
    raising an exception::

      >>> with batch:
      ...     batch.put(entity1)
      ...     batch.put(entity2)
      ...     batch.delete(key3)

    By default, no updates will be sent if the block exits with an error::

      >>> with batch:
      ...     do_some_work(batch)
      ...     raise Exception()  # rolls back

    :type client: :class:`gcloud.datastore.client.Client`
    :param client: The client used to connect to datastore.
    Nr   é   é   é   c                 C   s"   || _ t ¡ | _g | _| j| _d S ©N)Ú_clientÚ_datastore_pb2ZCommitRequestÚ_commit_requestÚ_partial_key_entitiesÚ_INITIALÚ_status)ÚselfÚclient© r   úW/var/www/html/python-backend/venv/lib/python3.9/site-packages/gcloud/datastore/batch.pyÚ__init__N   s    
zBatch.__init__c                 C   s   | j jS )z0Return the topmost batch / transaction, or None.)r	   Zcurrent_batch©r   r   r   r   ÚcurrentT   s    zBatch.currentc                 C   s   | j jS )z‘Getter for project in which the batch will run.

        :rtype: :class:`str`
        :returns: The project in which the batch will run.
        )r	   Úprojectr   r   r   r   r   X   s    zBatch.projectc                 C   s   | j jS )z•Getter for namespace in which the batch will run.

        :rtype: :class:`str`
        :returns: The namespace in which the batch will run.
        )r	   Ú	namespacer   r   r   r   r   a   s    zBatch.namespacec                 C   s   | j jS )z¾Getter for connection over which the batch will run.

        :rtype: :class:`gcloud.datastore.connection.Connection`
        :returns: The connection over which the batch will run.
        )r	   Ú
connectionr   r   r   r   r   j   s    zBatch.connectionc                 C   s   | j  ¡ }|jS )zùAdds a new mutation for an entity with a partial key.

        :rtype: :class:`gcloud.datastore._generated.entity_pb2.Entity`
        :returns: The newly created entity protobuf that will be
                  updated and sent with a commit.
        )Ú	mutationsÚaddÚinsert©r   Znew_mutationr   r   r   Ú_add_partial_key_entity_pbs   s    
z Batch._add_partial_key_entity_pbc                 C   s   | j  ¡ }|jS )zûAdds a new mutation for an entity with a completed key.

        :rtype: :class:`gcloud.datastore._generated.entity_pb2.Entity`
        :returns: The newly created entity protobuf that will be
                  updated and sent with a commit.
        )r   r   Zupsertr   r   r   r   Ú_add_complete_key_entity_pb}   s    

z!Batch._add_complete_key_entity_pbc                 C   s   | j  ¡ }|jS )zëAdds a new mutation for a key to be deleted.

        :rtype: :class:`gcloud.datastore._generated.entity_pb2.Key`
        :returns: The newly created key protobuf that will be
                  deleted when sent with a commit.
        )r   r   Údeleter   r   r   r   Ú_add_delete_key_pbŠ   s    
zBatch._add_delete_key_pbc                 C   s   | j jS )a.  Getter for the changes accumulated by this batch.

        Every batch is committed with a single commit request containing all
        the work to be done as mutations. Inside a batch, calling :meth:`put`
        with an entity, or :meth:`delete` with a key, builds up the request by
        adding a new mutation. This getter returns the protobuf that has been
        built-up so far.

        :rtype: iterable
        :returns: The list of :class:`._generated.datastore_pb2.Mutation`
                  protobufs to be sent in the commit request.
        )r   r   r   r   r   r   r   ”   s    zBatch.mutationsc                 C   s\   |j du rtdƒ‚| j|j jkr(tdƒ‚|j jrF|  ¡ }| j |¡ n|  ¡ }t||ƒ dS )a@  Remember an entity's state to be saved during :meth:`commit`.

        .. note::
           Any existing properties for the entity will be replaced by those
           currently set on this instance.  Already-stored properties which do
           not correspond to keys set on this instance will be removed from
           the datastore.

        .. note::
           Property values which are "text" ('unicode' in Python2, 'str' in
           Python3) map to 'string_value' in the datastore;  values which are
           "bytes" ('str' in Python2, 'bytes' in Python3) map to 'blob_value'.

        When an entity has a partial key, calling :meth:`commit` sends it as
        an ``insert`` mutation and the key is completed. On return,
        the key for the ``entity`` passed in is updated to match the key ID
        assigned by the server.

        :type entity: :class:`gcloud.datastore.entity.Entity`
        :param entity: the entity to be saved.

        :raises: ValueError if entity has no key assigned, or if the key's
                 ``project`` does not match ours.
        NzEntity must have a keyú&Key must be from same project as batch)	ÚkeyÚ
ValueErrorr   Ú
is_partialr   r   Úappendr   Ú_assign_entity_to_pb)r   ÚentityÚ	entity_pbr   r   r   Úput¤   s    
z	Batch.putc                 C   s<   |j rtdƒ‚| j|jkr"tdƒ‚| ¡ }|  ¡  |¡ dS )a  Remember a key to be deleted during :meth:`commit`.

        :type key: :class:`gcloud.datastore.key.Key`
        :param key: the key to be deleted.

        :raises: ValueError if key is not complete, or if the key's
                 ``project`` does not match ours.
        zKey must be completer!   N)r$   r#   r   Zto_protobufr    ÚCopyFrom)r   r"   Zkey_pbr   r   r   r   Ë   s    	zBatch.deletec                 C   s    | j | jkrtdƒ‚| j| _ dS )aU  Begins a batch.

        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.

        Overridden by :class:`gcloud.datastore.transaction.Transaction`.

        :raises: :class:`ValueError` if the batch has already begun.
        z!Batch already started previously.N)r   r   r#   Ú_IN_PROGRESSr   r   r   r   ÚbeginÝ   s    zBatch.beginc                 C   sN   | j  | j| j| j¡\}}t|| jƒD ]"\}}|jd j}|j	 
|¡|_	q&dS )zFCommits the batch.

        This is called by :meth:`commit`.
        éÿÿÿÿN)r   Úcommitr   r   Ú_idÚzipr   ÚpathÚidr"   Zcompleted_key)r   Ú_Zupdated_keysZ
new_key_pbr'   Znew_idr   r   r   Ú_commitì   s    ÿÿzBatch._commitc                 C   s$   z|   ¡  W | j| _n
| j| _0 dS )zÀCommits the batch.

        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.
        N)r4   Ú	_FINISHEDr   r   r   r   r   r.   ü   s    
zBatch.commitc                 C   s   | j | _dS )z«Rolls back the current batch.

        Marks the batch as aborted (can't be used again).

        Overridden by :class:`gcloud.datastore.transaction.Transaction`.
        N)Ú_ABORTEDr   r   r   r   r   Úrollback  s    zBatch.rollbackc                 C   s   | j  | ¡ |  ¡  | S r   )r	   Z_push_batchr,   r   r   r   r   Ú	__enter__  s    zBatch.__enter__c                 C   s:   z(|d u r|   ¡  n|  ¡  W | j ¡  n| j ¡  0 d S r   )r.   r7   r	   Z
_pop_batch)r   Úexc_typeÚexc_valÚexc_tbr   r   r   Ú__exit__  s
    

zBatch.__exit__)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r/   r   r+   r6   r5   r   r   Úpropertyr   r   r   r   r   r    r   r)   r   r,   r4   r.   r7   r8   r<   r   r   r   r   r      s6   #





'	r   c                 C   s&   t  |¡}|j |j¡ |  |¡ dS )aX  Copy ``entity`` into ``entity_pb``.

    Helper method for ``Batch.put``.

    :type entity_pb: :class:`gcloud.datastore._generated.entity_pb2.Entity`
    :param entity_pb: The entity owned by a mutation.

    :type entity: :class:`gcloud.datastore.entity.Entity`
    :param entity: The entity being updated within the batch / transaction.
    N)r   Zentity_to_protobufr"   r*   )r(   r'   Zbare_entity_pbr   r   r   r&      s    
r&   N)	r@   Zgcloud.datastorer   Zgcloud.datastore._generatedr   r
   Úobjectr   r&   r   r   r   r   Ú<module>   s   	  