o
    h                     @   s   U d Z ddlZddlZddlmZmZ ddlmZmZm	Z	m
Z
mZmZmZ ddlm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mZmZ dd
lmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z' dZ(e)e*d< G dd dZ+dS )z,Implements the MySQL Client/Server protocol.    N)DecimalDecimalException)AnyDictListOptionalSequenceTupleUnion   )utils)get_auth_plugin)PARAMETER_COUNT_AVAILABLE
ClientFlag	FieldFlag	FieldType	ServerCmd)DatabaseErrorInterfaceErrorProgrammingErrorget_exception)
ConnAttrsTypeDescriptionTypeEofPacketTypeHandShakeTypeOkPacketType%ParseValueFromBinaryResultPacketTypes
SocketTypeStatsPacketType
StrOrBytes!SupportedMysqlBinaryProtocolTypes
   PROTOCOL_VERSIONc                   @   s  e Zd ZdZededee defddZ	ededee
 dee dee d	ed
edee dedefddZ										dodee dee
 dee dee dedededed
ee dee d	ee defddZededefddZe	dpdedededefddZedqdedee defd d!Zedrd#ed$edefd%d&Z									dsdedee
 dee dee dededed
ee dee d	ee defd'd(Zed)edefd*d+Zed)edeeef fd,d-Zed)edefd.d/Zed)edee fd0d1Zedtd)ed3edefd4d5Zd)edefd6d7Zedud)ed9ede fd:d;Z!	"drd<e"d=eed>f d?edee#eee d>f  ee f fd@dAZ$ed)edBedeeef fdCdDZ%ed)edBedeee&f fdEdFZ'e	Gdvd)ededeee(f fdHdIZ)ed)edJedeeee*e+j,e+j+f  f fdKdLZ-ed)edeee+j.f fdMdNZ/	2dtdOe#e d)ededee0d>f fdPdQZ1	"	2dwd<e"dRe#e d?ededee#ee0d>f  ee f f
dSdTZ2ed)ede3eef fdUdVZ4edWedeeeef fdXdYZ5edWe*e+j,e+j+f deeef fdZd[Z6edWe*e+j.e+j7f deeef fd\d]Z8ed^ed_ed`edefdadbZ9	c	c			G		dxd#ed`e:e; dde:e< deedfee3eee f  dedgee#eee<f   dhedefdidjZ=ed)edeeef fdkdlZ>ed)edefdmdnZ?dS )yMySQLProtocolzRImplements MySQL client/server protocol

    Create and parses MySQL packets.
    client_flagsdatabasereturnc                 C   s    | t j@ r|r|dd S dS )z.Prepare database string for handshake responseutf8    )r   CONNECT_WITH_DBencode)r$   r%    r+   S/var/www/html/scripts/venv/lib/python3.10/site-packages/mysql/connector/protocol.py_connect_with_dbG   s   zMySQLProtocol._connect_with_dbusernamepasswordauth_plugin_classauth_plugin	auth_datassl_enabledc              
   C   s   |sdS zt |||||||d}| }	W n ttfy, }
 ztd|
 |
d}
~
ww | tj@ r@t|	}td||	 }|S |	d }|S )z#Prepare the authentication responser(   )r.   r/   r%   r3   zFailed authentication: N<B)	r   auth_response	TypeErrorr   r   SECURE_CONNECTIONlenstructpack)r$   r.   r/   r%   r0   r1   r2   r3   authplugin_auth_responseerrresplenr5   r+   r+   r,   _auth_responseN   s*   
zMySQLProtocol._auth_responseN-   r      @F	handshakecharsetmax_allowed_packet
conn_attrsc                 C   s  |du ri }z|d }|	p|d }	W n t tfy) } z	td| ddd}~ww |s.d}z|d}W n ty@   |}Y nw d}t|}td	| | d
||||}|| ||||||	||7 }|| 	||7 }|t
j@ rz||	dd 7 }|t
j@ r|
dur|| |
7 }|S )z"Make a MySQL Authentication packetNr2   r1   &Handshake misses authentication info ()    r'   xxxxxxxxxxxxxxxxxxxxxxz<IIHsxr(   )r6   KeyErrorr   r*   AttributeErrorr8   r9   r:   r?   r-   r   PLUGIN_AUTHCONNECT_ARGSmake_conn_attrs)selfrB   r.   r/   r%   rC   r$   rD   r3   r1   rE   r0   r2   r=   username_bytesfillerusername_lenpacketr+   r+   r,   	make_auths   sZ   

zMySQLProtocol.make_authc                    s    D ]} | du rd |< qt  fdd D t   t   }td|} D ](}|tdt|7 }||d7 }|tdt | 7 }| | d7 }q.|S )z Encode the connection attributesN c                 3   s$    | ]}t |t  |  V  qd S N)r8   ).0xrE   r+   r,   	<genexpr>   s   " z0MySQLProtocol.make_conn_attrs.<locals>.<genexpr>r4   r'   )sumr8   keysvaluesr9   r:   r*   )rE   	attr_nameconn_attrs_lenconn_attrs_packetr+   rZ   r,   rO      s"   

zMySQLProtocol.make_conn_attrsc                 C   s"   t |t | t |  d S )z Make a SSL authentication packets                         r   	int4store	int2store)rC   r$   rD   r+   r+   r,   make_auth_ssl   s   zMySQLProtocol.make_auth_sslcommandargumentc                 C   s   t | }|dur||7 }|S )z(Make a MySQL packet containing a commandN)r   	int1store)rf   rg   datar+   r+   r,   make_command   s   
zMySQLProtocol.make_commandr   statement_idrowsc                 C   s   t | t | S )z0Make a MySQL packet with Fetch Statement command)r   rc   )rk   rl   r+   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dd}~ww |s(d}z|d}W n ty:   |}Y nw t|}td| d	tj	|}|| 
|||||
|||7 }|| ||7 }|td
|7 }|tj@ rw||dd 7 }|tj@ r|	dur|| |	7 }|S )z0Make a MySQL packet with the Change User commandr2   r1   rF   rG   NrH   r'   r4   rJ   <Hr(   )r6   rK   r   r*   rL   r8   r9   r:   r   CHANGE_USERr?   r-   r   rM   rN   rO   )rP   rB   r.   r/   r%   rC   r$   r3   r1   rE   r0   r2   r=   rQ   rS   rT   r+   r+   r,   make_change_user   sR   


zMySQLProtocol.make_change_userrT   c           	   	   C   s  i }t d| dd d |d< |d tkr"td|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|rmt
d|d nd}| d| }| |d } |d dkr|dd }|tj@ rd| vr|d
 drd| } |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 = z, client version = Nr(   endserver_version_originalz<I8sx2sBH2sBxxxxxxxxxx   server_threadidrC   server_statusrH         z5.5.8r1   utf-8mysql_native_passwordr2   capabilities)r9   unpackr"   r   r   read_stringdecodeintreadr   r7   minrM   
startswith)	rT   res
auth_data1capabilities1capabilities2auth_data_lengthr   
auth_data2sizer+   r+   r,   parse_handshake  sR   

zMySQLProtocol.parse_handshakec                 C   s@   t | d\} }|dkrtdt j| dd\} }| |dfS )z$Parse a MySQL AuthNextFactor packet.r      z.Failed parsing AuthNextFactor packet (invalid)r(   rt   r}   )r   read_intr   r   r   )rT   statusr1   r+   r+   r,   parse_auth_next_factorR  s
   z$MySQLProtocol.parse_auth_next_factorc              
   C   s   | d dks
t di }zTt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yq } zt d|d}~ww )zParse a MySQL OK-packet   r   z#Failed parsing OK packet (invalid).rq   rr   field_countNaffected_rows	insert_idz<HHstatus_flagwarning_countinfo_msgr}   zFailed parsing OK packet.)r   r9   r   r   read_lc_intread_lc_stringr   
ValueError)rT   	ok_packetr=   r+   r+   r,   parse_ok[  s,   
zMySQLProtocol.parse_okc              
   C   sF   zt | dd d }|W S  tjtfy" } ztd|d}~ww )z=Parse a MySQL packet with the number of columns in result setr   Nr   zFailed parsing column count)r   r   r9   errorr   r   )rT   countr=   r+   r+   r,   parse_column_countr  s   
z MySQLProtocol.parse_column_countr}   encodingc              	   C   s   t | dd \} }t | \} }t | \} }t | \} }t | \} }t | \} }ztd| \}}}}}W n tjyH   tddw |||dddd| tj@ ||f	S )zParse a MySQL column-packetr   Nz	<xHIBHBxxz!Failed parsing column information)	r   r   r9   r   r   r   r   r   NOT_NULL)rT   r   _namerC   column_typeflagsr+   r+   r,   parse_column{  s6   


zMySQLProtocol.parse_columnc              
   C   s   |d dkr|  |S d}i }ztd|}W n tjy) } zt||d}~ww |d dkr6t|dks:t||d	 |d
< |d |d< |S )zParse a MySQL EOF-packetr   r   zFailed parsing EOF packet.z<xxxBBHHNr      	   r   r      r   )r   r9   r   r   r   r8   )rP   rT   err_msgr   unpackedr=   r+   r+   r,   	parse_eof  s   

zMySQLProtocol.parse_eofTwith_headerc           	      C   s  d}i }dg}d}|r| dd  d}n|  d}|D ]c}zdd | dd	D \}}W n ty> } zt||d}~ww |d
}zt|||< W q ttfy   zt|d
||< W n ty| } zt| d| dt| d|d}~ww Y qw |S )zParse the statistics packetz)Failed getting COM_STATISTICS informationrH   r   Ns     c                 S   s   g | ]}|  qS r+   )strip)rX   vr+   r+   r,   
<listcomp>      z2MySQLProtocol.parse_statistics.<locals>.<listcomp>   :r   r}   z (:rG   )	splitr   r   r   intrK   r   r   repr)	rT   r   errmsgr   pairslblpairvalr=   r+   r+   r,   parse_statistics  s6   


 zMySQLProtocol.parse_statisticssockversion.r   c                 C   s&  |}g }d}d}d}	 |s||kr	 ||fS |  }	|	drU|	dd g}
|  }	|	drA|
|	dd  |  }	|	ds/|
|	dd  ttd|
}n|	d dkri|	d dk ri| |	}d}nd}t|	dd }|du r|dur|| n|du r|du rt|	|d	7 }q)
zRead 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   r   rH   r      r   )	recvr   appendr   read_lc_string_list	bytearrayjoinr   r   )rP   r   r   r   r   rl   eofrowdatairT   datasr+   r+   r,   read_text_result  s<   



zMySQLProtocol.read_text_resultfieldc                 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   <ir   <qr{   r   Nr   )r   TINYSHORTINT24LONGLONGLONGr   UNSIGNEDupperr9   r   )rT   r   format_lengthr+   r+   r,   _parse_binary_integer  s   $z#MySQLProtocol._parse_binary_integerc                 C   sD   |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   r{   <dr   z<fNr   )r   DOUBLEr9   r   )rT   r   r   r   r+   r+   r,   _parse_binary_float  s   $z!MySQLProtocol._parse_binary_floatr'   c                 C   s    t | \} }| t||fS )z(Parse a New Decimal from a binary packet)r   r   r   r   )rT   rC   valuer+   r+   r,   _parse_binary_new_decimal  s   z'MySQLProtocol._parse_binary_new_decimal
field_typec              	   C   s   | d }d}|dkr8t d| dd d }| d }| d }|tjtjfv r/tj|||d}nAtj|||d}n8|dkrpd}|d	krPt 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   Nr   rn   r   r   )yearmonthdayr      <Ir{   rr      )r   r   r   hourminutesecondmicrosecond)r9   r   r   DATETIME	TIMESTAMPdatetimedate)rT   r   r   r   r   r   r   mcsr+   r+   r,   _parse_binary_timestamp#  s.   
z%MySQLProtocol._parse_binary_timestampc                 C   s   | d }|s| dd t  fS | d|d  }d}|dkr*td|dd d }td|dd d }|d dkr@|d9 }t j||d ||d	 |d d
}| |d d |fS )z'Parse a time value from a binary packetr   r   Nr{   r   rr   r|   r   r   )dayssecondsmicrosecondsminuteshours)r   	timedeltar9   r   )rT   r   ri   r   r   tmpr+   r+   r,   _parse_binary_timeC  s$   z MySQLProtocol._parse_binary_timefieldsc           
   	   C   s  t |d d d }dd |d| D }||d }g }d}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 ru| ||	\}}|| q#|	d tjtjfv r| ||\}}|| q#|	d tjtjtjfv r| ||	d \}}|| q#|	d tjkr| |\}}|| q#t|\}}z
||| W q# ty   || Y q#w t|S )	z(Parse values from a binary result packetr   r   r{   c                 S   s   g | ]}t |qS r+   )r   )rX   r   r+   r+   r,   r   b  r   z6MySQLProtocol._parse_binary_values.<locals>.<listcomp>r   Nr   )r8   	enumerater   r   r   r   r   r   r   r   r   r   FLOATr   DECIMAL
NEWDECIMALr   r   DATEr   r   TIMEr   r   r   r   UnicodeDecodeErrortuple)
rP   r   rT   rC   null_bitmap_lengthnull_bitmapr^   r   posr   r+   r+   r,   _parse_binary_valuesZ  sR   $
z"MySQLProtocol._parse_binary_valuescolumnsc           
      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   Tr   r   rr   r   )r   r   r  r   r   )
rP   r   r  r   rC   rl   r   r^   r   rT   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yR } zt d|d}~ww )z'Parse a MySQL Binary Protocol OK packetr   r   zFailed parsing Binary OK packetrr   Nrk   r   num_columns
num_paramsr   r   )r   r   r   r   )rT   ok_pktr=   r+   r+   r,   parse_binary_prepare_ok  s   
z%MySQLProtocol.parse_binary_prepare_okr   c                 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   ir   i r   i   r   r         r4   i  rn   l    r   z<Q)r   r   r   r   r   r9   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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   r   r   rd   r   rh   r   r   r   r   r   r   rc   r8   )r   r   packedr+   r+   r,   prepare_binary_timestamp  s0   






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   NrH   r   i  <   )r  r   r   timer   r   r   r   divmodr   r   rc   absrh   r   r   r   r   r   r8   )	r   r   negativer   r  r   	remainderminssecsr+   r+   r,   prepare_binary_time  sH   



z!MySQLProtocol.prepare_binary_time	statementparamri   c                 C   s   t | t | | }|S )zMPrepare long data for prepared statements

        Returns a string.
        rb   )r  r  ri   rT   r+   r+   r,   prepare_stmt_send_long_dataB  s   z)MySQLProtocol.prepare_stmt_send_long_datar+   
parametersr   long_data_usedquery_attrsconverter_str_fallbackc	              	   C   s  d}	dgt |d d  }
g }g }d}t |}g }|s|n|t }|dkr'd}|du r-i }|rJt|}|D ]	\}}|| q5dgt |d d  }
|sO|r|t |krYtd	t|D ]-\}}d}|du r|
|d   d|d > O  < |ttj	t|  q]||v r|| d rtj
}ntj}nt|tr| |\}}}|| nt|tr||}|tt ||  tj}nt|tr|tt ||  tj}nt|tr|tt t||t||  tj}net|tr|td
| tj}nRt|tjtjfr"| |\}}|| n;t|tjtjfr9| |\}}|| n$|rSt||}|tt ||  tj}n
td|j j! d|t|t|  |r|d |kr|||  d |}|tt ||  q]t"|t| t"|	 }|dur|t | }n|}|r|dur|t|7 }|d#dd |
D td 7 }d}|D ]$}||7 }|dur|d |kr||||  7 }n|d7 }|d7 }q|D ]}||7 }q|S )z6Make a MySQL packet with the Statement Execute commandr   r   r   r{   rH   utf8mb4r'   NzTFailed executing prepared statement: data values does not match number of parametersr   z&MySQL binary protocol can not handle 'z	' objectsc                 S   s   g | ]}t d |qS )B)r9   r:   )rX   bitr+   r+   r,   r     s    z3MySQLProtocol.make_stmt_execute.<locals>.<listcomp>r(   )$r8   r   listr   r   r   r   rh   r   NULLBLOBSTRINGr  r   r  strr*   lc_intbytesr   r   floatr9   r:   r   r   r   r  r   r  r  r   	__class____name__rc   r   )rP   rk   ri   r  r   r  rC   r  r   iteration_countr  r^   typesr  data_lenquery_attr_namesr   attr_valr  r   _flagsr   r   rT   parameter_countr   a_typea_valuer+   r+   r,   make_stmt_executeM  s   








zMySQLProtocol.make_stmt_executec                 C   sX   | 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-packetr   r   z'Failed parsing AuthSwitchRequest packetrr   Nr(   rt   r|   r   r'   )r   r   r   r   )rT   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-packetr   r   z"Failed parsing AuthMoreData packetrr   N)r   )rT   r+   r+   r,   parse_auth_more_data  s   z"MySQLProtocol.parse_auth_more_data)
NNNr@   r   rA   FNNN)r@   r   rA   rW   )r   )	NNNr@   r   FNNN)r}   )T)r'   )r   r}   )r+   r+   r   Nr'   NF)@r-  
__module____qualname____doc__staticmethodr   r   r(  r*  r-   r   boolr?   r   r   rU   rO   r   re   rj   rm   rp   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  r   r
  r  r  r  r  r  r   r    r   r7  r9  r:  r+   r+   r+   r,   r#   A   s   	'	

A	

=3 

)




7
%!
(
2	

 r#   ),r=  r   r9   decimalr   r   typingr   r   r   r   r   r	   r
   rV   r   authenticationr   	constantsr   r   r   r   r   errorsr   r   r   r   r/  r   r   r   r   r   r   r   r   r   r    r"   r   __annotations__r#   r+   r+   r+   r,   <module>   s   $0