U
    f                     @   s>  d Z ddlZddlZddlZddlmZ zddlZdZW n e	k
rP   dZY nX zddl
ZdZW n e	k
rz   dZY nX ddlmZmZmZmZ ddl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m Z m!Z!m"Z"m#Z# dZ$e%dZ&G dd de'Z(G dd de'Z)G dd de'Z*G dd de'Z+dS )z4Implementation of the X protocol for MySQL servers.
    N)BytesIOTF   )InterfaceErrorNotSupportedErrorOperationalErrorProgrammingError)
ExprParser
build_exprbuild_scalarbuild_bool_scalarbuild_int_scalarbuild_unsigned_int_scalar)encode_to_bytesget_item_or_attr)Column)CRUD_PREPARE_MAPPINGSERVER_MESSAGESPROTOBUF_REPEATED_TYPESMessagemysqlxpb_enumi  Zmysqlxc                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	
CompressorzImplements compression/decompression using `zstd_stream`, `lz4_message`
    and `deflate_stream` algorithms.

    Args:
        algorithm (str): Compression algorithm.

    .. versionadded:: 8.0.21

    c                 C   sR   || _ |dkr$t | _t | _n*|dkrBt | _t | _nd | _d | _d S )Nzstd_streamZdeflate_stream)	
_algorithmzstdZZstdCompressor_compressobjZZstdDecompressor_decompressobjzlibcompressobjdecompressobjself	algorithm r"   3/tmp/pip-unpacked-wheel-mzf9r1ws/mysqlx/protocol.py__init__J   s    

zCompressor.__init__c              	   C   s~   | j dkr| j|S | j dkr\tj (}| }|||7 }|| 7 }W 5 Q R X |S | j|}|| jtj	7 }|S )zCompresses data and returns it.

        Args:
            data (str, bytes or buffer object): Data to be compressed.

        Returns:
            bytes: Compressed data.
        r   lz4_message)
r   r   compresslz4frameZLZ4FrameCompressorbeginflushr   Z_SYNC_FLUSH)r    dataZ
compressor
compressedr"   r"   r#   r&   V   s    	

zCompressor.compressc              	   C   sf   | j dkr| j|S | j dkrDtj }||}W 5 Q R X |S | j|}|| jtj7 }|S )zDecompresses a frame of data and returns it as a string of bytes.

        Args:
            data (str, bytes or buffer object): Data to be compressed.

        Returns:
            bytes: Decompresssed data.
        r   r%   )	r   r   
decompressr'   r(   ZLZ4FrameDecompressorr*   r   r+   )r    r,   Zdecompressordecompressedr"   r"   r#   r.   m   s    	

zCompressor.decompressN)__name__
__module____qualname____doc__r$   r&   r.   r"   r"   r"   r#   r   @   s   	r   c                   @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )MessageReaderzImplements a Message Reader.

    Args:
        socket_stream (mysqlx.connection.SocketStream): `SocketStream` object.

    .. versionadded:: 8.0.21
    c                 C   s   || _ d | _d | _g | _d S N)_stream_compressor_msg
_msg_queuer    Zsocket_streamr"   r"   r#   r$      s    zMessageReader.__init__c                 C   s  | j r| j dS td| jd\}}|dkr:td| j|d }|tkr`td	||dkrx|d	krx| 
 S t||}|d
kr|d }t| j|d }d}||k rtd|d\}}	||d }
| j t|	|
 ||d 7 }q| j r| j dS dS |S )a  Reads X Protocol messages from the stream and returns a
        :class:`mysqlx.protobuf.Message` object.

        Raises:
            :class:`mysqlx.ProgrammingError`: If e connected server does not
                                              have the MySQL X protocol plugin
                                              enabled.

        Returns:
            mysqlx.protobuf.Message: MySQL X Protobuf Message.
        r   <LB   
   z[The connected server does not have the MySQL X protocol plugin enabled or protocol mismatchr   zUnknown message type: {}          uncompressed_sizepayload   N)r9   popstructunpackr6   readr   r   
ValueErrorformat_read_messager   Zfrom_server_messager   r7   r.   append)r    
frame_sizeZ
frame_typeZframe_payloadZ	frame_msgrA   streamZbytes_processedZpayload_sizemsg_typerB   r"   r"   r#   rJ      s2    

zMessageReader._read_messagec                 C   s"   | j dk	r| j }d| _ |S |  S )zgRead message.

        Returns:
            mysqlx.protobuf.Message: MySQL X Protobuf Message.
        N)r8   rJ   r    msgr"   r"   r#   read_message   s
    
zMessageReader.read_messagec                 C   s   | j dk	rtd|| _ dS )zPush message.

        Args:
            msg (mysqlx.protobuf.Message): MySQL X Protobuf Message.

        Raises:
            :class:`mysqlx.OperationalError`: If message push slot is full.
        NzMessage push slot is full)r8   r   rO   r"   r"   r#   push_message   s    	
zMessageReader.push_messagec                 C   s   |rt |nd| _dS )zCreates a :class:`mysqlx.protocol.Compressor` object based on the
        compression algorithm.

        Args:
            algorithm (str): Compression algorithm.

        .. versionadded:: 8.0.21

        Nr   r7   r   r"   r"   r#   set_compression   s    
zMessageReader.set_compressionN)	r0   r1   r2   r3   r$   rJ   rQ   rR   rT   r"   r"   r"   r#   r4      s   /r4   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	MessageWriterzImplements a Message Writer.

    Args:
        socket_stream (mysqlx.connection.SocketStream): `SocketStream` object.

    .. versionadded:: 8.0.21

    c                 C   s   || _ d | _d S r5   )r6   r7   r:   r"   r"   r#   r$      s    zMessageWriter.__init__c                 C   s  | |}| jr|tkrt| }td|d |}| jd||g}t	d}||d< |d |d< t	d}||d< dt|
 d	d
 t|
 g}	td}
tdt|	d |
}| jd||	g n4t| }td|d |}| jd||g d	S )zWrite message.

        Args:
            msg_type (int): The message type.
            msg (mysqlx.protobuf.Message): MySQL X Protobuf Message.
        r;   r   r?   zMysqlx.Connection.CompressionZclient_messagesr<   rA   rB   Nz&Mysqlx.ClientMessages.Type.COMPRESSION)Z	byte_sizer7   _COMPRESSION_THRESHOLDr   Zserialize_to_stringrE   packr&   joinr   Zserialize_partial_to_stringr   lenr6   sendall)r    rN   rP   Zmsg_sizeZmsg_strheaderr-   Zmsg_first_fieldsZmsg_payloadoutputZmsg_comp_idr"   r"   r#   write_message   s*    

zMessageWriter.write_messagec                 C   s   |rt |nd| _dS )zCreates a :class:`mysqlx.protocol.Compressor` object based on the
        compression algorithm.

        Args:
            algorithm (str): Compression algorithm.
        NrS   r   r"   r"   r#   rT     s    zMessageWriter.set_compressionN)r0   r1   r2   r3   r$   r^   rT   r"   r"   r"   r#   rU      s   "rU   c                   @   s  e Zd ZdZdd Zedd Zdd Zdd	 ZdDddZ	dd Z
dd Zdd Zdd Zdd ZdEddZdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ ZdFd0d1Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Z d<d= Z!d>d? Z"d@dA Z#dGdBdCZ$dS )HProtocolzImplements the MySQL X Protocol.

    Args:
        read (mysqlx.protocol.MessageReader): A Message Reader object.
        writer (mysqlx.protocol.MessageWriter): A Message Writer object.

    .. versionchanged:: 8.0.21
    c                 C   s   || _ || _d | _g | _d S r5   )_reader_writer_compression_algorithm	_warnings)r    readerwriterr"   r"   r#   r$   (  s    zProtocol.__init__c                 C   s   | j S )z'str: The compresion algorithm.
        )rb   )r    r"   r"   r#   compression_algorithm.  s    zProtocol.compression_algorithmc                 C   sX   |j r| |d< |jr*|d |  |jrB|d |  |jrT| |d< dS )zApply filter.

        Args:
            msg (mysqlx.protobuf.Message): The MySQL X Protobuf Message.
            stmt (Statement): A `Statement` based type object.
        ZcriteriaordergroupingZgrouping_criteriaN)	Z	has_whereZget_where_exprZhas_sortextendZget_sort_exprZhas_group_byZget_groupingZ
has_havingZ
get_having)r    rP   stmtr"   r"   r#   _apply_filter4  s    zProtocol._apply_filterc                 C   s  t |tr2td|d}tdd|d}tdd|dS t |trNtddt|dS t |tr|d	k rrtddt|dS tddt|dS t |trt	|d
kr|\}}td|| 
|d}td| gd}tdd
|dS t |tst |ttfrt |d	 trg }|D ]h}	g }
|	 D ],\}}td|| 
|d}|
|  qtd|
d}tdd
|d}||  q
td}||d< tdd|dS t |trg }
|D ],\}}td|| 
|d}|
|  qtd|
d}tdd
|d}|S dS )zCreate any.

        Args:
            arg (object): Arbitrary object.

        Returns:
            mysqlx.protobuf.Message: MySQL X Protobuf Message.
        zMysqlx.Datatypes.Scalar.StringvaluezMysqlx.Datatypes.Scalar   )typeZv_stringMysqlx.Datatypes.Anyr   )ro   scalarr      #Mysqlx.Datatypes.Object.ObjectFieldkeyrm   Mysqlx.Datatypes.ObjectZfldro   objzMysqlx.Datatypes.Arrayrm      )ro   arrayN)
isinstancestrr   boolr   intr   r   tuplerZ   _create_anyget_messagedictlistitemsrK   )r    argrm   rq   Zarg_key	arg_valueobj_fldry   Zarray_valuesr   obj_fldsru   msg_objmsg_anyrP   r"   r"   r#   r   D  sp    	


   zProtocol._create_anyTc           
         s   fdd |  }| }|dkr8 fdd|D S t|}|dg }|t|kr^td| D ]2\}}||krtd||| }	 |||	< qf|S )a  Returns the binding any/scalar.

        Args:
            stmt (Statement): A `Statement` based type object.
            is_scalar (bool): `True` to return scalar values.

        Raises:
            :class:`mysqlx.ProgrammingError`: If unable to find placeholder for
                                              parameter.

        Returns:
            list: A list of ``Any`` or ``Scalar`` objects.
        c                    s    rt |  S |  S r5   )r
   r   r   rl   )	is_scalarr    r"   r#   <lambda>  s    z,Protocol._get_binding_args.<locals>.<lambda>Nc                    s   g | ]} |qS r"   r"   .0rm   )build_valuer"   r#   
<listcomp>  s     z.Protocol._get_binding_args.<locals>.<listcomp>z;The number of bind parameters and placeholders do not matchz-Unable to find placeholder for parameter: {0})get_bindingsZget_binding_maprZ   r   r   rI   )
r    rj   r   ZbindingsZbinding_mapcountargsnamerm   posr"   )r   r   r    r#   _get_binding_args~  s"    
zProtocol._get_binding_argsc                 C   s(  |d dkrRt d|d }| j|j td|j|j ||j	|j|j n|d dkrpt d|d  n|d dkr$t d	|d }|d
 t
dkr|dd |d D  nlt|d ttr|d d n|d }|d
 t
dkr|t|d n"|d
 t
dkr$|t|d dS )zProcess frame.

        Args:
            msg (mysqlx.protobuf.Message): A MySQL X Protobuf Message.
            result (Result): A `Result` based type object.
        ro   r   zMysqlx.Notice.WarningrB   z:Protocol.process_frame Received Warning Notice code %s: %srr   z$Mysqlx.Notice.SessionVariableChangedrz   z!Mysqlx.Notice.SessionStateChangedparamzBMysqlx.Notice.SessionStateChanged.Parameter.GENERATED_DOCUMENT_IDSc                 S   s    g | ]}t t |d d qS )Zv_octetsrm   )r   decoder   r"   r"   r#   r     s
    z+Protocol._process_frame.<locals>.<listcomp>rm   r   z9Mysqlx.Notice.SessionStateChanged.Parameter.ROWS_AFFECTEDZv_unsigned_intz?Mysqlx.Notice.SessionStateChanged.Parameter.GENERATED_INSERT_IDN)r   Zfrom_messagerc   rK   rP   _LOGGERwarningcodeZappend_warninglevelr   Zset_generated_idsr|   r   r   Zset_rows_affectedr   Zset_generated_insert_id)r    rP   resultZwarn_msgZsess_state_msgZsess_state_valuer"   r"   r#   _process_frame  s\       zProtocol._process_framec              
   C   s   z| j  }W nB tk
rP } z$t| }|r@td||W 5 d}~X Y nX |jdkrpt|d |d q |jdkrz| || W q   Y q Y qX q |jdkrdS |jdkr|	d	 q |jd
kr|
d	 q |jdkr|d	 qq qq |S )z`Read message.

        Args:
            result (Result): A `Result` based type object.
        z{} reason: {}NMysqlx.ErrorrP   r   Mysqlx.Notice.FramezMysqlx.Sql.StmtExecuteOkzMysqlx.Resultset.FetchDoneTz(Mysqlx.Resultset.FetchDoneMoreResultsetsMysqlx.Resultset.Row)r`   rQ   RuntimeErrorreprZget_warningsrI   ro   r   r   Z
set_closedZset_has_more_resultsZset_has_data)r    r   rP   errwarningsr"   r"   r#   rJ     s4    







zProtocol._read_messagec                 C   s"   || _ | j| | j| dS )zSets the compression algorithm to be used by the compression
        object, for uplink and downlink.

        Args:
            algorithm (str): Algorithm to be used in compression/decompression.

        .. versionadded:: 8.0.21

        N)rb   r`   rT   ra   r   r"   r"   r#   rT     s    
zProtocol.set_compressionc                 C   sZ   t d}| jtd| | j }|jdkr:| j }q$|jdkrVt|d |d |S )zkGet capabilities.

        Returns:
            mysqlx.protobuf.Message: MySQL X Protobuf Message.
        z!Mysqlx.Connection.CapabilitiesGetz/Mysqlx.ClientMessages.Type.CON_CAPABILITIES_GETr   r   rP   r   )r   ra   r^   r   r`   rQ   ro   r   rO   r"   r"   r#   get_capabilites  s    


zProtocol.get_capabilitesc              
   K   s"  |sdS t d}| D ]\}}t d}||d< t|tr|}g }|D ]*}t d|| || d}	||	  qFt d|d}
t d	d
|
d}| |d< n| ||d< |d | g qt d}||d< | j	t
d| z
|  W S  tk
r } z|jdkr W 5 d}~X Y nX dS )zSet capabilities.

        Args:
            **kwargs: Arbitrary keyword arguments.

        Returns:
            mysqlx.protobuf.Message: MySQL X Protobuf Message.
        NzMysqlx.Connection.CapabilitieszMysqlx.Connection.Capabilityr   rs   rt   rv   rw   rp   rr   rx   rm   capabilitiesz!Mysqlx.Connection.CapabilitiesSetz/Mysqlx.ClientMessages.Type.CON_CAPABILITIES_SETi  )r   r   r|   r   r   rK   r   ri   ra   r^   r   read_okr   errno)r    kwargsr   ru   rm   Z
capabilityr   r   itemr   r   r   rP   r   r"   r"   r#   set_capabilities  s@    	

zProtocol.set_capabilitiesNc                 C   sF   t d}||d< |dk	r ||d< |dk	r0||d< | jtd| dS )zSend authenticate start.

        Args:
            method (str): Message method.
            auth_data (Optional[str]): Authentication data.
            initial_response (Optional[str]): Initial response.
        z Mysqlx.Session.AuthenticateStartZ	mech_nameN	auth_datainitial_responsez2Mysqlx.ClientMessages.Type.SESS_AUTHENTICATE_STARTr   ra   r^   r   )r    methodr   r   rP   r"   r"   r#   send_auth_start=  s    zProtocol.send_auth_startc                 C   s:   | j  }|jdkr | j  }q
|jdkr2td|d S )zRead authenticate continue.

        Raises:
            :class:`InterfaceError`: If the message type is not
                                     `Mysqlx.Session.AuthenticateContinue`

        Returns:
            str: The authentication data.
        r   #Mysqlx.Session.AuthenticateContinuez>Unexpected message encountered during authentication handshaker   )r`   rQ   ro   r   rO   r"   r"   r#   read_auth_continueN  s    



zProtocol.read_auth_continuec                 C   s"   t d|d}| jtd| dS )zeSend authenticate continue.

        Args:
            auth_data (str): Authentication data.
        r   )r   z5Mysqlx.ClientMessages.Type.SESS_AUTHENTICATE_CONTINUENr   )r    r   rP   r"   r"   r#   send_auth_continue`  s    zProtocol.send_auth_continuec                 C   s0   | j  }|jdkrq,|jdkr t|jq dS )z~Read authenticate OK.

        Raises:
            :class:`mysqlx.InterfaceError`: If message type is `Mysqlx.Error`.
        zMysqlx.Session.AuthenticateOkr   N)r`   rQ   ro   r   rP   rO   r"   r"   r#   read_auth_okk  s
    


zProtocol.read_auth_okc                 C   sB  |j r|jdkr|jdkr*| |\}}nB|jdkrD| |\}}n(|jdkr^| |\}}ntd|t| }t	d}t
d}t
d||d	|d
< |jdkrt
d||d d	|d< ||d< t| \}}	t
d}
t	||
d< ||
|	< t
d}|j|d< |
|d< | jt	d| z|   W n tk
r<   tY nX dS )a  
        Send prepare statement.

        Args:
            msg_type (str): Message ID string.
            msg (mysqlx.protobuf.Message): MySQL X Protobuf Message.
            stmt (Statement): A `Statement` based type object.

        Raises:
            :class:`mysqlx.NotSupportedError`: If prepared statements are not
                                               supported.

        .. versionadded:: 8.0.16
        Mysqlx.Crud.InsertMysqlx.Crud.FindMysqlx.Crud.UpdateMysqlx.Crud.DeletezInvalid message type: {}z!Mysqlx.Expr.Expr.Type.PLACEHOLDERzMysqlx.Crud.LimitExprzMysqlx.Expr.Expr)ro   position	row_countr   offsetZ
limit_expr#Mysqlx.Prepare.Prepare.OneOfMessagero   zMysqlx.Prepare.Preparestmt_idrj   z*Mysqlx.ClientMessages.Type.PREPARE_PREPAREN)	has_limitro   
build_findbuild_updatebuild_deleterH   rI   rZ   r   r   r   r   r   ra   r^   r   r   r   )r    rN   rP   rj   _r   placeholderZmsg_limit_expr
oneof_typeoneof_op	msg_oneofZmsg_preparer"   r"   r#   send_prepare_preparex  sH    






zProtocol.send_prepare_preparec           	      C   s   t | \}}td}t||d< |||< td}|j|d< | j|dd}|rZ|d | |jr|d | | 	 | |
 	 g | jtd| d	S )
a  
        Send execute statement.

        Args:
            msg_type (str): Message ID string.
            msg (mysqlx.protobuf.Message): MySQL X Protobuf Message.
            stmt (Statement): A `Statement` based type object.

        .. versionadded:: 8.0.16
        r   ro   zMysqlx.Prepare.Executer   Fr   r   z*Mysqlx.ClientMessages.Type.PREPARE_EXECUTEN)r   r   r   r   r   ri   r   r   get_limit_row_countr   get_limit_offsetra   r^   )	r    rN   rP   rj   r   r   r   Zmsg_executer   r"   r"   r#   send_prepare_execute  s$    
zProtocol.send_prepare_executec                 C   s.   t d}||d< | jtd| |   dS )z
        Send prepare deallocate statement.

        Args:
            stmt_id (int): Statement ID.

        .. versionadded:: 8.0.16
        zMysqlx.Prepare.Deallocater   z-Mysqlx.ClientMessages.Type.PREPARE_DEALLOCATEN)r   ra   r^   r   r   )r    r   Zmsg_deallocr"   r"   r#   send_prepare_deallocate  s    	z Protocol.send_prepare_deallocatec                 C   sx   |j r8td}| |d< |jdkr0| |d< ||d< |dkrDdnd}| j||d	}|rh|d
 | | || dS )a)  
        Send a message without prepared statements support.

        Args:
            msg_type (str): Message ID string.
            msg (mysqlx.protobuf.Message): MySQL X Protobuf Message.
            stmt (Statement): A `Statement` based type object.

        .. versionadded:: 8.0.16
        zMysqlx.Crud.Limitr   r   r   limit+Mysqlx.ClientMessages.Type.SQL_STMT_EXECUTEFTr   r   N)r   r   r   ro   r   r   ri   send_msg)r    rN   rP   rj   Z	msg_limitr   r   r"   r"   r#   send_msg_without_ps  s    
zProtocol.send_msg_without_psc                 C   s   | j t|| dS )z
        Send a message.

        Args:
            msg_type (str): Message ID string.
            msg (mysqlx.protobuf.Message): MySQL X Protobuf Message.

        .. versionadded:: 8.0.16
        N)ra   r^   r   )r    rN   rP   r"   r"   r#   r     s    
zProtocol.send_msgc                 C   s   t | rdnd}td|jj|jjd}td||d}|jrJ| |d< | || |	 rlt d|d	< n|
 rt d
|d	< |jdkr|j|d< d|fS )a  Build find/read message.

        Args:
            stmt (Statement): A :class:`mysqlx.ReadStatement` or
                              :class:`mysqlx.FindStatement` object.

        Returns:
            (tuple): Tuple containing:

                * `str`: Message ID string.
                * :class:`mysqlx.protobuf.Message`: MySQL X Protobuf Message.

        .. versionadded:: 8.0.16
        Mysqlx.Crud.DataModel.DOCUMENTMysqlx.Crud.DataModel.TABLEMysqlx.Crud.Collectionr   schemar   
data_model
collection
projectionz'Mysqlx.Crud.Find.RowLock.EXCLUSIVE_LOCKZlockingz$Mysqlx.Crud.Find.RowLock.SHARED_LOCKr   Zlocking_optionsz$Mysqlx.ClientMessages.Type.CRUD_FIND)r   is_doc_basedr   targetr   r   Zhas_projectionZget_projection_exprrk   Zis_lock_exclusiveZis_lock_sharedZlock_contentionr    rj   r   r   rP   r"   r"   r#   r     s0    

zProtocol.build_findc                 C   s   t | rdnd}td|jj|jjd}td||d}| || |  D ]P\}}td}|j	|d< |j
|d	< |jd
k	rt|j|d< |d | g qPd|fS )a  Build update message.

        Args:
            stmt (Statement): A :class:`mysqlx.ModifyStatement` or
                              :class:`mysqlx.UpdateStatement` object.

        Returns:
            (tuple): Tuple containing:

                * `str`: Message ID string.
                * :class:`mysqlx.protobuf.Message`: MySQL X Protobuf Message.

        .. versionadded:: 8.0.16
        r   r   r   r   r   r   zMysqlx.Crud.UpdateOperation	operationsourceNrm   z&Mysqlx.ClientMessages.Type.CRUD_UPDATE)r   r   r   r   r   r   rk   Zget_update_opsr   Zupdate_typer   rm   r	   ri   r   )r    rj   r   r   rP   r   Z	update_opr   r"   r"   r#   r   +  s*    


zProtocol.build_updatec                 C   sL   t | rdnd}td|jj|jjd}td||d}| || d|fS )a  Build delete message.

        Args:
            stmt (Statement): A :class:`mysqlx.DeleteStatement` or
                              :class:`mysqlx.RemoveStatement` object.

        Returns:
            (tuple): Tuple containing:

                * `str`: Message ID string.
                * :class:`mysqlx.protobuf.Message`: MySQL X Protobuf Message.

        .. versionadded:: 8.0.16
        r   r   r   r   r   r   z&Mysqlx.ClientMessages.Type.CRUD_DELETE)r   r   r   r   r   r   rk   r   r"   r"   r#   r   M  s    
zProtocol.build_deletec                 C   s|   t d||dd}|rtg }| D ]*\}}t d|| |d}||  q t d|d}	t dd	|	d
}
|
 g|d< d|fS )a  Build execute statement.

        Args:
            namespace (str): The namespace.
            stmt (Statement): A `Statement` based type object.
            fields (Optional[dict]): The message fields.

        Returns:
            (tuple): Tuple containing:

                * `str`: Message ID string.
                * :class:`mysqlx.protobuf.Message`: MySQL X Protobuf Message.

        .. versionadded:: 8.0.16
        zMysqlx.Sql.StmtExecuteF)	namespacerj   Zcompact_metadatars   rt   rv   rw   rp   rr   rx   r   r   )r   r   r   rK   r   )r    r   rj   fieldsrP   r   ru   rm   r   r   r   r"   r"   r#   build_execute_statementf  s     z Protocol.build_execute_statementc           
      C   s  t | rdnd}td|jj|jjd}td||d}t|drv|jD ],}t||  	 }|d 
| g qH| D ]f}td	}t|tr|D ]}	|d
 
t|	 g qn|d
 
t| g |d 
| g q~t|dr| |d< d|fS )a  Build insert statement.

        Args:
            stmt (Statement): A :class:`mysqlx.AddStatement` or
                              :class:`mysqlx.InsertStatement` object.

        Returns:
            (tuple): Tuple containing:

                * `str`: Message ID string.
                * :class:`mysqlx.protobuf.Message`: MySQL X Protobuf Message.

        .. versionadded:: 8.0.16
        r   r   r   r   r   r   _fieldsr   zMysqlx.Crud.Insert.TypedRowfieldrow	is_upsertZupsertz&Mysqlx.ClientMessages.Type.CRUD_INSERT)r   r   r   r   r   r   hasattrr   r   Zparse_table_insert_fieldri   r   Z
get_valuesr|   r   r	   r   )
r    rj   r   r   rP   r   exprrm   r   valr"   r"   r#   build_insert  s4    



zProtocol.build_insertc                 C   s   |  |}|dk	rtddS )zClose the result.

        Args:
            result (Result): A `Result` based type object.

        Raises:
            :class:`mysqlx.OperationalError`: If message read is None.
        NzExpected to close the result)rJ   r   r    r   rP   r"   r"   r#   close_result  s    	
zProtocol.close_resultc                 C   s4   |  |}|dkrdS |jdkr$|S | j| dS )z\Read row.

        Args:
            result (Result): A `Result` based type object.
        Nr   )rJ   ro   r`   rR   r   r"   r"   r#   read_row  s    

zProtocol.read_rowc                 C   s   g }|  |}|dkrq|jdkr0| j| q|jdkrBtdt|d |d |d |d |d	 |d
 |d |dd|dd|dd|dd|d}|| q|S )zReturns column metadata.

        Args:
            result (Result): A `Result` based type object.

        Raises:
            :class:`mysqlx.InterfaceError`: If unexpected message.
        Nr   zMysqlx.Resultset.ColumnMetaDatazUnexpected msg typero   catalogr   tableZoriginal_tabler   original_namelength   Z	collationr   Zfractional_digitsflags   content_type)rJ   ro   r`   rR   r   r   getrK   )r    r   columnsrP   colr"   r"   r#   get_column_metadata  s,    	


  



zProtocol.get_column_metadatac                 C   sD   | j  }|jdkr.td|d |d d|jdkr@tddS )	zeRead OK.

        Raises:
            :class:`mysqlx.InterfaceError`: If unexpected message.
        r   zMysqlx.Error: {}rP   r   )r   z	Mysqlx.OkzUnexpected message encounteredN)r`   rQ   ro   r   rI   rO   r"   r"   r#   r     s    


zProtocol.read_okc                 C   s   t d}| jtd| dS )zSend connection close.zMysqlx.Connection.Closez$Mysqlx.ClientMessages.Type.CON_CLOSENr   rO   r"   r"   r#   send_connection_close  s    zProtocol.send_connection_closec                 C   s   t d}| jtd| dS )zSend close.zMysqlx.Session.Closez%Mysqlx.ClientMessages.Type.SESS_CLOSENr   rO   r"   r"   r#   
send_close  s    zProtocol.send_closec                 C   sL   t d}td}||d< d|d< td}| g|d< | jt d| d	S )
zSend expectation.z3Mysqlx.Expect.Open.Condition.Key.EXPECT_FIELD_EXISTzMysqlx.Expect.Open.ConditionZcondition_keyz6.1Zcondition_valuezMysqlx.Expect.OpenZcondz&Mysqlx.ClientMessages.Type.EXPECT_OPENN)r   r   r   ra   r^   )r    Zcond_keyZmsg_ocZmsg_eor"   r"   r#   send_expect_open  s    zProtocol.send_expect_openc                 C   st   t d}|dkrBz|   |   d}W n tk
r@   d}Y nX |rNd|d< | jtd| |   |rpdS dS )zSend reset session message.

        Returns:
            boolean: ``True`` if the server will keep the session open,
                     otherwise ``False``.
        zMysqlx.Session.ResetNTF	keep_openz%Mysqlx.ClientMessages.Type.SESS_RESET)r   r   r   r   ra   r^   r   )r    r   rP   r"   r"   r#   
send_reset  s&    
zProtocol.send_reset)T)NN)N)N)%r0   r1   r2   r3   r$   propertyrf   rk   r   r   r   rJ   rT   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r"   r"   r"   r#   r_     sD   
:
$+"-
7 '"
,r_   ),r3   loggingrE   r   ior   Z	lz4.framer'   ZHAVE_LZ4ImportErrorZ	zstandardr   Z	HAVE_ZSTDerrorsr   r   r   r   r   r   r	   r
   r   r   r   Zhelpersr   r   r   r   Zprotobufr   r   r   r   r   rW   	getLoggerr   objectr   r4   rU   r_   r"   r"   r"   r#   <module>   s2   

 
Cc9