U
    ~fh)                     @  s  U d Z ddlmZ ddlZddl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mZmZmZ ddlZddlmZmZmZ ddlmZ ddlmZmZmZmZ dd	lmZ dd
l m!Z! zddl"m#Z# dZ$W n e%k
r   dZ$Y nX ddl&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z. ddl/m0Z0m1Z1 e
rbddl2m3Z3m4Z4m5Z5 ddl6m7Z7 ddl8m9Z9m:Z:m;Z;m<Z<m=Z= dZ>dZ?dZ@dZAdZBdZCdZDdZEdZFdZGdZHdZIdZJeAdeBd eCd!iZKd"d#d$d%d&ZLed'd(ZMd)eNd*< d+d,d-d.ZOd/d0d/d1d2d3ZPd4d5d6d7d8ZQd4d5d6d9d:ZRd;d<d<d5d=d>d?ZSdd@dAdBdCdDZTdEdFdGdHdIdJdKdLdMdNdNdOdPZUdd;d<dQd+d+dRdRdSdTdUdVd5dWdXdYZVdRd;dRdRdZd[d5d\d]d^ZWeXd_jYZZd`Z[d+dadbdcdddedfZ\eXdgjYZ]d+dadcdhdidjZ^eXdkjYZ_eXdljYZ`eXdmjYZad+d<d;dndodpdqdrdsZbd+d<d;dndodbdtdudvdwZcd+d<d;dndodtdqdxdyZde$rDe#jeZddd+d/d;dzdod{dtd|d}d~Zed+d;d+d+d<dTdoddddZfd+d;d+d+d<dTdodbdd	ddZgd+d;d+d+d<dTdoddddZhe$re#jiZhdd+d;d+d+d<dTdod{dd	ddZjeXdjYZkd;d+d+dadddZld;d+d+dbdcdddZmd;d+d+dcdddZne$r8e#joZndd;d+d+d{dcdddZpeAdeBdeCdiZqG dd dZrG dd derZsG dd desZtd;d+d+ddddZudZvd+d<dddoddddddZwd+d<dddodddddZxe$re#jxZxd+d<dddodddddZyd+d<dddodddddZze$r(e#jzZzd;d+d/ddodddddZ{G dd derZ|dZ}daddddd+dddZ~d<ddddoddddddÄZd<ddddodddŜddǄZd<ddddodddŜddʄZd<ddddodddŜdd̄Zd/dddoddd͜ddτZd;d+d/ddodddddфZe$re#jZd;d+d/ddoddddҜddԄZG ddք dփZG dd؄ d؃ZejejejejiZdeNd< G dd܄ d܃ZG ddބ dރZG dd deZG dd deZG dd deZdS )zTools for creating `messages
<https://www.mongodb.com/docs/manual/reference/mongodb-wire-protocol/>`_ to be sent to
MongoDB.

.. note:: This module is for internal use and is generally not needed by
   application developers.
    )annotationsN)BytesIO)	TYPE_CHECKINGAnyCallableIterableMappingMutableMappingNoReturnOptionalUnion)CodecOptions_dict_to_bson_make_c_string)Int64)_RAW_ARRAY_BSON_OPTIONSDEFAULT_RAW_BSON_OPTIONSRawBSONDocument_inflate_bson)HelloCompat)_EventListeners)	_cmessageTF)ConfigurationErrorCursorNotFoundDocumentTooLargeExecutionTimeoutInvalidOperationNotPrimaryErrorOperationFailureProtocolError)ReadPreference_ServerMode)SnappyContextZlibContextZstdContext)ReadConcern)_Address_AgnosticClientSession_AgnosticConnection_AgnosticMongoClient_DocumentOutii   i?                   s            s           s       s   documents     s   updates     s   deletes     	documentsupdatesZdeletes	bulkWrite)insertupdatedeleter3   replace)Zunicode_decode_error_handlerzCodecOptions[Mapping[str, Any]]_UNICODE_REPLACE_CODEC_OPTIONSintreturnc                   C  s   t ttS )z(Generate a pseudo random 32 bit integer.)randomrandint	MIN_INT32	MAX_INT32 r@   r@   3/tmp/pip-unpacked-wheel-36gvocj8/pymongo/message.py_randintt   s    rB   MutableMapping[str, Any]r!   )specread_preferencer;   c                 C  sD   |j }|j}|r@|tjj ks(t|dkr@d| kr8d| i} || d< | S )z-Add $readPreference to spec when appropriate.r+   $query$readPreference)modedocumentr    ZSECONDARY_PREFERREDlen)rD   rE   rH   rI   r@   r@   rA   _maybe_add_read_preferencey   s    rK   	Exceptiondict[str, Any])	exceptionr;   c                 C  s   t | | jjdS )z<Convert an Exception into a failure document for publishing.)errmsgerrtype)str	__class____name__rN   r@   r@   rA   _convert_exception   s    rU   c                 C  s   t | | j| jjdS )zmConvert an Exception into a failure document for publishing,
    for use in client-level bulk write API.
    )rO   coderP   )rQ   rV   rR   rS   rT   r@   r@   rA   _convert_client_bulk_exception   s    rW   rQ   Mapping[str, Any])	operationcommandresultr;   c           	      C  s  | dd}d|d}| d| dd}|r| drN|d	dd
id|d< n6d| dd|d}d|krv|d |d< |g|d< |S | dkrt|d |d< nx| dkrd|krd|d dg|d< nP| ddkr|dkr|d d }|d  d|d  d}d|dg|d< |S )z6Convert a legacy write result to write command format.nr   r+   )okr\   rO   err Zwtimeout@   T)rO   rV   errInfoZwriteConcernErrorrV      )indexrV   rO   ra   ZwriteErrorsr4   r1   r5   Zupserted)rc   _idZupdatedExistingFr2   urd   q)getrJ   )	rY   rZ   r[   ZaffectedresrO   errorr5   rd   r@   r@   rA   _convert_write_result   s*    



rj   rb             )ZtailableZoplogReplayZnoCursorTimeoutZ	awaitDataZallowPartialResultsfiltersorthintcommentZmaxScan	maxTimeMSmaxminZ	returnKeyZshowRecordIdZsnapshot)rF   z$orderbyz$hintz$commentz$maxScanz
$maxTimeMSz$maxz$minz
$returnKeyz$showRecordIdz$showDiskLocz	$snapshotz1Optional[Union[Mapping[str, Any], Iterable[str]]]Optional[int]r%   Optional[Mapping[str, Any]] Optional[_AgnosticClientSession]Optional[bool])collrD   
projectionskiplimit
batch_sizeoptionsread_concern	collationsessionallow_disk_user;   c                   s   d| i}d|krN| dd | D  d|kr:|d d|krV|d n||d< |rb||d< |rn||d	< |rt||d
< |dk rd|d< |r||d< |jr|	r|	js|j|d< |r||d< |
dk	r|
|d<  r|  fddt D  |S )z!Generate a find command document.findrF   c                 S  s,   g | ]$\}}|t kr t | |fn||fqS r@   )
_MODIFIERS).0keyvalr@   r@   rA   
<listcomp>   s   z%_gen_find_command.<locals>.<listcomp>$explainrG   rn   rz   r{   r|   r   TZsingleBatch	batchSizeZreadConcernr   NZallowDiskUsec                   s    g | ]\}} |@ r|d fqS )Tr@   )r   optr   r~   r@   rA   r     s      )r5   itemspopabslevelin_transactionrI   _OPTIONS)ry   rD   rz   r{   r|   r}   r~   r   r   r   r   cmdr@   r   rA   _gen_find_command   s>    

r   zOptional[Any]r(   )	cursor_idry   r}   max_await_time_msrq   connr;   c                 C  sD   | |d}|r||d< |dk	r&||d< |dk	r@|j dkr@||d< |S )z$Generate a getMore command document.)getMoreZ
collectionr   Nrr   	   rq   )max_wire_version)r   ry   r}   r   rq   r   r   r@   r@   rA   _gen_get_more_command  s    	
r   z<iiiiiiB   bytesz.Union[SnappyContext, ZlibContext, ZstdContext]ztuple[int, bytes])rY   datactxr;   c                 C  s>   | |}t }ttt| |dd| t||j}||| fS )zDTakes message data, compresses it, and adds an OP_COMPRESSED header.r   i  )compressrB   _pack_compression_header_COMPRESSION_HEADER_SIZErJ   Zcompressor_id)rY   r   r   
compressed
request_idheaderr@   r@   rA   	_compress"  s    

	r   z<iiii)rY   r   r;   c                 C  s(   t  }tdt| |d| }||| fS )ztTakes message data and adds a message header based on the operation.

    Returns the resultant message string.
    rk   r   )rB   _pack_headerrJ   )rY   r   ridmessager@   r@   rA   __pack_message8  s    r   z<iz<IBz<Bz!Optional[list[Mapping[str, Any]]]r   ztuple[bytes, int, int])flagsrZ   
identifierdocsoptsr;   c                   s   t |d }t| d}t|}d}|r|dk	rtd}	t|}
 fdd|D }t|
tdd |D  d	 }t|}||7 }td
d |D }|||	||
f|}n||g}d|||fS )zGet a OP_MSG message.

    Note: this method handles multiple documents in a type one payload but
    it does not perform batch splitting and the total message size is
    only checked *after* generating the entire message.
    Fr   Nr+   c                   s   g | ]}t |d  qS )F)r   r   docr   r@   rA   r   \  s     z%_op_msg_no_header.<locals>.<listcomp>c                 s  s   | ]}t |V  qd S NrJ   r   r@   r@   rA   	<genexpr>]  s     z$_op_msg_no_header.<locals>.<genexpr>   c                 s  s   | ]}t |V  qd S r   r   r   r@   r@   rA   r   `  s     r-   )	r   _pack_op_msg_flags_typerJ   
_pack_byter   sum	_pack_intrs   join)r   rZ   r   r   r   encodedZ
flags_type
total_sizeZmax_doc_sizeZtype_oneZcstringZencoded_docssizeZencoded_sizer   r@   r   rA   _op_msg_no_headerG  s    
r   ztuple[int, bytes, int, int])r   rZ   r   r   r   r   r;   c           
      C  s2   t | ||||\}}}td||\}	}|	|||fS )zInternal OP_MSG message helper.  )r   r   )
r   rZ   r   r   r   r   msgr   max_bson_sizer   r@   r@   rA   _op_msg_compressedg  s    	r   c           
      C  s0   t | ||||\}}}td|\}}	||	||fS )z*Internal compressed OP_MSG message helper.r   )r   r   )
r   rZ   r   r   r   r   r   r   r   Z
op_messager@   r@   rA   _op_msg_uncompressedu  s    r   zOptional[_ServerMode]z4Union[SnappyContext, ZlibContext, ZstdContext, None])r   rZ   dbnamerE   r   r   r;   c           	   	   C  s   ||d< |dk	r(d|kr(|j r(|j|d< tt|}zt| }||}W n tk
rf   d}d}Y nX z.|rt| |||||W S t| ||||W S |r|||< X dS )zGet a OP_MSG message.$dbNrG   r_   )	rH   rI   nextiter
_FIELD_MAPr   KeyErrorr   r   )	r   rZ   r   rE   r   r   namer   r   r@   r@   rA   _op_msg  s"    	

r   ztuple[bytes, int])r~   collection_namenum_to_skipnum_to_returnqueryfield_selectorr   r;   c           
      C  s`   t |d|}|rt |d|}nd}tt|t|}	dt| t|t|t|||g|	fS )zGet an OP_QUERY message.Fr-   )r   rs   rJ   r   r   bsonr   )
r~   r   r   r   r   r   r   r   Zefsr   r@   r@   rA   _query_impl  s     

r   tuple[int, bytes, int])	r~   r   r   r   r   r   r   r   r;   c                 C  s2   t | ||||||\}}	td||\}
}|
||	fS )z)Internal compressed query message helper.  )r   r   )r~   r   r   r   r   r   r   r   op_queryr   r   r   r@   r@   rA   _query_compressed  s          r   c                 C  s0   t | ||||||\}}td|\}	}
|	|
|fS )zInternal query message helper.r   )r   r   )r~   r   r   r   r   r   r   r   r   r   r   r@   r@   rA   _query_uncompressed  s    
      r   c              	   C  s.   |rt | |||||||S t| ||||||S )zGet a **query** message.)r   r   )r~   r   r   r   r   r   r   r   r@   r@   rA   _query  s(                 r   z<q)r   r   r   r;   c                 C  s    d tt| t|t|gS )zGet an OP_GET_MORE message.r-   )r   _ZERO_32r   r   r   _pack_long_longr   r   r   r@   r@   rA   _get_more_impl  s    r   )r   r   r   r   r;   c                 C  s   t dt| |||S )z+Internal compressed getMore message helper.  )r   r   r   r   r   r   r@   r@   rA   _get_more_compressed  s    r   c                 C  s   t dt| ||S )z Internal getMore message helper.r   )r   r   r   r@   r@   rA   _get_more_uncompressed  s    r   c                 C  s   |rt | |||S t| ||S )zGet a **getMore** message.)r   r   r   r@   r@   rA   	_get_more$  s    r   s
   documents s   updates s   deletes c                	   @  s   e Zd ZdZdZddddddddd	d
dZeddddZeddddZeddddZ	eddddZ
dddddddZdddddddZdS )_BulkWriteContextBasez]Private base class for wrapping around AsyncConnection to use with write splitting functions.)db_namer   op_idr   fieldpublish
start_time	listenersr   r   op_typecodecrQ   r(   r9   r   rw   r   database_namecmd_namer   operation_idr   r   r   r   c	           	      C  s`   || _ || _|| _|| _|j| _|| _t| j | _t	j	
 | _|| _t|j| _|| _|| _d S r   )r   r   r   r   Zenabled_for_commandsr   r   r   r   datetimenowr   r   boolcompression_contextr   r   r   	selfr   r   r   r   r   r   r   r   r@   r@   rA   __init__L  s    z_BulkWriteContextBase.__init__r:   c                 C  s   | j jS )z#A proxy for SockInfo.max_bson_size.)r   r   r   r@   r@   rA   r   d  s    z#_BulkWriteContextBase.max_bson_sizec                 C  s   | j r| jjd S | jjS )z&A proxy for SockInfo.max_message_size.rk   )r   r   max_message_sizer   r@   r@   rA   r   i  s    z&_BulkWriteContextBase.max_message_sizec                 C  s   | j jS )z*A proxy for SockInfo.max_write_batch_size.)r   max_write_batch_sizer   r@   r@   rA   r   q  s    z*_BulkWriteContextBase.max_write_batch_sizec                 C  s   | j S )z:The maximum size of a BSON command before batch splitting.)r   r   r@   r@   rA   max_split_sizev  s    z$_BulkWriteContextBase.max_split_sizer*   zdatetime.timedeltaNone)r   replydurationr;   c                 C  s4   | j j||| j|| jj| jj| j| jj| jd	 dS )z Publish a CommandSucceededEvent.r   N)	r   Zpublish_command_successr   r   addressserver_connection_idr   
service_idr   )r   r   r   r   r@   r@   rA   _succeed{  s    z_BulkWriteContextBase._succeed)r   failurer   r;   c                 C  s4   | j j||| j|| jj| jj| j| jj| jd	 dS )zPublish a CommandFailedEvent.r   N)	r   Zpublish_command_failurer   r   r   r   r   r   r   )r   r   r  r   r@   r@   rA   _fail  s    z_BulkWriteContextBase._failN)rS   
__module____qualname____doc__	__slots__r   propertyr   r   r   r   r  r  r@   r@   r@   rA   r   :  s   r   c                	      s^   e Zd ZdZdZddddddddd	 fd
dZddddddZdddddddZ  ZS )_BulkWriteContextz]A wrapper around AsyncConnection/Connection for use with the collection-level bulk write API.r@   rQ   r(   r9   r   rw   r   r   c	           	   
     s   t  |||||||| d S r   superr   r   rR   r@   rA   r     s    z_BulkWriteContext.__init__rC   list[Mapping[str, Any]]zAtuple[int, Union[bytes, dict[str, Any]], list[Mapping[str, Any]]]r   r   r;   c                 C  s<   | j d }t|| j||| j| \}}}|s2td|||fS )N.$cmdcannot do an empty bulk write)r   _do_batched_op_msgr   r   r   )r   r   r   	namespacer   r   to_sendr@   r@   rA   batch_command  s    
     
z_BulkWriteContext.batch_command)r   r   r   r;   c              	   C  s6   ||| j < | j|| j|| jj| jj| j| jj |S )Publish a CommandStartedEvent.)	r   r   publish_command_startr   r   r   r   r   r   )r   r   r   r   r@   r@   rA   _start  s    
	z_BulkWriteContext._start	rS   r  r  r  r  r   r  r  __classcell__r@   r@   r  rA   r	    s
    r	  c                   @  s4   e Zd ZdZddddddZedd	d
dZdS )_EncryptedBulkWriteContextr@   rC   r  z3tuple[int, dict[str, Any], list[Mapping[str, Any]]]r  c                 C  s`   | j d }t|| j||| j| \}}|s0td|ddd }tt||d  t}d||fS )Nr  r  r/   r   r   )	r   _encode_batched_write_commandr   r   r   rc   r   
memoryviewr   )r   r   r   r  r   r  Z	cmd_startoutgoingr@   r@   rA   r    s    
     z(_EncryptedBulkWriteContext.batch_commandr9   r:   c                 C  s   t S )z Reduce the batch splitting size.)_MAX_SPLIT_SIZE_ENCr   r@   r@   rA   r     s    z)_EncryptedBulkWriteContext.max_split_sizeN)rS   r  r  r  r  r  r   r@   r@   r@   rA   r    s   r  r
   )rY   doc_sizemax_sizer;   c                 C  s,   | dkrt d||f nt | ddS )z-Internal helper for raising DocumentTooLarge.r4   zfBSON document too large (%d bytes) - the connected server supports BSON document sizes up to %d bytes.z command document too largeN)r   )rY   r   r!  r@   r@   rA   _raise_document_too_large  s    	r"  i    r  r   _BytesIOz#tuple[list[Mapping[str, Any]], int])rY   rZ   r   ackr   r   bufr;   c                 C  sr  |j }|j}|j}	|rdnd}
||
 |d |t|d| |d | }|d z|t|   W n tk
r   tddY nX g }d}|D ]}t|d|}t	|}| | }|dko||	k}| o||k}|s|r
t
t |  }t|t	|| ||	kr qF|| || |d	7 }||kr qFq| }|| |t||  ||fS )
zCreate a batched OP_MSG write.r0         r/   F   Unknown commandNr   r+   )r   r   r   writer   tell_OP_MSG_MAPr   r   rJ   listr   keysr"  appendseekr   )rY   rZ   r   r$  r   r   r%  r   r   r   r   size_locationr  idxr   valueZ
doc_lengthnew_message_sizedoc_too_largeZunacked_doc_too_largewrite_oplengthr@   r@   rA   _batched_op_msg_impl  sH    









r7  z%tuple[bytes, list[Mapping[str, Any]]])rY   rZ   r   r$  r   r   r;   c           	      C  s*   t  }t| ||||||\}}| |fS )zOEncode the next batched insert, update, or delete operation
    as OP_MSG.
    )r#  r7  getvalue)	rY   rZ   r   r$  r   r   r%  r  _r@   r@   rA   _encode_batched_op_msgA  s    r:  z*tuple[int, bytes, list[Mapping[str, Any]]]c           
      C  sD   t | |||||\}}|jjdk	s&ttd||jj\}}	||	|fS )z]Create the next batched insert, update, or delete operation
    with OP_MSG, compressed.
    Nr   )r:  r   r   AssertionErrorr   )
rY   rZ   r   r$  r   r   r   r  r   r   r@   r@   rA   _batched_op_msg_compressedV  s    r<  c           
      C  sv   t  }|t |d t| ||||||\}}|d t }	|t|	 |d |t| |	| |fS )z"OP_MSG implementation entry point.         r   r   )r#  r)  _ZERO_64r7  r/  rB   r   r8  )
rY   rZ   r   r$  r   r   r%  r  r6  r   r@   r@   rA   _batched_op_msgh  s    	



r?  )r  rY   rZ   r   r   r   r;   c                 C  sb   |  ddd |d< d|kr2t|d dd}nd}|jjrPt||||||S t||||||S )zRCreate the next batched insert, update, or delete operation
    using OP_MSG.
    .r+   r   r   writeConcernwT)splitr   rg   r   r   r<  r?  )r  rY   rZ   r   r   r   r$  r@   r@   rA   r    s    r  c                      s`   e Zd ZdZdZdddddddd	 fd
dZdddddddZddddddddZ  ZS )_ClientBulkWriteContextzYA wrapper around AsyncConnection/Connection for use with the client-level bulk write API.r@   rQ   r(   r9   r   rw   r   )r   r   r   r   r   r   r   c              
     s   t  ||||||d| d S )Nr   r
  )r   r   r   r   r   r   r   r   r  r@   rA   r     s    
z _ClientBulkWriteContext.__init__rC   #list[tuple[str, Mapping[str, Any]]]	list[str]zZtuple[int, Union[bytes, dict[str, Any]], list[Mapping[str, Any]], list[Mapping[str, Any]]])r   
operations
namespacesr;   c                 C  s2   t |||| j| \}}}}|s&td||||fS )Nr  )_client_do_batched_op_msgr   r   )r   r   rG  rH  r   r   to_send_ops
to_send_nsr@   r@   rA   r    s        z%_ClientBulkWriteContext.batch_commandr  )r   r   op_docsns_docsr;   c              	   C  s<   ||d< ||d< | j || j|| jj| jj| j| jj |S )r  opsZnsInfo)r   r  r   r   r   r   r   r   )r   r   r   rL  rM  r@   r@   rA   r    s    	z_ClientBulkWriteContext._startr  r@   r@   r  rA   rD    s
   rD  i  list[bytes])command_encodedto_send_ops_encodedto_send_ns_encodedr$  r%  r;   c                 C  s   |rdnd}| | | d | |  | d | }| d | d |D ]}| | qT| }| }	|| | t|	|  || | d | }| d | d |D ]}
| |
 q| }	|| | t|	|  |	S )Nr0   r&  r/   r'  s   ops s   nsInfo )r)  r*  r/  r   )rP  rQ  rR  r$  r%  r   r0  Z
op_encodedZresume_locationr6  Z
ns_encodedr@   r@   rA   _client_construct_op_msg  s2    











rS  rE  rF  z<tuple[list[Mapping[str, Any]], list[Mapping[str, Any]], int])rZ   rG  rH  r$  r   r   r%  r;   c           %        s  ddddddd}|j }|j}	|j}
t d|}|sJ|dt||t  dd	d
g} drh|d  dr||d  dr|d  fdd|D }tt|d|}|
t|  }i }g }g }g }g }d}d}d}t	||D ]|\\}}}|}|dkr*|s*tt|d d|}|||| |dkr^d}|s^tt|d d|}|||| d}d}||krd|i}t|}|||< || ||< t|d|} t| }!|rt|d|}"t|"}|s|||!|t  || |! | }#|#|kr|dkrt
||!|t   qh|| ||  ||!7 }|rP|| ||" ||7 }|d7 }||	kr qhqt|||||}$|||$fS )z:Create a batched OP_MSG write for client-level bulk write.rQ   r9   r   )r   r   r|   r;   c                 S  s   ||krt | || d S r   )r"  )r   r   r|   r@   r@   rA   _check_doc_size_limits  s    z;_client_batched_op_msg_impl.<locals>._check_doc_size_limitsFr3   Z
errorsOnlyZorderedZbypassDocumentValidationrq   Zletc                   s   i | ]}| | qS r@   r@   )r   r   rZ   r@   rA   
<dictcomp>2  s      z/_client_batched_op_msg_impl.<locals>.<dictcomp>r   r4   rI   r7   r5   Z
updateModsNnsr+   )r   r   r   r   rJ   _COMMAND_OVERHEADrg   r.  _OP_MSG_OVERHEADzipr"  rS  )%rZ   rG  rH  r$  r   r   r%  rT  r   r   r   rP  Zabridged_keysZcommand_abridgedZcommand_len_abridgedZmax_doc_sequences_bytesZns_inforJ  rK  rQ  rR  Ztotal_ops_lengthZtotal_ns_lengthr1  Zreal_op_typeZop_docr  r   r   Zns_docZ	ns_lengthZnew_ns_indexZop_doc_encodedZ	op_lengthZns_doc_encodedr3  r6  r@   rU  rA   _client_batched_op_msg_impl  s    















    r[  z>tuple[bytes, list[Mapping[str, Any]], list[Mapping[str, Any]]])rZ   rG  rH  r$  r   r   r;   c           
      C  s.   t  }t| ||||||\}}}	| ||fS )zLEncode the next batched client-level bulkWrite
    operation as OP_MSG.
    )r#  r[  r8  )
rZ   rG  rH  r$  r   r   r%  rJ  rK  r9  r@   r@   rA   _client_encode_batched_op_msg  s          
r\  zCtuple[int, bytes, list[Mapping[str, Any]], list[Mapping[str, Any]]]c                 C  sH   t | |||||\}}}|jjdk	s(ttd||jj\}	}
|	|
||fS )zZCreate the next batched client-level bulkWrite operation
    with OP_MSG, compressed.
    Nr   )r\  r   r   r;  r   )rZ   rG  rH  r$  r   r   r   rJ  rK  r   r   r@   r@   rA   !_client_batched_op_msg_compressed  s         
r]  c                 C  sz   t  }|t |d t| ||||||\}}}	|d t }
|t|
 |d |t|	 |
| ||fS )z=OP_MSG implementation entry point for client-level bulkWrite.r=  r   r   )r#  r)  r>  r[  r/  rB   r   r8  )rZ   rG  rH  r$  r   r   r%  rJ  rK  r6  r   r@   r@   rA   _client_batched_op_msg  s$    	

      


r^  )rZ   rG  rH  r   r   r;   c                 C  sV   d| d< d| kr&t | d dd}nd}|jjrDt| |||||S t| |||||S )zOCreate the next batched client-level bulkWrite
    operation using OP_MSG.
    Zadminr   rA  rB  r+   T)r   rg   r   r   r]  r^  )rZ   rG  rH  r   r   r$  r@   r@   rA   rI    s    
rI  c           	      C  s*   t  }t| ||||||\}}| |fS )z:Encode the next batched insert, update, or delete command.)r#  _batched_write_command_implr8  )	r  rY   rZ   r   r   r   r%  r  r9  r@   r@   rA   r    s    	r  )r  rY   rZ   r   r   r   r%  r;   c                 C  s  |j }|j}|t }	|j}
|t || d |t |t |	 }|t
| |dd |  z|t|  W n tk
r   tddY nX |	 d }g }d}|D ]}t|d}t|d|}t||	k}|rtt | }t|t|| |d	ko2|	 t| t| |
k}||k}|sH|rN q|t || |t || || |d	7 }q|t |	 }|| |t|| d	  || |t||  ||fS )
z(Create a batched OP_QUERY write command.utf8r  r,   r(  Nr   r   Fr+   )r   r   rX  r   r)  r   encode_ZERO_8_SKIPLIMr*  r   r/  truncate_OP_MAPr   r   rQ   r   rJ   r,  r   r-  r"  _BSONOBJr.  _ZERO_16r   )r  rY   rZ   r   r   r   r%  r   r   Zmax_cmd_sizer   Zcommand_startZ
list_startr  r1  r   r   r2  r4  r5  Zenough_dataZenough_documentsr6  r@   r@   rA   r_    sV    



&








r_  c                   @  s   e Zd ZdZdZedjZdZ	dddddddZ
d$d
dddddZd	ed	dfd
dddddddZdddddZddddZedddd Zedd d!d"d#Zd	S )%_OpReplyz$A MongoDB OP_REPLY response message.)r   r   number_returnedr1   z<iqiir+   r9   r   c                 C  s    || _ t|| _|| _|| _d S r   )r   r   r   ri  r1   )r   r   r   ri  r1   r@   r@   rA   r   G  s    
z_OpReply.__init__Nru   rv   rO  r   user_fieldsr;   c                 C  s   | j d@ r>|dkrtdd|f }d|dd}t|d|n| j d@ rt| j }|d	d |d
 t	j
rt|d
 |n,|ddkrd}t|d
||d|td|d
 |d|| jr| jgS g S )a  Check the response header from the database, without decoding BSON.

        Check the response for errors and unpack.

        Can raise CursorNotFound, NotPrimaryError, ExecutionTimeout, or
        OperationFailure.

        :param cursor_id: cursor_id we sent to get this response -
            used for raising an informative exception when we get cursor id not
            valid at server response.
        r+   Nz"No cursor id for getMore operationzCursor not found, cursor id: %dr   +   )r]   rO   rV   r,   r]   z$errrV   2   zoperation exceeded time limitzdatabase error: %s)r   r   r   r   ZBSONr1   decode
setdefault
startswithr   ZLEGACY_ERRORr   rg   r   r   )r   r   rk  r   ZerrobjZerror_objectZdefault_msgr@   r@   rA   raw_responseM  s4    



  z_OpReply.raw_responseFr   r   list[dict[str, Any]]r   codec_optionsrk  legacy_responser;   c                 C  s,   |  | |rt| j|S t| j||S )a  Unpack a response from the database and decode the BSON document(s).

        Check the response for errors and unpack, returning a dictionary
        containing the response data.

        Can raise CursorNotFound, NotPrimaryError, ExecutionTimeout, or
        OperationFailure.

        :param cursor_id: cursor_id we sent to get this response -
            used for raising an informative exception when we get cursor id not
            valid at server response
        :param codec_options: an instance of
            :class:`~bson.codec_options.CodecOptions`
        :param user_fields: Response fields that should be decoded
            using the TypeDecoders from codec_options, passed to
            bson._decode_all_selective.
        )rq  r   Z
decode_allr1   _decode_all_selectiver   r   rt  rk  ru  r@   r@   rA   unpack_responsey  s    
z_OpReply.unpack_responserM   rt  r;   c                 C  s"   | j |d}| jdkst|d S )Unpack a command response.rt  r+   r   )rx  ri  r;  )r   rt  r   r@   r@   rA   command_response  s    z_OpReply.command_responser
   r:   c                 C  s   t dS ))Return the bytes of the command response.N)NotImplementedErrorr   r@   r@   rA   raw_command_response  s    z_OpReply.raw_command_responsec                 C  s   dS )+Is the moreToCome bit set on this response?Fr@   r   r@   r@   rA   more_to_come  s    z_OpReply.more_to_comer   r;   c                 C  s,   |  |\}}}}|dd }| ||||S )z%Construct an _OpReply from raw bytes.   N)UNPACK_FROM)clsr   r   r   r9  ri  r1   r@   r@   rA   unpack  s    z_OpReply.unpack)NN)rS   r  r  r  r  structStructunpack_fromr  OP_CODEr   rq  r8   rx  r|  r  r  r  classmethodr  r@   r@   r@   rA   rh  ?  s&      .rh  c                   @  s   e Zd ZdZdZedjZdZ	dZ
dZdZdd	d
ddZdi fddddddZdeddfddddddddZdddddZd	dd d!Zeddd"d#Zed	d d$d%d&ZdS )'_OpMsgz"A MongoDB OP_MSG response message.)r   r   ri  payload_documentz<IBir   r+   r,   i   r9   r   r   r  c                 C  s   || _ || _d S r   r  )r   r   r  r@   r@   rA   r     s    z_OpMsg.__init__Nru   rv   r  rj  c                 C  s   t t| j|t}|gS )zp
        cursor_id is ignored
        user_fields is used to determine which fields must not be decoded
        )r   Z_decode_selectiver   r  r   )r   r   rk  Zinflated_responser@   r@   rA   rq    s    	  z_OpMsg.raw_responseFr   r   rr  rs  c                 C  s   |rt t| j||S )a~  Unpack a OP_MSG command response.

        :param cursor_id: Ignored, for compatibility with _OpReply.
        :param codec_options: an instance of
            :class:`~bson.codec_options.CodecOptions`
        :param user_fields: Response fields that should be decoded
            using the TypeDecoders from codec_options, passed to
            bson._decode_all_selective.
        )r;  r   rv  r  rw  r@   r@   rA   rx    s    z_OpMsg.unpack_responserM   ry  c                 C  s   | j |dd S )rz  r{  r   )rx  )r   rt  r@   r@   rA   r|    s    z_OpMsg.command_responser:   c                 C  s   | j S )r}  )r  r   r@   r@   rA   r    s    z_OpMsg.raw_command_responsec                 C  s   t | j| j@ S )r  )r   r   MORE_TO_COMEr   r@   r@   rA   r    s    z_OpMsg.more_to_comer  c                 C  s   |  |\}}}|dkrL|| j@ r2td|d|| jA rLtd|d|dkrdtd|dt||d kr|td|dd }| ||S )	z#Construct an _OpMsg from raw bytes.r   z+Unsupported OP_MSG flag checksumPresent: 0xxzUnsupported OP_MSG flags: 0xz#Unsupported OP_MSG payload type: 0x   z$Unsupported OP_MSG reply: >1 sectionN)r  CHECKSUM_PRESENTr   r  rJ   )r  r   r   Zfirst_payload_typeZfirst_payload_sizer  r@   r@   rA   r    s    

z_OpMsg.unpack)rS   r  r  r  r  r  r  r  r  r  r  r  EXHAUST_ALLOWEDr   rq  r8   rx  r|  r  r  r  r  r  r@   r@   r@   rA   r    s,   r  z5dict[int, Callable[[bytes], Union[_OpReply, _OpMsg]]]_UNPACK_REPLYc                   @  s   e Zd ZdZdZdZdZdddddddd	ddd
ddddddddZddddZddddZ	dddddZ
dddddZd)ddd!d"d#d$Zd*d	ddd%d&d'd(ZdS )+_QueryzA query operation.)r   dbry   ntoskiprD   fieldsrt  rE   r|   r}   r   r   r   r   clientr   _as_commandexhaustNr9   rQ   rX   rv   r   r!   r%   rw   r)   rx   r   )r   r  ry   r  rD   r  rt  rE   r|   r}   r   r   r   r  r   r  c                 C  sp   || _ || _|| _|| _|| _|| _|| _|| _|| _|	| _	|
| _
|| _|| _|| _|| _d| _d | _|| _d S )Nr   )r   r  ry   r  rD   r  rt  rE   r   r|   r}   r   r   r  r   r   r  r  )r   r   r  ry   r  rD   r  rt  rE   r|   r}   r   r   r   r  r   r  r@   r@   rA   r   &  s$    z_Query.__init__r   r:   c                 C  s
   d | _ d S r   r  r   r@   r@   rA   resetL  s    z_Query.resetc                 C  s   | j  d| j S Nr@  r  ry   r   r@   r@   rA   r  O  s    z_Query.namespacer(   r   r;   c                 C  sR   d}| j sd}n.|jdkr d}n| jjs>td| jj|jf || j| j |S )NFTrb   zDread concern level of %s is not valid with a max wire version of %d.)	r  r   r   Zok_for_legacyr   r   validate_sessionr  r   )r   r   Zuse_find_cmdr@   r@   rA   use_commandR  s    
z_Query.use_commandrM   r   r;   c                 C  s   || j f| _d S r   r  r  r   r   r@   r@   rA   update_commandb  s    z_Query.update_commandFtuple[dict[str, Any], str]r   apply_timeoutr;   c                 C  s   | j dk	r| j S d| jk}t| j| j| j| j| j| j| j| j	| j
| j| j}|r^d| _d|i}|| | jr| j|d| j| |s| jjs| j|| ||| j| j |r|j| j|d || jf| _ | j S )z.Return a find command document for this query.Nr   explainFr   )r  rD   r   ry   r  r  r|   r}   r   r   r   r   r   r   add_server_api	_apply_torE   r   Z_update_read_concernsend_cluster_timer  r  r  )r   r   r  r  r   r@   r@   rA   
as_commande  s:    


z_Query.as_commandr   )rE   r   use_cmdr;   c              
   C  s   || _ |jr| jdB }n| j}|  }| j}|rj| |d }td|| j|| j|j	d\}}}	}
|||	fS | j
dkrxdp|| j
}| jr|rt| j|}n| j}|jrt|tstt||}t||| j|||rdn| j| j|j	dS )z:Get a query message, possibly setting the secondaryOk bit.r   r   r   r+   r,   N)rE   rH   r   r  rD   r  r   r  rt  r   r}   r|   rt   Z	is_mongos
isinstancer	   r;  rK   r   r  r  )r   rE   r   r  r   rW  rD   r   r   r   r9  	ntoreturnr@   r@   rA   get_message  sF    

z_Query.get_message)F)F)rS   r  r  r  r  conn_mgrr   r   r  r  r  r  r  r  r@   r@   r@   rA   r  
  s   ,& ( r  c                   @  s   e Zd ZdZdZdZdddddddd	d
ddddddZddddZddddZdddddZ	dddddZ
d(dddd d!d"Zd)dddd#d$d%d&Zd'S )*_GetMorezA getmore operation.)r  ry   r  r   r   rt  rE   r   r  r  r  r  rq   r   rQ   r9   r   r!   rw   r)   ru   r   r   )r  ry   r  r   rt  rE   r   r  r   r  r  rq   c                 C  sR   || _ || _|| _|| _|| _|| _|| _|| _|	| _|
| _	d | _
|| _|| _d S r   )r  ry   r  r   rt  rE   r   r  r   r  r  r  rq   )r   r  ry   r  r   rt  rE   r   r  r   r  r  rq   r@   r@   rA   r     s    z_GetMore.__init__r   r:   c                 C  s
   d | _ d S r   r  r   r@   r@   rA   r    s    z_GetMore.resetc                 C  s   | j  d| j S r  r  r   r@   r@   rA   r    s    z_GetMore.namespacer(   r  c                 C  s2   d}| j sd}n|jdkrd}|| j| j |S )NFTrb   )r  r   r  r  r   )r   r   r  r@   r@   rA   r    s    
z_GetMore.use_commandrM   r  c                 C  s   || j f| _d S r   r  r  r@   r@   rA   r    s    z_GetMore.update_commandFr  r  c                 C  s   | j dk	r| j S t| j| j| j| j| j|}| jrF| j|d| j	| |
| ||| j| j |rv|j| jdd || jf| _ | j S )z1Return a getMore command document for this query.NFr  )r  r   r   ry   r  r   rq   r   r  rE   r  r  r  r  r  )r   r   r  r   r@   r@   rA   r    s$    

z_GetMore.as_commandz0Union[tuple[int, bytes, int], tuple[int, bytes]])dummy0r   r  r;   c                 C  sv   |   }|j}|rd| |d }| jr4| jr4tj}nd}t||| jd| j	|jd\}}	}
}||	|
fS t
|| j| j|S )zGet a getmore message.r   Nr  )r  r   r  r  r  r  r  r   r  rt  r   r  r   )r   r  r   r  rW  r   rD   r   r   r   r   r9  r@   r@   rA   r  !  s"         
z_GetMore.get_messageN)F)F)rS   r  r  r  r  r   r   r  r  r  r  r  r  r@   r@   r@   rA   r    s   $  r  c                      s$   e Zd Zddd fddZ  ZS )_RawBatchQueryr(   r   r  c                   s(   t  | |jdkrdS | js$dS dS Nrb   TFr  r  r   r  r   r   r  r@   rA   r  7  s    
z_RawBatchQuery.use_commandrS   r  r  r  r  r@   r@   r  rA   r  6  s   r  c                      s$   e Zd Zddd fddZ  ZS )_RawBatchGetMorer(   r   r  c                   s(   t  | |jdkrdS | js$dS dS r  r  r  r  r@   rA   r  C  s    
z_RawBatchGetMore.use_commandr  r@   r@   r  rA   r  B  s   r  c                   @  sl   e Zd ZU dZded< ddd dddZedd	d
dZdd	ddZdddddZ	dddddZ
dS )_CursorAddresszEThe server address (host, port) of a cursor, with namespace property.r   _CursorAddress__namespacer&   rQ   )r   r  r;   c                 C  s   t | |}||_|S r   )tuple__new__r  )r  r   r  r   r@   r@   rA   r  S  s    z_CursorAddress.__new__r:   c                 C  s   | j S )zThe namespace this cursor.)r  r   r@   r@   rA   r  X  s    z_CursorAddress.namespacer9   c                 C  s   | | j f S r   )r  __hash__r   r@   r@   rA   r  ]  s    z_CursorAddress.__hash__objectr   )otherr;   c                 C  s*   t |tr&t| t|ko$| j|jkS tS r   )r  r  r  r  NotImplementedr   r  r@   r@   rA   __eq__b  s    
z_CursorAddress.__eq__c                 C  s
   | |k S r   r@   r  r@   r@   rA   __ne__g  s    z_CursorAddress.__ne__N)rS   r  r  r  __annotations__r  r  r  r  r  r  r@   r@   r@   rA   r  N  s   
r  )NNN)N)N)N)r  
__future__r   r   r<   r  ior   r#  typingr   r   r   r   r   r	   r
   r   r   r   r   r   r   Z
bson.int64r   Zbson.raw_bsonr   r   r   r   Zpymongo.hellor   Zpymongo.monitoringr   Zpymongor   Z_use_cImportErrorZpymongo.errorsr   r   r   r   r   r   r   r   Zpymongo.read_preferencesr    r!   Zpymongo.compression_supportr"   r#   r$   Zpymongo.read_concernr%   Zpymongo.typingsr&   r'   r(   r)   r*   r?   r>   rX  Z_INSERTZ_UPDATEZ_DELETEZ_EMPTYrf  rb  rg  r   r>  rc  re  r   r8   r  rB   rK   rU   rW   rj   r   r   r   r   r  packr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Z_query_messager   r   r   r   r   Z_get_more_messager   r+  r   r	  r  r"  r  r7  r:  r<  r?  r  rD  rY  rS  r[  r\  r]  r^  rI  r  r_  rh  r  r  r  r  r  r  r  r  r  r  r@   r@   r@   rA   <module>   s8  ,
(
	   %
   &3
 	    
    ^7D=0vMqU   8u