U
    ~fh6                     @  sf  d Z ddlmZ ddlZddlmZ ddlmZmZmZm	Z	m
Z
mZ ddlmZ ddlmZmZ ddlmZ dd	lmZmZmZmZmZ dd
lmZmZmZmZ ddlmZm Z  ddl!m"Z" erBddl#m$Z$ ddl%m&Z& ddl'm(Z( ddl)m*Z* ddl+m,Z, ddl-m.Z. ddl/m0Z0m1Z1 ddl2m3Z3 ddl4m5Z5m6Z6 ddl7m8Z8 dZ9ddddiZ:G dd dZ;dS )z2Communicate with one MongoDB server in a topology.    )annotationsN)datetime)TYPE_CHECKINGAnyCallableContextManagerOptionalUnion)_decode_all_selective)NotPrimaryErrorOperationFailure)_check_command_response)_COMMAND_LOGGER_SDAM_LOGGER_CommandStatusMessage
_debug_log_SDAMStatusMessage)_convert_exception_GetMore_OpMsg_Query)PinnedResponseResponse)_handle_reauth)Queue)ReferenceType)ObjectId)_EventListeners)_ServerMode)ServerDescription)MongoClient_MongoClientErrorHandler)Monitor)
ConnectionPool)_DocumentOutTcursor   )
firstBatch	nextBatchc                	   @  s  e Zd Zd8dddddddd	d
dZddddZd9dddddZddddZddddZd:dddddddZe	dddddd d!d"d#d$Z
d;d%d&d'd(d)Zeddd*d+Zejddd,d-d+Zeddd.d/Zd0d1d2d3d4Zd5dd6d7ZdS )<ServerNr   r$   r"   zOptional[ObjectId]zOptional[_EventListeners]zOptional[ReferenceType[Queue]]None)server_descriptionpoolmonitortopology_id	listenerseventsreturnc                 C  sF   || _ || _|| _|| _|dk	o$|j| _|| _d| _| jrB| | _dS )zRepresent one MongoDB server.N)_description_pool_monitor_topology_idZenabled_for_server_publish	_listener_events)selfr,   r-   r.   r/   r0   r1    r;   >/tmp/pip-unpacked-wheel-36gvocj8/pymongo/synchronous/server.py__init__>   s    
zServer.__init__)r2   c                 C  s   | j jjs| j  dS )z[Start monitoring, or restart after a fork.

        Multiple calls have no effect.
        N)r4   optsZload_balancedr5   openr:   r;   r;   r<   r?   R   s    
zServer.open)
service_idr2   c                 C  s   | j | dS )zClear the connection pool.N)r-   reset)r:   rA   r;   r;   r<   rB   Z   s    zServer.resetc                 C  s   | j r@| jdk	st| jdk	s"t| j| jj| jj| jff t	
tjrrtt	| j| jjd | jjd tjd | j  | j  dS )zXClear the connection pool and stop the monitor.

        Reconnect with open().
        Nr   r'   )Z
topologyId
serverHost
serverPortmessage)r7   r8   AssertionErrorr9   putZpublish_server_closedr3   addressr6   r   isEnabledForloggingDEBUGr   r   ZSTOP_SERVERr5   closer4   r@   r;   r;   r<   rL   ^   s$    


zServer.closec                 C  s   | j   dS )zCheck the server's state soon.N)r5   request_checkr@   r;   r;   r<   rM   x   s    zServer.request_checkFzUnion[_Query, _GetMore]r#   boolztuple[dict[str, Any], str])	operationconnapply_timeoutr2   c                 C  sJ   | ||\}}|jjr8|jjjs8|jj|j||j}|| ||fS N)Z
as_commandclient
_encrypterZ_bypass_auto_encryptionZencryptdbcodec_optionsZupdate_command)r:   rO   rP   rQ   cmdrU   r;   r;   r<   operation_to_command|   s      
zServer.operation_to_commandr   z!Callable[..., list[_DocumentOut]]r    r   )rP   rO   read_preferencer0   
unpack_resrS   r2   c                 C  s(  |dk	st |j}t }||}	|jo0|jj}
| |||	\}}|
rNd}n||||	}| 	|\}}}t
tjrtt
|jjtj|tt|||||j|j|jd |jd |jd |rd|kr||d< |dk	st |j||||j|j|jd z|
r
|d}n||| ||}|	r0t}d}nd}d}|||j|j||d	}|	rx|d }|j ||j! t"||j# W n t$k
r\ } zt | }t%|t&t'fr|j(}nt)|}t
tjrtt
|jjtj*||tt|||||j|j|jd |jd |jt%|t'd
 |rJ|dk	s(t |j+|||j,||j|j|j|d  W 5 d}~X Y nX t | }|	rz|d }n\|j,dkr|r|d ni }n<|j|- ddd}|j,dkr||d d< n||d d< t
tjr(tt
|jjtj.||tt|||||j|j|jd |jd |jd |r^|dk	s<t |j/|||j,||j|j|j|d |j}|r|j0r|	r|j01|2 }t3||j|}|4|j!s|j5r|6  t%|t7r|j}
nt8|j5o|j}
|jr|j9|
 t:|| j;j||||	||
d}nt<|| j;j|||	|d}|S )a<  Run a _Query or _GetMore operation and return a Response object.

        This method is used only to run _Query/_GetMore operations from
        cursors.
        Can raise ConnectionFailure, OperationFailure, etc.

        :param conn: A Connection instance.
        :param operation: A _Query or _GetMore object.
        :param read_preference: The read preference to use.
        :param listeners: Instance of _EventListeners or None.
        :param unpack_res: A callable that decodes the wire protocol response.
        :param client: A MongoClient instance.
        Nr   r'   )clientIdrE   commandcommandNamedatabaseName	requestIdoperationIddriverConnectionIdserverConnectionIdrC   rD   	serviceIdz$db)rA   FT)legacy_responseuser_fields)r[   rE   
durationMSfailurer]   r^   r_   r`   ra   rb   rC   rD   rc   ZisServerSideError)rA   Zdatabase_nameexplain)idns)r&   okfindr&   r(   r)   )r[   rE   rf   replyr]   r^   r_   r`   ra   rb   rC   rD   rc   )datarH   rP   duration
request_idfrom_commanddocsmore_to_come)rn   rH   ro   rp   rq   rr   )=rF   Zenabled_for_commandsr   nowZuse_commandZconn_mgrrs   rX   Zget_message_split_messager   rI   rJ   rK   r   Z_topology_settingsr6   r   ZSTARTEDnextiterri   Zserver_connection_idrH   rA   Zpublish_command_startZreceive_messagesend_message_CURSOR_DOC_FIELDSZ	cursor_idrV   rS   Z_process_responsesessionr   Zmax_wire_version	Exception
isinstancer   r   detailsr   ZFAILEDZpublish_command_failurename	namespaceZ	SUCCEEDEDZpublish_command_successrT   ZdecryptZraw_command_responser
   Z_should_pin_cursorZexhaustZ
pin_cursorr   rN   Zupdate_exhaustr   r3   r   )r:   rP   rO   rY   r0   rZ   rS   publishstartZuse_cmdrs   rW   Zdbnrp   rE   rn   Zmax_doc_sizerm   re   rd   rr   firstexcro   rg   resZ	decryptedresponser;   r;   r<   run_operation   sH   

	




	zServer.run_operationz"Optional[_MongoClientErrorHandler]zContextManager[Connection])handlerr2   c                 C  s   | j |S rR   )r-   checkout)r:   r   r;   r;   r<   r   ^  s    zServer.checkoutc                 C  s   | j S rR   )r3   r@   r;   r;   r<   descriptionc  s    zServer.description)r,   r2   c                 C  s   |j | jj kst|| _d S rR   )rH   r3   rF   )r:   r,   r;   r;   r<   r   g  s    c                 C  s   | j S rR   )r4   r@   r;   r;   r<   r-   l  s    zServer.poolz,Union[tuple[int, Any], tuple[int, Any, int]]ztuple[int, Any, int])rE   r2   c                 C  s&   t |dkr|S |\}}||dfS dS )zReturn request_id, data, max_doc_size.

        :param message: (request_id, data, max_doc_size) or (request_id, data)
           r   N)len)r:   rE   rp   rn   r;   r;   r<   ru   p  s    zServer._split_messagestrc                 C  s   d| j j d| jdS )N< >)	__class____name__r3   r@   r;   r;   r<   __repr__~  s    zServer.__repr__)NNN)N)F)N)r   
__module____qualname__r=   r?   rB   rL   rM   rX   r   r   r   propertyr   setterr-   ru   r   r;   r;   r;   r<   r*   =   s.        V r*   )<__doc__
__future__r   rJ   r   typingr   r   r   r   r   r	   Zbsonr
   Zpymongo.errorsr   r   Zpymongo.helpers_sharedr   Zpymongo.loggerr   r   r   r   r   Zpymongo.messager   r   r   r   Zpymongo.responser   r   Zpymongo.synchronous.helpersr   queuer   weakrefr   Zbson.objectidr   Zpymongo.monitoringr   Zpymongo.read_preferencesr   Zpymongo.server_descriptionr   Z pymongo.synchronous.mongo_clientr    r!   Zpymongo.synchronous.monitorr"   Zpymongo.synchronous.poolr#   r$   Zpymongo.typingsr%   Z_IS_SYNCry   r*   r;   r;   r;   r<   <module>   s2    	