3
O6b;/                 @   s   d Z ddlmZ ddlmZ ddlmZ ddlmZm	Z	 ddl
mZmZmZ ddlmZmZmZ ddlmZ G d	d
 d
eZG dd deZdS )z4CommandCursor class to iterate over command results.    )deque)&_convert_raw_document_lists_to_streams)integer_types)_SocketManager_CURSOR_CLOSED_ERRORS)ConnectionFailureInvalidOperationOperationFailure)_CursorAddress_GetMore_RawBatchGetMore)PinnedResponsec               @   s   e Zd ZdZeZd/ddZdd Zd0d	d
Zdd Z	dd Z
dd Zdd Zedd Zdd Zdd Zd1d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 )2CommandCursorz)A cursor / iterator over command cursors.r   NFc	       	      C   s   d| _ || _|d | _t|d | _|jd| _|| _|| _|| _	|| _
|| _| jdk| _| jrj| jd d|kr~|d | _n|j| _| j| t|t r|dk	rtddS )	zSCreate a new command cursor.

        The parameter 'retrieved' is unused.
        Nid
firstBatchpostBatchResumeTokenr   Tnsz,max_await_time_ms must be an integer or None)_CommandCursor__sock_mgr_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__nsZ	full_name
batch_size
isinstancer   	TypeError)	self
collectioncursor_infoaddress	retrievedr!   max_await_time_mssessionexplicit_session r,   U/var/www/html/sandeepIITI/myenv/lib/python3.6/site-packages/pymongo/command_cursor.py__init__#   s(    


zCommandCursor.__init__c             C   s   | j   d S )N)_CommandCursor__die)r$   r,   r,   r-   __del__C   s    zCommandCursor.__del__c             C   sl   | j }d| _ | jr.| r.| j}t| j| j}nd}d}| jjjj|||| j	| j
| j | jsbd| _
d| _	dS )zCloses this cursor.
        Tr   N)r   r   r
   r   r    r   databaseclientZ_cleanup_cursorr   r   r   )r$   synchronousZalready_killed	cursor_idr'   r,   r,   r-   Z__dieF   s$    
zCommandCursor.__diec             C   s&   | j r"| j r"| j j|d d | _ d S )N)lock)r   r   Z_end_session)r$   r3   r,   r,   r-   Z__end_session^   s    zCommandCursor.__end_sessionc             C   s   | j d dS )z-Explicitly close / kill this cursor.
        TN)r/   )r$   r,   r,   r-   closec   s    zCommandCursor.closec             C   s8   t |tstd|dk r"td|dkr.dp0|| _| 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!   h   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_next   s    zCommandCursor._has_nextc             C   s   | 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             C   sP   | j jj}|j| jsd S | jsL|j  t|d}| jdkrF|j	  n|| _d S )NFr   )
r   r1   r2   Z_should_pin_cursorr   r   Z
pin_cursorr   r   r6   )r$   Z	sock_infor2   Zsock_mgrr,   r,   r-   _maybe_pin_connection   s    



z#CommandCursor._maybe_pin_connectionc             C   s$  | j jj}y|j|| j| jd}W nz tk
r^ } z |jtkrDd| _	| j
   W Y dd}~X n@ tk
r   d| _	| j
   Y n tk
r   | j
   Y nX t|tr| jst|j|j| _|jr|jd d }|d }|jd| _|d | _n|j}|jj| _| jdkr| j
  t|| _dS )	z8Send a getmore message and handle the response.
        )r'   TNr   cursorZ	nextBatchr   r   )r   r1   r2   Z_run_operation_unpack_responser   r	   coder   r   r6   r   	Exceptionr"   r   r   r   Zsocket_infoZmore_to_comeZfrom_commandZdocsr   r   r   datar4   r   r   )r$   Z	operationr2   responseexcr>   Z	documentsr,   r,   r-   Z__send_message   s<    




zCommandCursor.__send_messagec             C   s   |j ||||S )N)Zunpack_response)r$   rC   r4   codec_optionsuser_fieldslegacy_responser,   r,   r-   r?      s    
zCommandCursor._unpack_responsec             C   s   t | js| jrt | jS | jrz| jjdd\}}| jj| j}| j	| j
||| j| j| jj|| j| jjj| j| jd n
| j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.
        .r7   FT)r:   r   r   r   r    splitr   Z_read_preference_forr*   _CommandCursor__send_message_getmore_classr   rE   r   r1   r2   r   r   r/   )r$   ZdbnameZcollnameZ	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   s   | j S )zReturns the id of the cursor.)r   )r$   r,   r,   r-   r4      s    zCommandCursor.cursor_idc             C   s   | j S )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   | S )Nr,   )r$   r,   r,   r-   __iter__  s    zCommandCursor.__iter__c             C   s*   x | j r | jd}|dk	r|S qW tdS )zAdvance the cursor.TN)rN   	_try_nextStopIteration)r$   docr,   r,   r-   next  s
    
zCommandCursor.nextc             C   sL   t | j r | j r |r | j  t | jrD| j}|jj| jj |S dS dS )z<Advance the cursor blocking for at most one getMore command.N)r:   r   r   rL   r   r1   Z_fix_outgoingpopleft)r$   Zget_more_allowedZcollr,   r,   r-   rP     s    
zCommandCursor._try_nextc             C   s   | S )Nr,   )r$   r,   r,   r-   	__enter__$  s    zCommandCursor.__enter__c             C   s   | j   d S )N)r6   )r$   exc_typeexc_valexc_tbr,   r,   r-   __exit__'  s    zCommandCursor.__exit__)r   r   NNF)F)NF)__name__
__module____qualname____doc__r   rK   r.   r0   r/   r   r6   r!   r;   propertyr<   r=   rJ   r?   rL   rN   r4   r'   r*   rO   rS   __next__rP   rU   rY   r,   r,   r,   r-   r      s4     

*
	

r   c                   s4   e Zd ZeZd
 fdd	ZdddZdd	 Z  ZS )RawBatchCommandCursorr   NFc	       	   	      s2   |j d sttt| j|||||||| dS )aL  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.

        .. seealso:: The MongoDB documentation on `cursors <https://dochub.mongodb.org/core/cursors>`_.
        r   N)r   AssertionErrorsuperr`   r.   )	r$   r%   r&   r'   r(   r!   r)   r*   r+   )	__class__r,   r-   r.   .  s    

zRawBatchCommandCursor.__init__c             C   s"   |j ||d}|st|d  |S )N)rF   r   )raw_responser   )r$   rC   r4   rE   rF   rG   rd   r,   r,   r-   r?   >  s
    
z&RawBatchCommandCursor._unpack_responsec             C   s   t dd S )Nz)Cannot call __getitem__ on RawBatchCursor)r   )r$   indexr,   r,   r-   __getitem__H  s    z!RawBatchCommandCursor.__getitem__)r   r   NNF)NF)	rZ   r[   r\   r   rK   r.   r?   rf   __classcell__r,   r,   )rc   r-   r`   +  s     
	r`   N)r]   collectionsr   Zbsonr   Zbson.py3compatr   Zpymongo.cursorr   r   Zpymongo.errorsr   r   r	   Zpymongo.messager
   r   r   Zpymongo.responser   objectr   r`   r,   r,   r,   r-   <module>   s     