o
    sDiB                     @  s$  d Z ddlmZ ddlmZ ddlmZmZmZm	Z	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 ddlmZ dd	lmZmZmZ dd
lmZmZmZm Z m!Z! ddl"m#Z# ddl$m%Z%m&Z&m'Z' erzddl(m)Z) ddl*m+Z+ ddl,m-Z- dZ.G dd de	e' Z/G dd de/e' Z0dS )z4CommandCursor class to iterate over command results.    )annotations)deque)	TYPE_CHECKINGAnyAsyncIteratorGenericMappingNoReturnOptionalSequenceUnion)CodecOptions&_convert_raw_document_lists_to_streams)_csot)_ConnectionManager)_CURSOR_CLOSED_ERRORS)ConnectionFailureInvalidOperationOperationFailure)_CursorAddress_GetMore_OpMsg_OpReply_RawBatchGetMore)PinnedResponse)_Address_DocumentOut_DocumentType)AsyncClientSession)AsyncCollection)AsyncConnectionFc                   @  sP  e Zd ZdZeZ				dgdhddZdiddZdjddZdkddZ	e
dldd Zdmd#d$Z		%dndod.d/Ze
dkd0d1Ze
dpd2d3Ze
dqd4d5Ze
drd6d7Zdsd9d:Zdid;d<Zdid=d>Zdid?d@ZdidAdBZdtdEdFZdpdGdHZdudJdKZdvdMdNZdvdOdPZdwdSdTZdxdydXdYZdzdZd[Zd{d\d]Zd|dadbZ e!j"dxd}dedfZ#dS )~AsyncCommandCursorz7An asynchronous cursor / iterator over command cursors.r   N
collectionAsyncCollection[_DocumentType]cursor_infoMapping[str, Any]addressOptional[_Address]
batch_sizeintmax_await_time_msOptional[int]sessionOptional[AsyncClientSession]commentr   returnNonec                 C  s   d| _ || _|d | _t|d | _|d| _|| _|| _|| _	| jj
jjj| _|| _| jdur5d| j_| jdk| _|| _| jrE|   d|v rO|d | _n|j| _| | t|tsj|durltdt| dS dS )	zCreate a new command cursor.Nid
firstBatchpostBatchResumeTokenTr   nsz2max_await_time_ms must be an integer or None, not )	_sock_mgr_collection_idr   _dataget_postbatchresumetoken_address_batch_size_max_await_time_msdatabaseclientoptionstimeout_timeout_session_attached_to_cursor_killed_comment_end_session_ns	full_namer(   
isinstancer)   	TypeErrortypeselfr"   r$   r&   r(   r*   r,   r.    rO   a/home/alumno/antzosa8961/venv/lib/python3.10/site-packages/pymongo/asynchronous/command_cursor.py__init__;   s6   


zAsyncCommandCursor.__init__c                 C  s   |    d S N)_die_no_lockrN   rO   rO   rP   __del__e   s   zAsyncCommandCursor.__del__!AsyncCommandCursor[_DocumentType]c                 C  sB   t |tstdt| |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``.

        :param batch_size: The size of each batch of results requested.
        z#batch_size must be an integer, not r   zbatch_size must be >= 0      )rJ   r)   rK   rL   
ValueErrorr<   )rN   r(   rO   rO   rP   r(   h   s   
zAsyncCommandCursor.batch_sizeboolc                 C  s   t | jdkS )z^Returns `True` if the cursor has documents remaining from the
        previous batch.
        r   )lenr8   rT   rO   rO   rP   	_has_next   s   zAsyncCommandCursor._has_nextOptional[Mapping[str, Any]]c                 C     | j S )zlRetrieve the postBatchResumeToken from the response to a
        changeStream aggregate or getMore.
        )r:   rT   rO   rO   rP   _post_batch_resume_token   s   z+AsyncCommandCursor._post_batch_resume_tokenconnr    c                   s^   | j jj}|| jsd S | js-|  t|d}| jdkr(|	 I d H  d S || _d S d S )NFr   )
r6   r>   r?   _should_pin_cursorrC   r5   
pin_cursorr   r7   close)rN   r`   r?   conn_mgrrO   rO   rP   _maybe_pin_connection   s   



z(AsyncCommandCursor._maybe_pin_connectionFresponseUnion[_OpReply, _OpMsg]	cursor_idcodec_optionsCodecOptions[Mapping[str, Any]]user_fieldslegacy_responseSequence[_DocumentOut]c                 C  s   | ||||S rR   )unpack_response)rN   rf   rh   ri   rk   rl   rO   rO   rP   _unpack_response   s   z#AsyncCommandCursor._unpack_responsec                 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::

            async 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.
        )rZ   r[   r8   rE   rT   rO   rO   rP   alive   s   zAsyncCommandCursor.alivec                 C  r^   )zReturns the id of the cursor.)r7   rT   rO   rO   rP   rh      s   zAsyncCommandCursor.cursor_idc                 C  r^   )zUThe (host, port) of the server used, or None.

        .. versionadded:: 3.0
        )r;   rT   rO   rO   rP   r&      s   zAsyncCommandCursor.addressc                 C  s   | j r
| j js
| j S dS )zThe cursor's :class:`~pymongo.asynchronous.client_session.AsyncClientSession`, or None.

        .. versionadded:: 3.6
        N)rC   	_implicitrT   rO   rO   rP   r,      s   zAsyncCommandCursor.session$tuple[int, Optional[_CursorAddress]]c                 C  sP   | j }d| _ | jr |s | j}| jd usJ t| j| j}||fS d}d }||fS )NTr   )rE   r7   r;   r   rH   )rN   already_killedrh   r&   rO   rO   rP   _prepare_to_die   s   
z"AsyncCommandCursor._prepare_to_diec                 C  sL   |   \}}| jjj||| j| j | jr!| jjr!d| j_d| _d| _dS )z,Closes this cursor without acquiring a lock.FN)	rt   r6   r>   r?   _cleanup_cursor_no_lockr5   rC   rq   rD   rN   rh   r&   rO   rO   rP   rS      s   

zAsyncCommandCursor._die_no_lockc                   sT   |   \}}| jjj||| j| jI dH  | jr%| jjr%d| j_d| _d| _dS )zCloses this cursor.NF)	rt   r6   r>   r?   _cleanup_cursor_lockr5   rC   rq   rD   rv   rO   rO   rP   	_die_lock   s   


zAsyncCommandCursor._die_lockc                 C  s2   | j r| j jrd| j _| j   d | _ d S d S d S NF)rC   rq   rD   _end_implicit_sessionrT   rO   rO   rP   rG      s
   

zAsyncCommandCursor._end_sessionc                   s   |   I dH  dS )z$Explicitly close / kill this cursor.N)rx   rT   rO   rO   rP   rc      s   zAsyncCommandCursor.close	operationr   c              
     sL  | j jj}z|j|| j| jdI dH }W nC ty9 } z|jtv r%d| _	|j
r-|    |  I dH   d}~w tyJ   d| _	|  I dH    tyX   |  I dH   w t|tri| jsit|j|j| _|jr|jd d }|d }|d| _|d | _n|j}t|jtsJ |jj| _| jdkr|  I dH  t|| _dS )	z/Send a getmore message and handle the response.)r&   NTr   cursor	nextBatchr3   r1   )r6   r>   r?   _run_operationro   r;   r   coder   rE   rA   rS   rc   r   	ExceptionrJ   r   r5   r   r`   more_to_comefrom_commanddocsr9   r:   r7   datar   rh   r   r8   )rN   r{   r?   rf   excr|   	documentsrO   rO   rP   _send_message   sJ   





z AsyncCommandCursor._send_messagec                   s   t | js	| jrt | jS | jrC| jdd\}}| j| j}| 	| 
||| j| j| jj|| j| jjj| j| jd| jI dH  n|  I dH  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.
        .rW   FN)r[   r8   rE   r7   rH   splitr6   _read_preference_forr,   r   _getmore_classr<   ri   rC   r>   r?   r=   r5   rF   rx   )rN   dbnamecollname	read_prefrO   rO   rP   _refresh(  s0   

zAsyncCommandCursor._refreshAsyncIterator[_DocumentType]c                 C  s   | S rR   rO   rT   rO   rO   rP   	__aiter__J  s   zAsyncCommandCursor.__aiter__r   c                   s.   | j r| dI dH }|dur|S | j st)zAdvance the cursor.TN)rp   	_try_nextStopAsyncIteration)rN   docrO   rO   rP   nextM  s   zAsyncCommandCursor.nextc                   s   |   I d H S rR   )r   rT   rO   rO   rP   	__anext__W  s   zAsyncCommandCursor.__anext__get_more_allowedOptional[_DocumentType]c                   s<   t | js| js|r|  I dH  t | jr| j S dS )z<Advance the cursor blocking for at most one getMore command.N)r[   r8   rE   r   popleft)rN   r   rO   rO   rP   r   Z  s   

zAsyncCommandCursor._try_nextresultlisttotalc                   s~   t | js| js|  I dH  t | jr=|du r&|| j | j  dS ttt | j|D ]
}|| j	  q0dS dS )z4Get all or some available documents from the cursor.NTF)
r[   r8   rE   r   extendclearrangeminappendr   )rN   r   r   _rO   rO   rP   _next_batchc  s   

zAsyncCommandCursor._next_batchc                   s   | j ddI dH S )ar  Advance the cursor without blocking indefinitely.

        This method returns the next document without waiting
        indefinitely for data.

        If no document is cached locally then this method runs a single
        getMore command. If the getMore yields any documents, the next
        document is returned, otherwise, if the getMore returns no documents
        (because there is no additional data) then ``None`` is returned.

        :return: The next document or ``None`` when no document is available
          after running a single getMore or when the cursor is closed.

        .. versionadded:: 4.5
        T)r   N)r   rT   rO   rO   rP   try_nextr  s   zAsyncCommandCursor.try_nextc                   s   | S rR   rO   rT   rO   rO   rP   
__aenter__  s   zAsyncCommandCursor.__aenter__exc_typeexc_valexc_tbc                   s   |   I d H  d S rR   )rc   )rN   r   r   r   rO   rO   rP   	__aexit__  s   zAsyncCommandCursor.__aexit__lengthlist[_DocumentType]c                   sn   g }|}t |tr|dk rtd| jr5| ||I dH s!	 |S |dur2|t| }|dkr2	 |S | js|S )a}  Converts the contents of this cursor to a list more efficiently than ``[doc async for doc in cursor]``.

        To use::

          >>> await cursor.to_list()

        Or, so read at most n items from the cursor::

          >>> await cursor.to_list(n)

        If the cursor is empty or has no more results, an empty list will be returned.

        .. versionadded:: 4.9
        rW   z'to_list() length must be greater than 0Nr   )rJ   r)   rY   rp   r   r[   )rN   r   res	remainingrO   rO   rP   to_list  s    zAsyncCommandCursor.to_listr   NNNr"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r   r/   r0   )r/   r0   )r(   r)   r/   rV   )r/   rZ   )r/   r]   )r`   r    r/   r0   ry   )rf   rg   rh   r+   ri   rj   rk   r]   rl   rZ   r/   rm   )r/   r)   )r/   r'   )r/   r-   )r/   rr   )r{   r   r/   r0   )r/   r   )r/   r   )r   rZ   r/   r   rR   )r   r   r   r+   r/   rZ   )r/   r   )r/   rV   )r   r   r   r   r   r   r/   r0   )r   r+   r/   r   )$__name__
__module____qualname____doc__r   r   rQ   rU   r(   r\   propertyr_   re   ro   rp   rh   r&   r,   rt   rS   rx   rG   rc   r   r   r   r   r   r   r   r   r   r   r   applyr   rO   rO   rO   rP   r!   6   sT    
*




	





,
"



	


r!   c                      sF   e Zd ZeZ				d&d' fddZ		d(d)d d!Zd*d$d%Z  ZS )+AsyncRawBatchCommandCursorr   Nr"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r   r/   r0   c              	     s*   | drJ 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.asynchronous.collection.AsyncCollection.aggregate_raw_batches`
        instead.

        .. seealso:: The MongoDB documentation on `cursors <https://dochub.mongodb.org/core/cursors>`_.
        r2   N)r9   superrQ   rM   	__class__rO   rP   rQ     s   z#AsyncRawBatchCommandCursor.__init__Frf   rg   rh   ri   CodecOptions[dict[str, Any]]rk   r]   rl   rZ   list[Mapping[str, Any]]c                 C  s"   |j ||d}|st|d  |S )N)rk   r   )raw_responser   )rN   rf   rh   ri   rk   rl   r   rO   rO   rP   ro     s   z+AsyncRawBatchCommandCursor._unpack_responseindexr	   c                 C  s   t d)Nz5Cannot call __getitem__ on AsyncRawBatchCommandCursor)r   )rN   r   rO   rO   rP   __getitem__  s   z&AsyncRawBatchCommandCursor.__getitem__r   r   ry   )rf   rg   rh   r+   ri   r   rk   r]   rl   rZ   r/   r   )r   r)   r/   r	   )	r   r   r   r   r   rQ   ro   r   __classcell__rO   rO   r   rP   r     s    "r   N)1r   
__future__r   collectionsr   typingr   r   r   r   r   r	   r
   r   r   bsonr   r   pymongor   pymongo.asynchronous.cursorr   pymongo.cursor_sharedr   pymongo.errorsr   r   r   pymongo.messager   r   r   r   r   pymongo.responser   pymongo.typingsr   r   r   #pymongo.asynchronous.client_sessionr   pymongo.asynchronous.collectionr   pymongo.asynchronous.poolr    _IS_SYNCr!   r   rO   rO   rO   rP   <module>   s*   ,  t