o
    Åîï]é*  ã                   @   sl   d Z ddlmZ ddlmZ ddlmZmZmZm	Z	 ddl
mZmZmZ G dd„ deƒZG dd	„ d	eƒZd
S )z4CommandCursor class to iterate over command results.é    )Údeque)Úinteger_types)ÚConnectionFailureÚInvalidOperationÚNotMasterErrorÚOperationFailure)Ú_CursorAddressÚ_GetMoreÚ_RawBatchGetMorec                   @   sÚ   e Zd ZdZeZ			d-dd„Zdd„ Zd.d	d
„Zdd„ Z	dd„ Z
dd„ Zdd„ Zedd„ ƒZdd„ Z	d/dd„Zdd„ Zedd„ ƒZedd„ ƒZedd „ ƒZed!d"„ ƒZd#d$„ Zd%d&„ ZeZd'd(„ Zd)d*„ Zd+d,„ ZdS )0ÚCommandCursorz)A cursor / iterator over command cursors.r   NFc	           	      C   s¬   || _ |d | _t|d ƒ| _| d¡| _|| _|| _|| _|| _	|| _
| jdk| _| jr2|  d¡ d|v r<|d | _n|j| _|  |¡ t|tƒsR|durTtdƒ‚dS dS )	zSCreate a new command cursor.

        The parameter 'retrieved' is unused.
        ÚidÚ
firstBatchÚpostBatchResumeTokenr   TÚnsNz,max_await_time_ms must be an integer or None)Ú_CommandCursor__collectionÚ_CommandCursor__idr   Ú_CommandCursor__dataÚgetÚ$_CommandCursor__postbatchresumetokenÚ_CommandCursor__addressÚ_CommandCursor__batch_sizeÚ!_CommandCursor__max_await_time_msÚ_CommandCursor__sessionÚ _CommandCursor__explicit_sessionÚ_CommandCursor__killedÚ_CommandCursor__end_sessionÚ_CommandCursor__nsÚ	full_nameÚ
batch_sizeÚ
isinstancer   Ú	TypeError©	ÚselfÚ
collectionÚcursor_infoÚaddressÚ	retrievedr   Úmax_await_time_msÚsessionÚexplicit_session© r*   úH/var/www/html/env/lib/python3.10/site-packages/pymongo/command_cursor.pyÚ__init__!   s*   



þzCommandCursor.__init__c                 C   s    | j r| js|  ¡  d S d S d S ©N)r   r   Ú_CommandCursor__die©r"   r*   r*   r+   Ú__del__@   s   ÿzCommandCursor.__del__c                 C   sh   | j }d| _ | jr-|s-t| j| jjƒ}|r#| jjjj| j|| j	d� n
| jjj 
| j|¡ |  |¡ dS )zCloses this cursor.
        T)r(   N)r   r   r   r   r   r   ÚdatabaseÚclientÚ_close_cursor_nowr   Ú_close_cursorr   )r"   ÚsynchronousÚalready_killedr%   r*   r*   r+   Ú__dieD   s   

ÿ

ÿ
ÿzCommandCursor.__diec                 C   s,   | j r| js| j j|d� d | _ d S d S d S )N)Úlock)r   r   Ú_end_session)r"   r5   r*   r*   r+   Ú__end_sessionU   s   
þzCommandCursor.__end_sessionc                 C   s   |   d¡ dS )z-Explicitly close / kill this cursor.
        TN)r.   r/   r*   r*   r+   ÚcloseZ   ó   zCommandCursor.closec                 C   s8   t |tƒs	tdƒ‚|dk rtdƒ‚|dkrdp|| _| S )aÅ  Limits the number of documents returned in one batch. Each batch
        requires a round trip to the server. It can be adjusted to optimize
        performance and limit data transfer.

        .. note:: batch_size can not override MongoDB's internal limits on the
           amount of data it will return to the client in a single batch (i.e
           if you set batch size to 1,000,000,000, MongoDB will currently only
           return 4-16MB of results per batch).

        Raises :exc:`TypeError` if `batch_size` is not an integer.
        Raises :exc:`ValueError` if `batch_size` is less than ``0``.

        :Parameters:
          - `batch_size`: The size of each batch of results requested.
        zbatch_size must be an integerr   zbatch_size must be >= 0é   é   )r   r   r    Ú
ValueErrorr   )r"   r   r*   r*   r+   r   _   s   
zCommandCursor.batch_sizec                 C   s   t | jƒdkS )zUReturns `True` if the cursor has documents remaining from the
        previous batch.r   )Úlenr   r/   r*   r*   r+   Ú	_has_nextw   r<   zCommandCursor._has_nextc                 C   ó   | j S )zcRetrieve the postBatchResumeToken from the response to a
        changeStream aggregate or getMore.)r   r/   r*   r*   r+   Ú_post_batch_resume_token|   s   z&CommandCursor._post_batch_resume_tokenc           
         sð   ‡ fdd„}ˆ j jj}z|j|ˆ jˆ jd�}W n* ty"   |ƒ  ‚  ty,   |ƒ  ‚  ty6   |ƒ  ‚  t	yA   ˆ  
¡  ‚ w |j}|j}|j}|rc|d d }|d }	| d¡ˆ _|d ˆ _n|}	|jˆ _ˆ jdkrq|ƒ  t|	ƒˆ _d	S )
z8Send a getmore message and handle the response.
        c                      s   dˆ _ ˆ  d¡ d S )NT)r   r   r*   r/   r*   r+   Úkill…   s   z*CommandCursor.__send_message.<locals>.kill)r%   r   ÚcursorÚ	nextBatchr   r   N)r   r1   r2   Ú_run_operation_with_responseÚ_unpack_responser   r   r   r   Ú	Exceptionr.   Úfrom_commandÚdataÚdocsr   r   r   Ú	cursor_idr   r   )
r"   Ú	operationrD   r2   ÚresponserJ   ÚreplyrL   rE   Ú	documentsr*   r/   r+   Ú__send_message‚   s@   


ÿý
zCommandCursor.__send_messagec                 C   s   |  ||||¡S r-   )Úunpack_response©r"   rO   rM   Úcodec_optionsÚuser_fieldsÚlegacy_responser*   r*   r+   rH   ²   s   
ÿzCommandCursor._unpack_responsec                 C   s�   t | jƒs| jrt | jƒS | jr;| j dd¡\}}| j | j¡}|  	|  
||| j| j| jj|| j| jjj| jd¡
¡ nd| _|  d¡ t | jƒS )a  Refreshes the cursor with more data from the server.

        Returns the length of self.__data after refresh. Will exit early if
        self.__data is already non-empty. Raises OperationFailure when the
        cursor cannot be refreshed due to an error on the query.
        Ú.r=   FT)r@   r   r   r   r   Úsplitr   Ú_read_preference_forr(   Ú_CommandCursor__send_messageÚ_getmore_classr   rU   r   r1   r2   r   r   )r"   ÚdbnameÚcollnameÚ	read_prefr*   r*   r+   Ú_refresh·   s*   
÷ÿ

zCommandCursor._refreshc                 C   s   t t| jƒp	| j ƒS )a  Does this cursor have the potential to return more data?

        Even if :attr:`alive` is ``True``, :meth:`next` can raise
        :exc:`StopIteration`. Best to use a for loop::

            for doc in collection.aggregate(pipeline):
                print(doc)

        .. note:: :attr:`alive` can be True while iterating a cursor from
          a failed server. In this case :attr:`alive` will return False after
          :meth:`next` fails to retrieve the next batch of results from the
          server.
        )Úboolr@   r   r   r/   r*   r*   r+   ÚaliveÕ   s   zCommandCursor.alivec                 C   rB   )zReturns the id of the cursor.)r   r/   r*   r*   r+   rM   æ   s   zCommandCursor.cursor_idc                 C   rB   )zUThe (host, port) of the server used, or None.

        .. versionadded:: 3.0
        )r   r/   r*   r*   r+   r%   ë   s   zCommandCursor.addressc                 C   s   | j r| jS dS )zmThe cursor's :class:`~pymongo.client_session.ClientSession`, or None.

        .. versionadded:: 3.6
        N)r   r   r/   r*   r*   r+   r(   ó   s   ÿzCommandCursor.sessionc                 C   ó   | S r-   r*   r/   r*   r*   r+   Ú__iter__ü   ó   zCommandCursor.__iter__c                 C   s&   | j r|  d¡}|dur|S | j st‚)zAdvance the cursor.TN)rb   Ú	_try_nextÚStopIteration)r"   Údocr*   r*   r+   Únextÿ   s   
ýzCommandCursor.nextc                 C   sD   t | jƒs| js|r|  ¡  t | jƒr | j}|j | j ¡ |¡S dS )z<Advance the cursor blocking for at most one getMore command.N)r@   r   r   r`   r   r1   Ú_fix_outgoingÚpopleft)r"   Úget_more_allowedÚcollr*   r*   r+   rf     s   
zCommandCursor._try_nextc                 C   rc   r-   r*   r/   r*   r*   r+   Ú	__enter__  re   zCommandCursor.__enter__c                 C   s   |   ¡  d S r-   )r;   )r"   Úexc_typeÚexc_valÚexc_tbr*   r*   r+   Ú__exit__  s   zCommandCursor.__exit__©r   r   NNF)F©NF)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r	   r\   r,   r0   r.   r   r;   r   rA   ÚpropertyrC   r[   rH   r`   rb   rM   r%   r(   rd   ri   Ú__next__rf   rn   rr   r*   r*   r*   r+   r      sB    
þ

1
ÿ





r   c                       s<   e Zd ZeZ			d
‡ fdd„	Z	ddd„Zdd	„ Z‡  ZS )ÚRawBatchCommandCursorr   NFc	           	   
      s0   |  d¡rJ ‚tt| ƒ ||||||||¡ dS )a  Create a new cursor / iterator over raw batches of BSON data.

        Should not be called directly by application developers -
        see :meth:`~pymongo.collection.Collection.aggregate_raw_batches`
        instead.

        .. mongodoc:: cursors
        r   N)r   Úsuperr{   r,   r!   ©Ú	__class__r*   r+   r,     s
   

þzRawBatchCommandCursor.__init__c                 C   s
   |  |¡S r-   )Úraw_responserT   r*   r*   r+   rH   /  s   
z&RawBatchCommandCursor._unpack_responsec                 C   s   t dƒ‚)Nz)Cannot call __getitem__ on RawBatchCursor)r   )r"   Úindexr*   r*   r+   Ú__getitem__3  s   z!RawBatchCommandCursor.__getitem__rs   rt   )	ru   rv   rw   r
   r\   r,   rH   r�   Ú__classcell__r*   r*   r}   r+   r{     s    þ
ÿr{   N)rx   Úcollectionsr   Úbson.py3compatr   Úpymongo.errorsr   r   r   r   Úpymongo.messager   r	   r
   Úobjectr   r{   r*   r*   r*   r+   Ú<module>   s     