B
    Ñš[(m  ã               @   sˆ   d 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
 ddlmZmZ ddlmZ ddlmZmZ dd	lmZ G d
d„ deƒZdS )z,Implements the MySQL Client/Server protocol
é    N)ÚDecimalé   )Ú	FieldFlagÚ	ServerCmdÚ	FieldTypeÚ
ClientFlagÚMAX_MYSQL_TABLE_COLUMNS)ÚerrorsÚutils)Úget_auth_plugin)ÚPY2Ústruct_unpack)Úget_exceptionc               @   sú   e Zd ZdZdd„ Zdd„ ZdBdd„ZdCdd„ZdDdd„ZdEdd„Z	dd„ Z
dd„ Zdd„ ZdFdd„Zdd„ ZdGdd „ZdHd"d#„Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ ZdId.d/„Zd0d1„ Zd2d3„ Zd4d5„ Zd6d7„ Zd8d9„ ZdJd<d=„Zd>d?„ Zd@dA„ ZdS )KÚMySQLProtocolzRImplements MySQL client/server protocol

    Create and parses MySQL packets.
    c             C   s    |t j@ r|r| d¡d S dS )z.Prepare database string for handshake responseÚutf8ó    )r   ZCONNECT_WITH_DBÚencode)ÚselfÚclient_flagsÚdatabase© r   úœC:\Users\HIRONO~1\AppData\Local\Temp\pip-install-ioykiiwb\mysql-connector-python-rf\mysql_connector_python_rf-2.2.2.data\purelib\mysql\connector\protocol.pyÚ_connect_with_db-   s    zMySQLProtocol._connect_with_dbc          
   C   s˜   |sdS y"t |ƒ|||||d�}| ¡ }	W n< ttjfk
rf }
 zt d t|
ƒ¡¡‚W dd}
~
X Y nX |tj	@ rŒt
|	ƒ}t d|¡|	 }n|	d }|S )z#Prepare the authentication responser   )ÚusernameÚpasswordr   Ússl_enabledzFailed authentication: {0}Nz<B)r   Úauth_responseÚ	TypeErrorr	   ÚInterfaceErrorÚProgrammingErrorÚformatÚstrr   ÚSECURE_CONNECTIONÚlenÚstructÚpack)r   r   r   r   r   Úauth_pluginÚ	auth_datar   ÚauthZplugin_auth_responseÚexcZresplenr   r   r   r   Ú_auth_response3   s     "
zMySQLProtocol._auth_responseNé!   r   é   @Fc
          
   C   sê   y|d }
|	p|d }	W n6 t tfk
rN } zt d |¡¡‚W dd}~X Y nX |sXd}y| d¡}W n tk
r~   |}Y nX t djdt	|ƒd	�||||¡}||  
|||||	|
|¡7 }||  ||¡7 }|tj@ ræ||	 d¡d
 7 }|S )z"Make a MySQL Authentication packetr'   r&   z*Handshake misses authentication info ({0})Nó    r   z<IIB{filler}{usrlen}sxZxxxxxxxxxxxxxxxxxxxxxxx)ZfillerÚusrlenr   )r   ÚKeyErrorr	   r   r    r   ÚAttributeErrorr$   r%   r#   r*   r   r   ÚPLUGIN_AUTH)r   Ú	handshaker   r   r   Úcharsetr   Úmax_allowed_packetr   r&   r'   r)   Úusername_bytesÚpacketr   r   r   Ú	make_authJ   s0    


zMySQLProtocol.make_authc             C   s"   t  |¡t  |¡ t  |¡ d S )z Make a SSL authentication packets                          )r
   Ú	int4storeÚ	int1store)r   r3   r   r4   r   r   r   Úmake_auth_sslo   s    zMySQLProtocol.make_auth_sslc             C   s   t  |¡}|dk	r||7 }|S )z(Make a MySQL packet containing a commandN)r
   r9   )r   ÚcommandZargumentÚdatar   r   r   Úmake_commandw   s    
zMySQLProtocol.make_commandc	          
   C   sö   y|d }	|p|d }W n6 t tfk
rN }
 zt d |
¡¡‚W dd}
~
X Y nX |sXd}y| d¡}W n tk
r~   |}Y nX t djt	|ƒd�t
j|¡}||  ||||||	|¡7 }||  ||¡7 }|t d	|¡7 }|tj@ rò|| d¡d
 7 }|S )z0Make a MySQL packet with the Change User commandr'   r&   z*Handshake misses authentication info ({0})Nr-   r   z<B{usrlen}sx)r.   z<Hr   )r   r/   r	   r   r    r   r0   r$   r%   r#   r   ZCHANGE_USERr*   r   r   r1   )r   r2   r   r   r   r3   r   r   r&   r'   r)   r5   r6   r   r   r   Úmake_change_user~   s.    



zMySQLProtocol.make_change_userc       
   	   C   sf  i }t d|dd… ƒd |d< tj|dd… dd�\}|d< t d	|dd
… ƒ\|d< }}|d< |d< }}|d  ¡ |d< |d
d… }t || ¡}d}|tj@ ræ|r²td|d ƒnd}	|d|	… }||	d… }|d dkræ|dd… }|tj@ �rFd|k�r|d  	d¡�rd| }|d< ntj|dd�\}|d< |d  d¡|d< nd|d< || |d< ||d< |S )zParse a MySQL Handshake-packetz<xxxxBr   é   ÚprotocolNr   )ÚendZserver_version_originalz<I8sx2sBH2sBxxxxxxxxxxé   Zserver_threadidr3   Zserver_statusr-   é   é   éÿÿÿÿz5.5.8r&   zutf-8Zmysql_native_passwordr'   Úcapabilities)
r   r
   Úread_stringÚdecodeZintreadr   r"   Úminr1   Ú
startswith)
r   r6   ÚresZ
auth_data1Zcapabilities1Zcapabilities2Zauth_data_lengthrF   Z
auth_data2Úsizer   r   r   Úparse_handshake¢   s4    	,

zMySQLProtocol.parse_handshakec             C   sÚ   |d dkst  d¡‚i }yœtd|dd… ƒd |d< t |dd… ¡\}|d< t |¡\}|d	< td
|dd… ƒ\|d< |d< |dd… }|r´t |¡\}|d< |d  d¡|d< W n tk
rÔ   t  d¡‚Y nX |S )zParse a MySQL OK-packeté   r   z#Failed parsing OK packet (invalid).z<xxxxBr?   Zfield_countNZaffected_rowsZ	insert_idz<HHÚstatus_flagÚwarning_countZinfo_msgzutf-8zFailed parsing OK packet.)r	   r   r   r
   Úread_lc_intÚread_lc_stringrH   Ú
ValueError)r   r6   Z	ok_packetr   r   r   Úparse_okÎ   s    
zMySQLProtocol.parse_okc          	   C   sP   y&t  |dd… ¡d }|tkr$dS |S  tjtfk
rJ   t d¡‚Y nX dS )z=Parse a MySQL packet with the number of columns in result setrN   Nr   zFailed parsing column count)r
   rQ   r   r$   ÚerrorrS   r	   r   )r   r6   Úcountr   r   r   Úparse_column_countâ   s    z MySQLProtocol.parse_column_countúutf-8c             C   s¸   t  |dd… ¡\}}t  |¡\}}t  |¡\}}t  |¡\}}t  |¡\}}t  |¡\}}ytd|ƒ\}}}}}W n  tjk
r”   t d¡‚Y nX | |¡|dddd| tj	@ |fS )zParse a MySQL column-packetrN   Nz	<xHIBHBxxz!Failed parsing column information)
r
   rR   r   r$   rU   r	   r   rH   r   ZNOT_NULL)r   r6   r3   Ú_ÚnameÚ
field_typeÚflagsr   r   r   Úparse_columnì   s$    
zMySQLProtocol.parse_columnc             C   sŒ   |d dkr|   |¡S d}i }ytd|ƒ}W n  tjk
rL   t |¡‚Y nX |d dkrft|ƒdkspt |¡‚|d |d	< |d
 |d< |S )zParse a MySQL EOF-packetrN   r   zFailed parsing EOF packet.z<xxxBBHHr   éþ   é	   é   rP   é   rO   )rT   r   r$   rU   r	   r   r#   )r   r6   Zerr_msgrK   Úunpackedr   r   r   Ú	parse_eof  s    

zMySQLProtocol.parse_eofTc       	      C   sÒ   d}i }|r |dd…   d¡}n
|  d¡}x¢|D ]š}ydd„ |  dd¡D ƒ\}}W n   t |¡‚Y nX | d	¡}yt|ƒ||< W q0   yt| d	¡ƒ||< W n    t d
 |||¡¡‚Y nX Y q0X q0W |S )zParse the statistics packetz)Failed getting COM_STATISTICS informationrN   Ns     c             S   s   g | ]}|  ¡ ‘qS r   )Ústrip)Ú.0Úvr   r   r   ú
<listcomp>%  s    z2MySQLProtocol.parse_statistics.<locals>.<listcomp>ó   :r`   zutf-8z{0} ({1}:{2}).)Úsplitr	   r   rH   Úintr   r    )	r   r6   Zwith_headerÚerrmsgrK   ÚpairsÚpairZlblÚvalr   r   r   Úparse_statistics  s(    


 zMySQLProtocol.parse_statisticsr   c             C   s^  g }d}d}d}|dk}�x:|s(||kr*P |  ¡ }	|	 d¡r¤|	dd… g}
|  ¡ }	x(|	 d¡rz|
 |	dd… ¡ |  ¡ }	qTW |
 |	dd… ¡ t tdƒ |
¡¡}nj|	d dkrÌ|	d dk rÌ|  |	¡}d}nB|rø|	d dkrø|	d d	krø|  |	¡}d}nd}t |	dd… ¡}|dk�r.|dk	�r.| |¡ n|dk�rJ|dk�rJt	|	ƒ‚|d
7 }qW ||fS )z¶Read MySQL text result

        Reads all or given number of rows from the socket.

        Returns a tuple with 2 elements: a list with all rows and
        the EOF packet.
        Nr   )r?   é   r?   s   ÿÿÿrN   r-   r^   rp   r_   r   )
ÚrecvrJ   Úappendr
   Zread_lc_string_listÚ	bytearrayÚjoinrc   rT   r   )r   ÚsockÚversionrV   ÚrowsÚeofZrowdataÚiZeof57r6   Zdatasr   r   r   Úread_text_result5  s>    


zMySQLProtocol.read_text_resultc             C   sœ   |d t jkrd}d}nL|d t jkr0d}d}n4|d t jt jfkrNd}d}n|d t jkrdd}d}|d	 tj@ rz| ¡ }||d
… t	||d|… ƒd fS )z%Parse an integer from a binary packetr   ÚbÚhr`   ry   rN   ÚqrD   rp   Nr   )
r   ÚTINYÚSHORTÚINT24ÚLONGÚLONGLONGr   ZUNSIGNEDÚupperr   )r   r6   ÚfieldÚformat_Úlengthr   r   r   Ú_parse_binary_integer_  s    z#MySQLProtocol._parse_binary_integerc             C   sB   |d t jkrd}d}nd}d}||d… t||d|… ƒd fS )z)Parse a float/double from a binary packetr   rD   ÚdrN   ÚfNr   )r   ÚDOUBLEr   )r   r6   r„   r†   r…   r   r   r   Ú_parse_binary_floats  s    z!MySQLProtocol._parse_binary_floatc          	   C   sÀ   |d }d}|dkr@t jtd|dd… ƒd |d |d d�}nl|dkr¬d}|d	krntd
|d|d … ƒd }t j td|dd… ƒd |d |d |d |d |d |d�}||d d… |fS )z&Parse a timestamp from a binary packetr   NrN   ÚHr   ra   )ÚyearÚmonthÚdayrp   é   ÚIrD   r?   é   )r�   rŽ   r�   ÚhourÚminuteÚsecondÚmicrosecond)ÚdatetimeÚdater   )r   r6   r„   r†   ÚvalueÚmcsr   r   r   Ú_parse_binary_timestamp~  s(    z%MySQLProtocol._parse_binary_timestampc             C   s˜   |d }|d|d … }d}|dkr:t d|dd… ƒd }t d|dd… ƒd }|d dkrd|d9 }tj||d ||d	 |d d
�}||d d… |fS )z'Parse a time value from a binary packetr   r   rD   r‘   Nr?   rE   rp   r’   )ÚdaysÚsecondsÚmicrosecondsÚminutesÚhours)r   r—   Ú	timedelta)r   r6   r„   r†   r<   rš   rœ   Útmpr   r   r   Ú_parse_binary_time–  s    z MySQLProtocol._parse_binary_timec       	      C   st  t |ƒd d d }dd„ |d|… D ƒ}||d… }g }�x.t|ƒD �] \}}|t|d d ƒ d|d d > @ r‚| d¡ qFqF|d tjtjtjtjtj	fkr¾|  
||¡\}}| |¡ qF|d tjtjfkrî|  ||¡\}}| |¡ qF|d tjtjtjfk�r$|  ||¡\}}| |¡ qF|d tjk�rP|  ||¡\}}| |¡ qFt |¡\}}| |¡ qFW t|ƒS )	z(Parse values from a binary result packetrp   r`   rD   c             S   s   g | ]}t |ƒ‘qS r   )rj   )re   ry   r   r   r   rg   «  s    z6MySQLProtocol._parse_binary_values.<locals>.<listcomp>r   Nr   )r#   Ú	enumeraterj   rr   r   r~   r   r€   r�   r‚   r‡   rŠ   ÚFLOATr‹   ÚDATETIMEÚDATEÚ	TIMESTAMPr›   ÚTIMEr£   r
   rR   Útuple)	r   Úfieldsr6   Znull_bitmap_lengthÚnull_bitmapÚvaluesÚposr„   r™   r   r   r   Ú_parse_binary_values¨  s4    $
z"MySQLProtocol._parse_binary_valuesc       	      C   s¶   g }d}d}d}xœ|dk	rP ||kr&P |  ¡ }|d dkrJ|  |¡}d}n$|d dkrnd}|  ||dd… ¡}|dkrŠ|dk	rŠ| |¡ n|dkr¢|dkr¢t|ƒ‚|d7 }qW ||fS )zwRead MySQL binary protocol result

        Reads all or given number of binary resultset rows from the socket.
        Nr   rN   r^   r?   r   )rq   rc   r¯   rr   r   )	r   ru   ÚcolumnsrV   rw   rx   r­   ry   r6   r   r   r   Úread_binary_resultÈ  s,    
z MySQLProtocol.read_binary_resultc             C   s¦   |d dkst  d¡‚i }yht |dd… d¡\}|d< t |d¡\}|d< t |d¡\}|d	< |d
d… }t |d¡\}|d< W n tk
r    t  d¡‚Y nX |S )z'Parse a MySQL Binary Protocol OK packetrN   r   zFailed parsing Binary OK packetr?   NÚstatement_idr`   Znum_columnsZ
num_paramsr   rP   )r	   r   r
   Zread_intrS   )r   r6   Zok_pktr   r   r   Úparse_binary_prepare_okä  s    
z%MySQLProtocol.parse_binary_prepare_okc             C   s´   d}d}|dk rX|dkr$d}t j}q¢|dkr8d}t j}q¢|dkrLd}t j}q¢d	}t j}nJd
}|dkrpd}t j}n2|dkr„d}t j}n|dkr˜d}t j}n
t j}d}t ||¡||fS )z0Prepare an integer for the MySQL binary protocolNr   i€ÿÿÿr{   i €ÿÿr|   i   €ry   r}   é€   éÿ   ÚBiÿÿ  rŒ   l   ÿÿ r‘   ÚQ)r   r~   r   r�   r‚   r$   r%   )r   r™   r[   r\   r…   r   r   r   Ú_prepare_binary_integerõ  s6    z%MySQLProtocol._prepare_binary_integerc             C   s¼   t |tjƒrtj}nt |tjƒr(tj}ntdƒ‚t |j	¡t 
|j¡ t 
|j¡ }t |tjƒr¢|t 
|j¡ t 
|j¡ t 
|j¡ }|jdkr¢|t |j¡7 }t 
t|ƒ¡| }||fS )aƒ  Prepare a timestamp object for the MySQL binary protocol

        This method prepares a timestamp of type datetime.datetime or
        datetime.date for sending over the MySQL binary protocol.
        A tuple is returned with the prepared value and field type
        as elements.

        Raises ValueError when the argument value is of invalid type.

        Returns a tuple.
        z2Argument must a datetime.datetime or datetime.dater   )Ú
isinstancer—   r   r¦   r˜   r§   rS   r
   Ú	int2storer�   r9   rŽ   r�   r“   r”   r•   r–   r8   r#   )r   r™   r[   Úpackedr   r   r   Ú_prepare_binary_timestamp  s    
z'MySQLProtocol._prepare_binary_timestampc       
      C   s  t |tjtjfƒstdƒ‚tj}d}d}d}t |tjƒrž|jdk rFd}t|j	dƒ\}}t|dƒ\}}	|t
 t|jƒ¡t
 |¡ t
 |¡ t
 |	¡ 7 }|j}n8|t
 d¡t
 |j¡ t
 |j¡ t
 |j¡ 7 }|j}|rè|t
 |¡7 }t
 |¡| }t
 t|ƒ¡| }||fS )a�  Prepare a time object for the MySQL binary protocol

        This method prepares a time object of type datetime.timedelta or
        datetime.time for sending over the MySQL binary protocol.
        A tuple is returned with the prepared value and field type
        as elements.

        Raises ValueError when the argument value is of invalid type.

        Returns a tuple.
        z3Argument must a datetime.timedelta or datetime.timer   Nr-   r   i  é<   )r¹   r—   r¡   ÚtimerS   r   r©   rœ   Údivmodr�   r
   r8   Úabsr9   rž   r“   r”   r•   r–   r#   )
r   r™   r[   Únegativerš   r»   r    Ú	remainderZminsÚsecsr   r   r   Ú_prepare_binary_time8  s2    
" z"MySQLProtocol._prepare_binary_timec             C   s   t  |¡t  |¡ | }|S )zMPrepare long data for prepared statements

        Returns a string.
        )r
   r8   rº   )r   Z	statementÚparamr<   r6   r   r   r   Ú_prepare_stmt_send_long_datae  s    z*MySQLProtocol._prepare_stmt_send_long_datar   r   c          	   C   s8  d}dgt |ƒd d  }g }	g }
d}|dkr2i }|�rÈ|�rÈt |ƒt |ƒkrXt d¡‚�xlt|ƒD �]^\}}|| }d}|dkrÀ||d   d|d > O  < |
 t tj¡t |¡ ¡ qd�nê||kræ|| d rÜtj	}ntj
}�nÄt|tƒ�r|  |¡\}}}|	 |¡ �nšt|tƒ�rht�r<|	 t t |ƒ¡| ¡ n"| |¡}|	 t t |ƒ¡| ¡ tj}�nBt|tƒ�r–|	 t t |ƒ¡| ¡ tj	}�nt�rÒt|tƒ�rÒ| |¡}|	 t t |ƒ¡| ¡ tj}nØt|tƒ�r|	 t t t|ƒ |¡ƒ¡t|ƒ |¡ ¡ tj}n˜t|tƒ�r8|	 t d|¡¡ tj}nrt|tjtjfƒ�rf|  |¡\}}|	 |¡ nDt|tjtjfƒ�r”|   |¡\}}|	 |¡ nt !d	j"|j#j$d
�¡‚|
 t |¡t |¡ ¡ qdW t %|¡t |¡ t %|¡ d &dd„ |D ƒ¡ t d¡ }x|
D ]}||7 }�q
W x|	D ]}||7 }�q"W |S )z6Make a MySQL packet with the Statement Execute commandr   r   rp   rD   r-   NzTFailed executing prepared statement: data values does not match number of parametersrˆ   z:MySQL binary protocol can not handle '{classname}' objects)Ú	classnamec             S   s   g | ]}t  d |¡‘qS )r¶   )r$   r%   )re   Úbitr   r   r   rg   ¾  s    z3MySQLProtocol.make_stmt_execute.<locals>.<listcomp>)'r#   r	   r   r¤   rr   r
   r9   r   ÚNULLZBLOBÚSTRINGr¹   rj   r¸   r!   r   Zlc_intr   ZVARCHARÚbytesÚunicoder   ZDECIMALÚfloatr$   r%   rŠ   r—   r˜   r¼   r¡   r¾   rÄ   r   r    Ú	__class__Ú__name__r8   rt   )r   r²   r<   Ú
parametersr\   Zlong_data_usedr3   Ziteration_countr¬   r­   Útypesr»   r®   rY   r™   r[   r6   Za_typeZa_valuer   r   r   Úmake_stmt_executep  sŠ    






0

zMySQLProtocol.make_stmt_executec             C   sZ   |d dkst  d¡‚tj|dd… dd�\}}|rL|d d	krL|dd… }| d
¡|fS )z&Parse a MySQL AuthSwitchRequest-packetrN   r^   z'Failed parsing AuthSwitchRequest packetr?   Nr   )rA   rE   r   r   )r	   r   r
   rG   rH   )r   r6   Zplugin_namer   r   r   Úparse_auth_switch_requestÊ  s    z'MySQLProtocol.parse_auth_switch_requestc             C   s"   |d dkst  d¡‚|dd… S )z!Parse a MySQL AuthMoreData-packetrN   r   z"Failed parsing AuthMoreData packetr?   N)r	   r   )r   r6   r   r   r   Úparse_auth_more_dataÖ  s    z"MySQLProtocol.parse_auth_more_data)NNNr+   r   r,   FN)r+   r   r,   )N)NNNr+   r   FN)rX   )T)r   )r   )r   r   r   Nr   )rÏ   Ú
__module__Ú__qualname__Ú__doc__r   r*   r7   r:   r=   r>   rM   rT   rW   r]   rc   ro   rz   r‡   r‹   r›   r£   r¯   r±   r³   r¸   r¼   rÄ   rÆ   rÒ   rÓ   rÔ   r   r   r   r   r   '   sF      
" 

  
",



* 
!"- 
Yr   )r×   r$   r—   Údecimalr   Ú	constantsr   r   r   r   r   Ú r	   r
   Zauthenticationr   Zcatch23r   r   r   Úobjectr   r   r   r   r   Ú<module>   s   