o
    –¨ÊhQo  ã                   @   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	 ddl
mZmZ ddlmZ ddlmZmZ dd	lmZmZ d
ZG dd„ deƒZdS )z,Implements the MySQL Client/Server protocol
é    N)ÚDecimalé   )Ú	FieldFlagÚ	ServerCmdÚ	FieldTypeÚ
ClientFlag)ÚerrorsÚutils)Úget_auth_plugin)ÚPY2Ústruct_unpack)ÚDatabaseErrorÚget_exceptioné
   c                   @   s  e Zd ZdZdd„ Zdd„ Z			
	dDdd„Z			dEdd„ZdFdd„ZdGdd„Z				dHdd„Z
dd„ Zdd„ Zdd„ ZdIdd„Zdd „ ZdJd"d#„ZdGd$d%„Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ ZdId.d/„ZdKd0d1„Zd2d3„ Zd4d5„ Zd6d7„ Zd8d9„ Zd:d;„ Z	<	=dLd>d?„Zd@dA„ ZdBdC„ ZdS )MÚ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   ÚCONNECT_WITH_DBÚencode)ÚselfÚclient_flagsÚdatabase© r   úJ/var/www/html/env/lib/python3.10/site-packages/mysql/connector/protocol.pyÚ_connect_with_db4   s   zMySQLProtocol._connect_with_dbc              
   C   s�   |sdS zt |ƒ|||||d�}| ¡ }	W n ttjfy. }
 z
t d t|
ƒ¡¡‚d}
~
ww |tj@ rBt	|	ƒ}t
 d|¡|	 }|S |	d }|S )z#Prepare the authentication responser   )ÚusernameÚpasswordr   Ússl_enabledzFailed authentication: {0}Nz<B)r
   Úauth_responseÚ	TypeErrorr   ÚInterfaceErrorÚformatÚstrr   ÚSECURE_CONNECTIONÚlenÚstructÚpack)r   r   r   r   r   Úauth_pluginÚ	auth_datar   ÚauthÚplugin_auth_responseÚexcÚresplenr   r   r   r   Ú_auth_response:   s*   ýÿ€ÿ
ÿzMySQLProtocol._auth_responseNé-   r   é   @Fc
              
   C   sÞ   z|d }
|	p
|d }	W n t tfy" } zt d |¡¡‚d}~ww |s'd}z| d¡}W n ty9   |}Y nw t djdt	|ƒd	�||||¡}||  
|||||	|
|¡7 }||  ||¡7 }|tj@ rm||	 d¡d
 7 }|S )z"Make a MySQL Authentication packetr(   r'   ú*Handshake misses authentication info ({0})Nó    r   z<IIB{filler}{usrlen}sxÚxxxxxxxxxxxxxxxxxxxxxxx)ÚfillerÚusrlenr   )r   ÚKeyErrorr   ÚProgrammingErrorr!   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_authQ   s>   ÿ€ÿþÿýý
zMySQLProtocol.make_authc                 C   s"   t  |¡t  |¡ t  |¡ d S )z Make a SSL authentication packets                          )r	   Ú	int4storeÚ	int1store)r   r:   r   r;   r   r   r   Úmake_auth_sslv   s   ÿþýzMySQLProtocol.make_auth_sslc                 C   s   t  |¡}|dur||7 }|S )z(Make a MySQL packet containing a commandN)r	   r@   )r   ÚcommandÚargumentÚdatar   r   r   Úmake_command~   s   
zMySQLProtocol.make_commandr   c                 C   s   t  |¡t  |¡ S )z0Make a MySQL packet with Fetch Statement command)r	   r?   )r   Ústatement_idÚrowsr   r   r   Úmake_stmt_fetch…   s   zMySQLProtocol.make_stmt_fetchc	              
   C   sê   z|d }	|p
|d }W n t tfy" }
 zt d |
¡¡‚d}
~
ww |s'd}z| d¡}W n ty9   |}Y nw t djt	|ƒd�t
j|¡}||  ||||||	|¡7 }||  ||¡7 }|t d	|¡7 }|tj@ rs|| d¡d
 7 }|S )z0Make a MySQL packet with the Change User commandr(   r'   r0   Nr1   r   z<B{usrlen}sx)r4   z<Hr   )r   r5   r   r6   r!   r   r7   r%   r&   r$   r   ÚCHANGE_USERr-   r   r   r8   )r   r9   r   r   r   r:   r   r   r'   r(   r+   r<   r=   r   r   r   Úmake_change_user‰   s:   ÿ€ÿþÿý
zMySQLProtocol.make_change_userc           
   	   C   s€  i }t d|dd… ƒd |d< |d tkrtd |d t¡ƒ‚tj|dd… dd�\}|d	< t d
|dd… ƒ\|d< }}|d< |d< }}|d	  ¡ |d	< |dd… }t || ¡}d}|tj	@ rƒ|rit
d|d ƒnd}	|d|	… }||	d… }|d dkrƒ|dd… }|tj@ r°d|v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-packetú<xxxxBr   é   Úprotocolz;Protocol mismatch; server version = {}, client version = {}Nr   ©ÚendÚserver_version_originalz<I8sx2sBH2sBxxxxxxxxxxé   Úserver_threadidr:   Úserver_statusr1   é   é   éÿÿÿÿz5.5.8r'   úutf-8Úmysql_native_passwordr(   Úcapabilities)r   ÚPROTOCOL_VERSIONr   r!   r	   Úread_stringÚdecodeÚintreadr   r#   Úminr8   Ú
startswith)
r   r=   ÚresÚ
auth_data1Úcapabilities1Úcapabilities2Úauth_data_lengthrY   Ú
auth_data2Úsizer   r   r   Úparse_handshake­   sT   ÿÿÿ
ù

ÿÿzMySQLProtocol.parse_handshakec                 C   sØ   |d dkst  d¡‚i }zRt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 |S W |S  tyk   t  d¡‚w )zParse a MySQL OK-packeté   r   z#Failed parsing OK packet (invalid).rK   rL   Úfield_countNÚaffected_rowsÚ	insert_idz<HHÚstatus_flagÚwarning_countÚinfo_msgrW   zFailed parsing OK packet.)r   r    r   r	   Úread_lc_intÚread_lc_stringr\   Ú
ValueError)r   r=   Ú	ok_packetr   r   r   Úparse_okÝ   s(   
ÿûþ
ÿzMySQLProtocol.parse_okc              	   C   s<   zt  |dd… ¡d }|W S  tjtfy   t d¡‚w )z=Parse a MySQL packet with the number of columns in result setrh   Nr   zFailed parsing column count)r	   ro   r%   Úerrorrq   r   r    )r   r=   Úcountr   r   r   Úparse_column_countñ   s   
ÿz MySQLProtocol.parse_column_countrW   c                 C   s²   t  |dd… ¡\}}t  |¡\}}t  |¡\}}t  |¡\}}t  |¡\}}t  |¡\}}ztd|ƒ\}}}}}W n tjyG   t d¡‚w | |¡|dddd| tj	@ |fS )zParse a MySQL column-packetrh   Nz	<xHIBHBxxz!Failed parsing column information)
r	   rp   r   r%   rt   r   r    r\   r   ÚNOT_NULL)r   r=   r:   Ú_ÚnameÚ
field_typeÚflagsr   r   r   Úparse_columnù   s,   ÿ
ÿ
øzMySQLProtocol.parse_columnc                 C   s†   |d dkr|   |¡S d}i }ztd|ƒ}W n tjy#   t |¡‚w |d dkr0t|ƒdks5t |¡‚|d |d	< |d
 |d< |S )zParse a MySQL EOF-packetrh   r   zFailed parsing EOF packet.z<xxxBBHHr   éþ   é	   é   rm   é   rl   )rs   r   r%   rt   r   r    r$   )r   r=   Úerr_msgr`   Úunpackedr   r   r   Ú	parse_eof  s   

ÿ
zMySQLProtocol.parse_eofTc           	      C   s¾   d}i }|r|dd…   d¡}n|  d¡}|D ]E}zdd„ |  dd¡D ƒ\}}W n   t |¡‚| d	¡}zt|ƒ||< W q   zt| d	¡ƒ||< W n   t d
 |||¡¡‚Y q|S )zParse the statistics packetz)Failed getting COM_STATISTICS informationrh   Ns     c                 S   s   g | ]}|  ¡ ‘qS r   )Ústrip)Ú.0Úvr   r   r   Ú
<listcomp>2  ó    z2MySQLProtocol.parse_statistics.<locals>.<listcomp>ó   :r   rW   z{0} ({1}:{2}).)Úsplitr   r    r\   Úintr   r!   )	r   r=   Úwith_headerÚerrmsgr`   ÚpairsÚpairÚlblÚvalr   r   r   Úparse_statistics'  s,   


ÿþzMySQLProtocol.parse_statisticsc           
      C   s"  g }d}d}d}	 |s||kr	 ||fS |  ¡ }| d¡rS|dd… g}	|  ¡ }| d¡r?|	 |dd… ¡ |  ¡ }| d¡s-|	 |dd… ¡ t tdƒ |	¡¡}n|d dkrg|d dk rg|  |¡}d}nd}t |dd… ¡}|du r€|dur€| |¡ n|du rŒ|du rŒt|ƒ‚|d	7 }q	)
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   Ts   ÿÿÿrh   r1   r}   é   r   )	Úrecvr_   Úappendr	   Úread_lc_string_listÚ	bytearrayÚjoinrƒ   r   )
r   ÚsockÚversionru   rG   ÚeofÚrowdataÚir=   Údatasr   r   r   Úread_text_resultB  s:   ì


þ
êzMySQLProtocol.read_text_resultc                 C   sœ   |d t jkrd}d}n&|d t jkrd}d}n|d t jt jfv r'd}d}n|d t jkr2d}d}|d	 tj@ r=| ¡ }||d
… t	||d|… ƒd fS )z%Parse an integer from a binary packetr   ÚbÚhr   r�   rh   ÚqrU   r“   Nr   )
r   ÚTINYÚSHORTÚINT24ÚLONGÚLONGLONGr   ÚUNSIGNEDÚupperr   )r   r=   ÚfieldÚformat_Úlengthr   r   r   Ú_parse_binary_integerg  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   rU   Údrh   ÚfNr   )r   ÚDOUBLEr   )r   r=   rª   r¬   r«   r   r   r   Ú_parse_binary_float{  s   "z!MySQLProtocol._parse_binary_floatc              	   C   sÀ   |d }d}|dkr t jtd|dd… ƒd |d |d d�}n6|dkrVd}|d	kr7t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   Nrh   ÚHr   r€   )ÚyearÚmonthÚdayr“   é   ÚIrU   rL   é   )r³   r´   rµ   ÚhourÚminuteÚsecondÚmicrosecond)ÚdatetimeÚdater   )r   r=   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r2|d9 }tj||d ||d	 |d d
�}||d d… |fS )z'Parse a time value from a binary packetr   r   rU   r·   NrL   rV   r“   r¸   )ÚdaysÚsecondsÚmicrosecondsÚminutesÚhours)r   r½   Ú	timedelta)r   r=   rª   r¬   rD   rÀ   rÂ   Útmpr   r   r   Ú_parse_binary_timež  s   üz MySQLProtocol._parse_binary_timec           
      C   sl  t |ƒd d d }dd„ |d|… D ƒ}||d… }g }t|ƒD ]�\}}|t|d d ƒ d|d d > @ r=| d¡ q!|d tjtjtjtjtj	fv r[|  
||¡\}}	| |	¡ q!|d tjtjfv rs|  ||¡\}}	| |	¡ q!|d tjtjtjfv r�|  ||¡\}}	| |	¡ q!|d tjkr¢|  ||¡\}}	| |	¡ q!t |¡\}}	| |	 |¡¡ q!t|ƒS )	z(Parse values from a binary result packetr“   r   rU   c                 S   s   g | ]}t |ƒ‘qS r   )r‹   )r…   r�   r   r   r   r‡   ³  rˆ   z6MySQLProtocol._parse_binary_values.<locals>.<listcomp>r   Nr   )r$   Ú	enumerater‹   r•   r   r£   r¤   r¥   r¦   r§   r­   r°   ÚFLOATr±   ÚDATETIMEÚDATEÚ	TIMESTAMPrÁ   ÚTIMErÉ   r	   rp   r\   Útuple)
r   Úfieldsr=   r:   Únull_bitmap_lengthÚnull_bitmapÚvaluesÚposrª   r¿   r   r   r   Ú_parse_binary_values°  s8   $
þÿz"MySQLProtocol._parse_binary_valuesc           
      C   s¾   g }d}d}d}	 |dur	 ||fS ||kr	 ||fS |  ¡ }	|	d dkr-|  |	¡}d}n|	d dkr@d}|  ||	dd… |¡}|du rN|durN| |¡ n|du rZ|du rZt|	ƒ‚|d7 }q	)zwRead MySQL binary protocol result

        Reads all or given number of binary resultset rows from the socket.
        Nr   Trh   r}   rL   r   )r”   rƒ   rÖ   r•   r   )
r   r™   Úcolumnsru   r:   rG   r›   rÔ   r�   r=   r   r   r   Úread_binary_resultÐ  s0   òô
ðz MySQLProtocol.read_binary_resultc                 C   sž   |d dkst  d¡‚i }z5t |dd… d¡\}|d< t |d¡\}|d< t |d¡\}|d	< |d
d… }t |d¡\}|d< W |S  tyN   t  d¡‚w )z'Parse a MySQL Binary Protocol OK packetrh   r   zFailed parsing Binary OK packetrL   NrF   r   Únum_columnsÚ
num_paramsr   rm   )r   r    r	   Úread_intrq   )r   r=   Úok_pktr   r   r   Úparse_binary_prepare_okì  s   
ý
ÿz%MySQLProtocol.parse_binary_prepare_okc                 C   s´   d}d}|dk r,|dkrd}t j}n?|dkrd}t j}n5|dkr&d}t j}n+d	}t j}n%d
}|dkr8d}t j}n|dkrBd}t j}n|dkrLd}t j}nt j}d}t ||¡||fS )z0Prepare an integer for the MySQL binary protocolNr   i€ÿÿÿr    i €ÿÿr¡   i   €r�   r¢   é€   éÿ   ÚBiÿÿ  r²   l   ÿÿ r·   ÚQ)r   r£   r¤   r¦   r§   r%   r&   )r   r¿   rz   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ƒrQ|t 
|j¡ t 
|j¡ t 
|j¡ }|jdkrQ|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Í   rq   r	   Ú	int2storer³   r@   r´   rµ   r¹   rº   r»   r¼   r?   r$   )r   r¿   rz   Ú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ƒrO|jdk r#d}t|j	dƒ\}}t|dƒ\}}	|t
 t|jƒ¡t
 |¡ t
 |¡ t
 |	¡ 7 }|j}n|t
 d¡t
 |j¡ t
 |j¡ t
 |j¡ 7 }|j}|rt|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   Nr1   r   i  é<   )rã   r½   rÇ   Útimerq   r   rÏ   rÂ   ÚdivmodrÃ   r	   r?   Úabsr@   rÄ   r¹   rº   r»   r¼   r$   )
r   r¿   rz   ÚnegativerÀ   rå   rÆ   Ú	remainderÚminsÚsecsr   r   r   Ú_prepare_binary_time@  sD   ÿ
ÿþý

ÿ
þ
ýz"MySQLProtocol._prepare_binary_timec                 C   s   t  |¡t  |¡ | }|S )zMPrepare long data for prepared statements

        Returns a string.
        )r	   r?   rä   )r   Ú	statementÚparamrD   r=   r   r   r   Ú_prepare_stmt_send_long_datam  s   ÿþÿz*MySQLProtocol._prepare_stmt_send_long_datar   r   c              	   C   s  d}dgt |ƒd d  }g }	g }
d}|dkrd}|du ri }|�r[|�r[t |ƒt |ƒkr2t d	¡‚t|ƒD �]#\}}|| }d}|du rb||d   d|d > O  < |
 t tj¡t |¡ ¡ q6||v rt|| d rptj	}nÝtj
}nÙt|tƒr‡|  |¡\}}}|	 |¡ nÆt|tƒr°tr›|	 t t |ƒ¡| ¡ n| |¡}|	 t t |ƒ¡| ¡ tj}n�t|tƒrÅ|	 t t |ƒ¡| ¡ tj	}nˆtrát|tƒrá| |¡}|	 t t |ƒ¡| ¡ tj}nlt|tƒ�r|	 t t t|ƒ |¡ƒ¡t|ƒ |¡ ¡ tj}nLt|tƒ�r|	 t d
|¡¡ tj}n9t|tjtjfƒ�r+|  |¡\}}|	 |¡ n"t|tjtjfƒ�rB|   |¡\}}|	 |¡ nt !dj"|j#j$d�¡‚|
 t |¡t |¡ ¡ q6t %|¡t |¡ t %|¡ d &dd„ |D ƒ¡ t d¡ }|
D ]}||7 }�q{|	D ]}||7 }�q…|S )z6Make a MySQL packet with the Statement Execute commandr   r   r“   rU   r1   Úutf8mb4r   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&   )r…   Úbitr   r   r   r‡   È  s    z3MySQLProtocol.make_stmt_execute.<locals>.<listcomp>)'r$   r   r    rÊ   r•   r	   r@   r   ÚNULLÚBLOBÚSTRINGrã   r‹   râ   r"   r   Úlc_intr   ÚVARCHARÚbytesÚunicoder   ÚDECIMALÚfloatr%   r&   r°   r½   r¾   ræ   rÇ   rè   rï   r6   r!   Ú	__class__Ú__name__r?   r˜   )r   rF   rD   Ú
parametersr{   Úlong_data_usedr:   Úiteration_countrÓ   rÔ   Útypesrå   rÕ   rx   r¿   rz   r=   Úa_typeÚa_valuer   r   r   Úmake_stmt_executex  s¾   ÿÿ
ÿ
ÿ
ÿ
ÿ
ÿÿÿÿþÿÿÿþýüÿzMySQLProtocol.make_stmt_executec                 C   sZ   |d dkst  d¡‚tj|dd… dd�\}}|r&|d d	kr&|dd… }| d
¡|fS )z&Parse a MySQL AuthSwitchRequest-packetrh   r}   z'Failed parsing AuthSwitchRequest packetrL   Nr   rN   rV   r   r   )r   r    r	   r[   r\   )r   r=   Ú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-packetrh   r   z"Failed parsing AuthMoreData packetrL   N)r   r    )r   r=   r   r   r   Úparse_auth_more_dataà  s
   ÿz"MySQLProtocol.parse_auth_more_data)NNNr.   r   r/   FN)r.   r   r/   )N)r   )NNNr.   r   FN)rW   )T)r   rW   )r   r   r   Nr   ) r   Ú
__module__Ú__qualname__Ú__doc__r   r-   r>   rA   rE   rH   rJ   rg   rs   rv   r|   rƒ   r’   rŸ   r­   r±   rÁ   rÉ   rÖ   rØ   rÝ   râ   ræ   rï   rò   r  r	  r
  r   r   r   r   r   .   sR    
ý%
ÿ


þ$0


%

 !"-
ÿ\r   )r  r%   r½   Údecimalr   Ú	constantsr   r   r   r   Ú r   r	   Úauthenticationr
   Úcatch23r   r   r   r   rZ   Úobjectr   r   r   r   r   Ú<module>   s   