3
S^                  @   s   d Z ddlZddlmZmZ 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 G d
d deZG dd deZdS )z3Implementation of the X protocol for MySQL servers.    N   )STRING_TYPES	INT_TYPES)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_enumc               @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )MessageReaderWriterzImplements a Message Reader/Writer.

    Args:
        socket_stream (mysqlx.connection.SocketStream): `SocketStream` object.
    c             C   s   || _ d | _d S )N)_stream_msg)selfZsocket_stream r   A/tmp/pip-build-8app2_gc/mysql-connector-python/mysqlx/protocol.py__init__2   s    zMessageReaderWriter.__init__c             C   s   | j jd}tjd|\}}|dkr,td| j j|d }tj|}|sXtdj||dkrp|dkrp| j	 S yt
j||}W n tk
r   | j	 S X |S )	aK  Read message.

        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.
           z<LB
   zZThe connected server does not have the MySQL X protocol plugin enabled or protocolmismatchr   zUnknown msg_type: {0}       )r   readstructunpackr   r   get
ValueErrorformat_read_messager   Zfrom_server_messageRuntimeError)r   hdrZmsg_lenmsg_typepayloadZmsg_type_namemsgr   r   r   r(   6   s    

z!MessageReaderWriter._read_messagec             C   s"   | j dk	r| j }d| _ |S | j S )zgRead message.

        Returns:
            mysqlx.protobuf.Message: MySQL X Protobuf Message.
        N)r   r(   )r   r-   r   r   r   read_messageU   s
    
z MessageReaderWriter.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)r   r   )r   r-   r   r   r   push_messagea   s    	
z MessageReaderWriter.push_messagec             C   s<   t |j }tjdt|d |}| jjdj||g dS )zWrite message.

        Args:
            msg_id (int): The message ID.
            msg (mysqlx.protobuf.Message): MySQL X Protobuf Message.
        z<LBr   r!   N)r   Zserialize_to_stringr#   packlenr   sendalljoin)r   Zmsg_idr-   Zmsg_strheaderr   r   r   write_messagen   s    z!MessageReaderWriter.write_messageN)	__name__
__module____qualname____doc__r   r(   r.   r/   r5   r   r   r   r   r   ,   s   r   c               @   s  e Zd ZdZdd Zdd Zdd ZdBd	d
Zdd Zdd Z	dd Z
dd Zdd ZdCd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d.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Zd<d= Z d>d? Z!dDd@dAZ"dS )EProtocolzImplements the MySQL X Protocol.

    Args:
        read_writer (mysqlx.protocol.MessageReaderWriter): A Message             Reader/Writer object.
    c             C   s   || _ || _d | _d S )N)_reader_writer_message)r   Zreader_writerr   r   r   r      s    zProtocol.__init__c             C   sX   |j r|j |d< |jr*|d j|j  |jrB|d j|j  |jrT|j |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   r-   stmtr   r   r   _apply_filter   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|| j
|d}td|j gd}tdd
|dS t |tst |ttfrt |d	 trg }xt|D ]l}	g }
x8|	j D ],\}}td|| j
|d}|
j|j  qW td|
d}tdd
|d}|j|j  qW t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_stringzMysqlx.Datatypes.Anyr   )rE   scalarr      z#Mysqlx.Datatypes.Object.ObjectField)keyrC   zMysqlx.Datatypes.Object)fld)rE   objzMysqlx.Datatypes.ArrayrC      )rE   arrayN)
isinstancer   r   boolr   r   r   r   tupler1   _create_anyget_messagedictlistitemsappend)r   argrC   rF   Zarg_key	arg_valueobj_fldrJ   Zarray_valuesrT   obj_fldsrH   msg_objmsg_anyr-   r   r   r   rP      sH    	



zProtocol._create_anyTc       
         s   fdd |j  }|j }|dkr8 fdd|D S t|}|dg }|t|kr^tdx>|j D ]2\}}||krtdj||| }	 |||	< qhW |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 | j S j| j S )N)r   rQ   rP   )rC   )	is_scalarr   r   r   <lambda>   s    z,Protocol._get_binding_args.<locals>.<lambda>Nc                s   g | ]} |qS r   r   ).0rC   )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_mapr1   r   rT   r'   )
r   rA   r\   ZbindingsZbinding_mapcountargsnamerC   posr   )r_   r\   r   r   _get_binding_args   s     
zProtocol._get_binding_argsc             C   s  |d dkr2t jd|d }|j|j|j|j n|d dkrPt jd|d  n|d dkrt jd|d }|d	 td
kr|jdd |d D  nht|d t	t
r|d d n|d }|d	 tdkr|jt|d n |d	 tdkr|jt|d dS )zProcess frame.

        Args:
            msg (mysqlx.protobuf.Message): A MySQL X Protobuf Message.
            result (Result): A `Result` based type object.
        rE   r   zMysqlx.Notice.Warningr,   rG   z$Mysqlx.Notice.SessionVariableChangedrK   z!Mysqlx.Notice.SessionStateChangedparamzBMysqlx.Notice.SessionStateChanged.Parameter.GENERATED_DOCUMENT_IDSc             S   s    g | ]}t t |d dj qS )Zv_octetsrC   )r   decode)r^   rC   r   r   r   r`     s   z+Protocol._process_frame.<locals>.<listcomp>rC   r   z9Mysqlx.Notice.SessionStateChanged.Parameter.ROWS_AFFECTEDZv_unsigned_intz?Mysqlx.Notice.SessionStateChanged.Parameter.GENERATED_INSERT_IDN)r   Zfrom_messageZappend_warninglevelcoder-   r   Zset_generated_idsrM   rO   r   Zset_rows_affectedr   Zset_generated_insert_id)r   r-   resultZwarn_msgZsess_state_msgZsess_state_valuer   r   r   _process_frame   s4    
zProtocol._process_framec          	   C   s   x| j j }|jdkr*t|d |d q|jdkrVy| j|| W q   wY qX q|jdkrddS |jdkrz|jd q|jd	kr|jd q|jd
kr|jd P qP qW |S )z`Read message.

        Args:
            result (Result): A `Result` based type object.
        zMysqlx.Errorr-   rj   zMysqlx.Notice.FramezMysqlx.Sql.StmtExecuteOkNzMysqlx.Resultset.FetchDoneTz(Mysqlx.Resultset.FetchDoneMoreResultsetszMysqlx.Resultset.Row)r;   r.   rE   r   rl   Z
set_closedZset_has_more_resultsZset_has_data)r   rk   r-   r   r   r   r(     s(    








zProtocol._read_messagec             C   sB   t d}| jjtd| | jj }x|jdkr<| jj }q&W |S )zkGet capabilities.

        Returns:
            mysqlx.protobuf.Message: MySQL X Protobuf Message.
        z!Mysqlx.Connection.CapabilitiesGetz/Mysqlx.ClientMessages.Type.CON_CAPABILITIES_GETzMysqlx.Notice.Frame)r   r<   r5   r   r;   r.   rE   )r   r-   r   r   r   get_capabilites1  s    
zProtocol.get_capabilitesc             K   s   t d}x|j D ]\}}t d}||d< t|tr|}g }x2|D ]*}t d|| j|| d}	|j|	j  qBW t d|d}
t dd	|
d
}|j |d< n| j||d< |d j|j g qW t d}||d< | jj	t
d| y| j S  tk
r } z|jdkr
 W Y dd}~X nX dS )zSet capabilities.

        Args:
            **kwargs: Arbitrary keyword arguments.

        Returns:
            mysqlx.protobuf.Message: MySQL X Protobuf Message.
        zMysqlx.Connection.CapabilitieszMysqlx.Connection.Capabilityrd   z#Mysqlx.Datatypes.Object.ObjectField)rH   rC   zMysqlx.Datatypes.Object)rI   zMysqlx.Datatypes.AnyrG   )rE   rJ   rC   capabilitiesz!Mysqlx.Connection.CapabilitiesSetz/Mysqlx.ClientMessages.Type.CON_CAPABILITIES_SETi  N)r   rT   rM   rR   rP   rU   rQ   r@   r<   r5   r   read_okr   errno)r   kwargsrn   rH   rC   
capabilityrT   rY   itemrX   rZ   r[   r-   errr   r   r   set_capabilities@  s8    	

zProtocol.set_capabilitiesc             K   sz   t d}xF|j D ]:\}}t d}||d< | j||d< |d j|j g qW t d}||d< | jjtd| | j S )	zSet capabilities.

        Args:
            **kwargs: Arbitrary keyword arguments.

        Returns:
            mysqlx.protobuf.Message: MySQL X Protobuf Message.
        zMysqlx.Connection.CapabilitieszMysqlx.Connection.Capabilityrd   rC   rn   z!Mysqlx.Connection.CapabilitiesSetZsession_connect_attrsz/Mysqlx.ClientMessages.Type.CON_CAPABILITIES_SET)	r   rT   rP   r@   rQ   r<   r5   r   ro   )r   rq   rn   rH   rC   rr   r-   r   r   r   set_session_capabilitiesk  s    	z!Protocol.set_session_capabilitiesNc             C   sF   t d}||d< |dk	r ||d< |dk	r0||d< | j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   r<   r5   r   )r   methodrw   rx   r-   r   r   r   send_auth_start  s    zProtocol.send_auth_startc             C   s>   | j j }x|jdkr"| j j }qW |jdkr6td|d S )zRead authenticate continue.

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

        Returns:
            str: The authentication data.
        zMysqlx.Notice.Framez#Mysqlx.Session.AuthenticateContinuez>Unexpected message encountered during authentication handshakerw   )r;   r.   rE   r   )r   r-   r   r   r   read_auth_continue  s    

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

        Args:
            auth_data (str): Authentication data.
        z#Mysqlx.Session.AuthenticateContinue)rw   z5Mysqlx.ClientMessages.Type.SESS_AUTHENTICATE_CONTINUEN)r   r<   r5   r   )r   rw   r-   r   r   r   send_auth_continue  s    zProtocol.send_auth_continuec             C   s4   x.| j j }|jdkrP |jdkrt|jqW dS )z~Read authenticate OK.

        Raises:
            :class:`mysqlx.InterfaceError`: If message type is `Mysqlx.Error`.
        zMysqlx.Session.AuthenticateOkzMysqlx.ErrorN)r;   r.   rE   r   r-   )r   r-   r   r   r   read_auth_ok  s    


zProtocol.read_auth_okc             C   sB  |j r|jdkr|jdkr*| j|\}}nB|jdkrD| j|\}}n(|jdkr^| j|\}}ntdj|t|j }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jt	d| y| j  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
        zMysqlx.Crud.InsertzMysqlx.Crud.FindzMysqlx.Crud.UpdatezMysqlx.Crud.DeletezInvalid message type: {}z!Mysqlx.Expr.Expr.Type.PLACEHOLDERzMysqlx.Crud.LimitExprzMysqlx.Expr.Expr)rE   position	row_countr   offsetZ
limit_exprz#Mysqlx.Prepare.Prepare.OneOfMessagerE   zMysqlx.Prepare.Preparestmt_idrA   z*Mysqlx.ClientMessages.Type.PREPARE_PREPAREN)	has_limitrE   
build_findbuild_updatebuild_deleter&   r'   r1   ra   r   r   r   r   r<   r5   ro   r   r   )r   r+   r-   rA   _r~   placeholderZmsg_limit_expr
oneof_typeoneof_op	msg_oneofZmsg_preparer   r   r   send_prepare_prepare  sB    




zProtocol.send_prepare_preparec       	      C   s   t | \}}td}t||d< |||< td}|j|d< | j|dd}|rZ|d j| |jr|d j| j|j j	 | j|j
 j	 g | j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
        z#Mysqlx.Prepare.Prepare.OneOfMessagerE   zMysqlx.Prepare.Executer   F)r\   rc   z*Mysqlx.ClientMessages.Type.PREPARE_EXECUTEN)r   r   r   r   rf   r@   r   rP   get_limit_row_countrQ   get_limit_offsetr<   r5   )	r   r+   r-   rA   r   r   r   Zmsg_executerc   r   r   r   send_prepare_execute  s     
zProtocol.send_prepare_executec             C   s.   t d}||d< | jjtd| | j  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   r<   r5   r   ro   )r   r   Zmsg_deallocr   r   r   send_prepare_deallocate  s    	z Protocol.send_prepare_deallocatec             C   sx   |j r8td}|j |d< |jdkr0|j |d< ||d< |dkrDdnd}| j||d	}|rh|d
 j| | j|| 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   zMysqlx.Crud.Findr   limitz+Mysqlx.ClientMessages.Type.SQL_STMT_EXECUTEFT)r\   rc   N)r   r   r   rE   r   rf   r@   send_msg)r   r+   r-   rA   Z	msg_limitr\   rc   r   r   r   send_msg_without_ps#  s    
zProtocol.send_msg_without_psc             C   s   | j 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)r<   r5   r   )r   r+   r-   r   r   r   r   <  s    
zProtocol.send_msgc             C   s   t |j rdnd}td|jj|jjd}td||d}|jrJ|j |d< | j|| |j	 rlt d|d	< n|j
 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
        zMysqlx.Crud.DataModel.DOCUMENTzMysqlx.Crud.DataModel.TABLEzMysqlx.Crud.Collection)rd   schemazMysqlx.Crud.Find)
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   targetrd   r   Zhas_projectionZget_projection_exprrB   Zis_lock_exclusiveZis_lock_sharedZlock_contention)r   rA   r   r   r-   r   r   r   r   H  s$    

zProtocol.build_findc             C   s   t |j rdnd}td|jj|jjd}td||d}| j|| x`|j j D ]P\}}td}|j	|d< |j
|d	< |jd
k	rt|j|d< |d j|j g qRW d|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
        zMysqlx.Crud.DataModel.DOCUMENTzMysqlx.Crud.DataModel.TABLEzMysqlx.Crud.Collection)rd   r   zMysqlx.Crud.Update)r   r   zMysqlx.Crud.UpdateOperation	operationsourceNrC   z&Mysqlx.ClientMessages.Type.CRUD_UPDATE)r   r   r   r   rd   r   rB   Zget_update_opsrT   Zupdate_typer   rC   r
   r@   rQ   )r   rA   r   r   r-   r   Z	update_opr   r   r   r   r   o  s"    


zProtocol.build_updatec             C   sL   t |j rdnd}td|jj|jjd}td||d}| j|| 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
        zMysqlx.Crud.DataModel.DOCUMENTzMysqlx.Crud.DataModel.TABLEzMysqlx.Crud.Collection)rd   r   zMysqlx.Crud.Delete)r   r   z&Mysqlx.ClientMessages.Type.CRUD_DELETE)r   r   r   r   rd   r   rB   )r   rA   r   r   r-   r   r   r   r     s    
zProtocol.build_deletec             C   s   t d||dd}|dkrt|ttfr2|d j n|j }g }x2|D ]*\}}t d|| j|d}	|j|	j  qDW t d|d	}
t d
d|
d}|j g|d< n,x*|D ]"}| j|}|d j|j g qW d|fS )a  Build execute statement.

        Args:
            namespace (str): The namespace.
            stmt (Statement): A `Statement` based type object.
            args (iterable): An iterable object.

        Returns:
            (tuple): Tuple containing:

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

        .. versionadded:: 8.0.16
        zMysqlx.Sql.StmtExecuteF)	namespacerA   Zcompact_metadataZmysqlxr   z#Mysqlx.Datatypes.Object.ObjectField)rH   rC   zMysqlx.Datatypes.Object)rI   zMysqlx.Datatypes.AnyrG   )rE   rJ   rc   z+Mysqlx.ClientMessages.Type.SQL_STMT_EXECUTE)	r   rM   rS   rO   rT   rP   rU   rQ   r@   )r   r   rA   rc   r-   rT   rY   rH   rC   rX   rZ   r[   rV   r   r   r   build_execute_statement  s"    

z Protocol.build_execute_statementc       
      C   s  t |j rdnd}td|jj|jjd}td||d}t|drzx6|jD ],}t||j  j	 }|d j
|j g qJW xv|j D ]j}td	}t|trx>|D ]}	|d
 j
t|	j g qW n|d
 j
t|j g |d j
|j g qW t|dr
|j |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
        zMysqlx.Crud.DataModel.DOCUMENTzMysqlx.Crud.DataModel.TABLEzMysqlx.Crud.Collection)rd   r   zMysqlx.Crud.Insert)r   r   _fieldsr   zMysqlx.Crud.Insert.TypedRowfieldrow	is_upsertZupsertz&Mysqlx.ClientMessages.Type.CRUD_INSERT)r   r   r   r   rd   r   hasattrr   r	   Zparse_table_insert_fieldr@   rQ   Z
get_valuesrM   rS   r
   r   )
r   rA   r   r   r-   r   exprrC   r   valr   r   r   build_insert  s,    


zProtocol.build_insertc             C   s   | j |}|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)r(   r   )r   rk   r-   r   r   r   close_result  s    	
zProtocol.close_resultc             C   s4   | j |}|dkrdS |jdkr$|S | jj| dS )z\Read row.

        Args:
            result (Result): A `Result` based type object.
        NzMysqlx.Resultset.Row)r(   rE   r;   r/   )r   rk   r-   r   r   r   read_row
  s    

zProtocol.read_rowc             C   s   g }x| j |}|dkrP |jdkr2| jj| P |jdkrDtdt|d |d |d |d |d	 |d
 |d |jdd|jdd|jdd|jdd|jd}|j| qW |S )zReturns column metadata.

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

        Raises:
            :class:`mysqlx.InterfaceError`: If unexpected message.
        NzMysqlx.Resultset.RowzMysqlx.Resultset.ColumnMetaDatazUnexpected msg typerE   catalogr   tableZoriginal_tablerd   original_namelength   Z	collationr   Zfractional_digitsflags   content_type)r(   rE   r;   r/   r   r   r%   rU   )r   rk   columnsr-   colr   r   r   get_column_metadata  s(    	






zProtocol.get_column_metadatac             C   sD   | j j }|jdkr.tdj|d |d d|jdkr@tddS )	zeRead OK.

        Raises:
            :class:`mysqlx.InterfaceError`: If unexpected message.
        zMysqlx.ErrorzMysqlx.Error: {}r-   rj   )rp   z	Mysqlx.OkzUnexpected message encounteredN)r;   r.   rE   r   r'   )r   r-   r   r   r   ro   6  s    


zProtocol.read_okc             C   s   t d}| jjtd| dS )zSend connection close.zMysqlx.Connection.Closez$Mysqlx.ClientMessages.Type.CON_CLOSEN)r   r<   r5   r   )r   r-   r   r   r   send_connection_closeC  s    zProtocol.send_connection_closec             C   s   t d}| jjtd| dS )zSend close.zMysqlx.Session.Closez%Mysqlx.ClientMessages.Type.SESS_CLOSEN)r   r<   r5   r   )r   r-   r   r   r   
send_closeI  s    zProtocol.send_closec             C   sL   t d}td}||d< d|d< td}|j g|d< | j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   rQ   r<   r5   )r   Zcond_keyZmsg_ocZmsg_eor   r   r   send_expect_openO  s    zProtocol.send_expect_openc             C   st   t d}|dkrBy| j  | j  d}W n tk
r@   d}Y nX |rNd|d< | jjtd| | j  |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   ro   r   r<   r5   r   )r   r   r-   r   r   r   
send_reset]  s     

zProtocol.send_reset)T)NN)N)#r6   r7   r8   r9   r   rB   rP   rf   rl   r(   rm   ru   rv   rz   r{   r|   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   ro   r   r   r   r   r   r   r   r   r:   z   s@   3
$(+
7 '"',r:   )r9   r#   compatr   r   errorsr   r   r   r   r   r	   r
   r   r   r   r   helpersr   r   rk   r   Zprotobufr   r   r   r   r   objectr   r:   r   r   r   r   <module>   s    N