U
    e                     @   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'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QueryAttrType
SocketTypeStatsPacketType
StrOrBytes!SupportedMysqlBinaryProtocolTypes
   PROTOCOL_VERSIONc                   @   s  e Zd ZdZeeee edddZ	eeee
 ee ee eeee eed	ddZd_ee ee
 ee ee eeeeee ee ee edddZeeedddZed`eeeedddZedaeee edddZedbeeedddZdceee
 ee ee eeeee ee ee edddZeeed d!d"Zeeeeef d d#d$Zeeed d%d&Zeeee d d'd(Zeddeeed*d+d,Zeed d-d.Zedeeee d0d1d2Z!dfe"eed3f eee#eee d3f  ee f d4d5d6Z$eeeeeef d7d8d9Z%eeeeee&f d7d:d;Z'edgeeeee(f d=d>d?Z)eeeeeee*e+j,e+j+f  f d@dAdBZ-eeeee+j.f d dCdDZ/dhe#e eeee0d3f dEdFdGZ1die"e#e eeee#ee0d3f  ee f dHdIdJZ2eee3eef d dKdLZ4eeeeeef dMdNdOZ5ee*e+j,e+j+f eeef dMdPdQZ6ee*e+j.e+j7f eeef dMdRdSZ8eeeeedTdUdVZ9djee:e; e:e< eee3eee f  eee= eedX	dYdZZ>eeeeef d d[d\Z?eeed d]d^Z@dS )k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   ZCONNECT_WITH_DBencode)r%   r&    r+   Y/var/www/html/assets/scripts/venv/lib/python3.8/site-packages/mysql/connector/protocol.py_connect_with_dbH   s    zMySQLProtocol._connect_with_db)	r%   usernamepasswordr&   auth_plugin_classauth_plugin	auth_datassl_enabledr'   c              
   C   s   |sdS z$t |||||||d}| }	W n6 ttfk
rb }
 ztd|
 |
W 5 d}
~
X Y nX | tj@ rt|	}td||	 }n|	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   authZplugin_auth_responseerrZresplenr5   r+   r+   r,   _auth_responseO   s$    "
zMySQLProtocol._auth_responseN-   r      @F)	handshaker.   r/   r&   charsetr%   max_allowed_packetr3   r1   
conn_attrsr0   r'   c                 C   s*  |dkri }z|d }|	p |d }	W n8 t tfk
r\ } ztd| ddW 5 d}~X Y nX |sfd}z|d}W n tk
r   |}Y nX d}t|}td	| | d
||||}|| ||||||	||7 }|| 	||7 }|t
j@ r||	dd 7 }|t
j@ r&|
dk	r&|| |
7 }|S )z"Make a MySQL Authentication packetNr2   r1   &Handshake misses authentication info ()    r(   Zxxxxxxxxxxxxxxxxxxxxxxz<IIHsxr)   )r6   KeyErrorr   r*   AttributeErrorr8   r9   r:   r=   r-   r   PLUGIN_AUTHCONNECT_ARGSmake_conn_attrs)selfr@   r.   r/   r&   rA   r%   rB   r3   r1   rC   r0   r2   r<   username_bytesZfillerusername_lenpacketr+   r+   r,   	make_autht   sT    

zMySQLProtocol.make_auth)rC   r'   c                    s    D ]} | dkrd |< qt  fdd D t   t   }td|} D ]P}|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rC   r+   r,   	<genexpr>   s     z0MySQLProtocol.make_conn_attrs.<locals>.<genexpr>r4   r(   )sumr8   keysvaluesr9   r:   r*   )rC   	attr_nameZconn_attrs_lenZconn_attrs_packetr+   rU   r,   rL      s     


zMySQLProtocol.make_conn_attrs)rA   r%   rB   r'   c                 C   s"   t |t | t |  d S )z Make a SSL authentication packets                         r   	int4store	int2store)rA   r%   rB   r+   r+   r,   make_auth_ssl   s    zMySQLProtocol.make_auth_ssl)commandargumentr'   c                 C   s   t | }|dk	r||7 }|S )z(Make a MySQL packet containing a commandN)r   	int1store)r_   r`   datar+   r+   r,   make_command   s    
zMySQLProtocol.make_commandr   )statement_idrowsr'   c                 C   s   t | t | S )z0Make a MySQL packet with Fetch Statement command)r   r\   )rd   re   r+   r+   r,   make_stmt_fetch   s    zMySQLProtocol.make_stmt_fetch)r@   r.   r/   r&   rA   r%   r3   r1   rC   r0   r'   c                 C   s"  z|d }|p|d }W n8 t tfk
rP } ztd| ddW 5 d}~X Y nX |sZd}z|d}W n tk
r   |}Y nX t|}td| d	tj	|}|| 
|||||
|||7 }|| ||7 }|td
|7 }|tj@ r||dd 7 }|tj@ r|	dk	r|| |	7 }|S )z0Make a MySQL packet with the Change User commandr2   r1   rD   rE   NrF   r(   r4   rG   <Hr)   )r6   rH   r   r*   rI   r8   r9   r:   r   ZCHANGE_USERr=   r-   r   rJ   rK   rL   )rM   r@   r.   r/   r&   rA   r%   r3   r1   rC   r0   r2   r<   rN   rO   rP   r+   r+   r,   make_change_user   sL    



zMySQLProtocol.make_change_user)rP   r'   c           	   	   C   s  i }t d| dd d |d< |d tkrDt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|rt
d|d nd}| d| }| |d } |d dkr|dd }|tj@ rrd| krH|d
 drHd|  } |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)   endZserver_version_originalz<I8sx2sBH2sBxxxxxxxxxx   Zserver_threadidrA   Zserver_statusrF         z5.5.8r1   utf-8Zmysql_native_passwordr2   capabilities)r9   unpackr#   r   r   read_stringdecodeZintreadr   r7   minrJ   
startswith)	rP   resZ
auth_data1Zcapabilities1Zcapabilities2Zauth_data_lengthrs   Z
auth_data2sizer+   r+   r,   parse_handshake  sP    
 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)   rl   rr   )r   read_intr   ru   rv   )rP   statusr1   r+   r+   r,   parse_auth_next_factorS  s
    z$MySQLProtocol.parse_auth_next_factorc              
   C   s   | d dkst di }ztd| dd d |d< t| dd \} |d< t| \} |d	< td
| dd \|d< |d< | dd } | rt| \} |d< |d d|d< W n, tk
r } zt d|W 5 d}~X Y nX |S )zParse a MySQL OK-packet   r   z#Failed parsing OK packet (invalid).ri   rj   Zfield_countNZaffected_rowsZ	insert_idz<HHstatus_flagwarning_countZinfo_msgrr   zFailed parsing OK packet.)r   r9   rt   r   read_lc_intread_lc_stringrv   
ValueError)rP   Z	ok_packetr<   r+   r+   r,   parse_ok\  s$    zMySQLProtocol.parse_okc              
   C   sT   zt | dd d }|W S  tjtfk
rN } ztd|W 5 d}~X Y nX dS )z=Parse a MySQL packet with the number of columns in result setr   Nr   zFailed parsing column count)r   r   r9   errorr   r   )rP   countr<   r+   r+   r,   parse_column_counts  s
    z MySQLProtocol.parse_column_countrr   )rP   encodingr'   c              	   C   s   t | dd \} }t | \} }t | \} }t | \} }t | \} }t | \} }ztd| \}}}}}W n  tjk
r   tddY nX |||dddd| tj@ ||f	S )zParse a MySQL column-packetr   Nz	<xHIBHBxxz!Failed parsing column information)	r   r   r9   rt   r   r   rv   r   ZNOT_NULL)rP   r   _namerA   Z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k
r\ } zt||W 5 d}~X Y nX |d dkrvt|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   rt   r   r   r8   )rM   rP   err_msgry   unpackedr<   r+   r+   r,   	parse_eof  s    
zMySQLProtocol.parse_eofT)rP   with_headerr'   c           	      C   s   d}i }dg}d}|r*| dd  d}n
|  d}|D ]}zdd | dd	D \}}W n, tk
r } zt||W 5 d}~X Y nX |d
}zt|||< W q8 ttfk
r   zt|d
||< W nD tk
r } z$t| d| dt| d|W 5 d}~X Y nX Y q8X q8|S )zParse the statistics packetz)Failed getting COM_STATISTICS informationrF   r   Ns     c                 S   s   g | ]}|  qS r+   )strip)rS   vr+   r+   r,   
<listcomp>  s     z2MySQLProtocol.parse_statistics.<locals>.<listcomp>   :r|   rr   z (:rE   )	splitr   r   rv   intrH   r   r   repr)	rP   r   errmsgry   pairsZlblpairvalr<   r+   r+   r,   parse_statistics  s*    

:zMySQLProtocol.parse_statistics.)sockversionr   r'   c                 C   s"  |}g }d}d}d}|s ||kr$q|  }	|	dr|	dd g}
|  }	|	drr|
|	dd  |  }	qL|
|	dd  ttd|
}n>|	d dkr|	d dk r| |	}d}nd}t|	dd }|dkr|dk	r|| n|dkr|dkrt|	|d7 }q||fS )	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   s   r   rF   r      r   )	recvrx   appendr   Zread_lc_string_list	bytearrayjoinr   r   )rM   r   r   r   r   re   eofZrowdatairP   Zdatasr+   r+   r,   read_text_result  s6    




zMySQLProtocol.read_text_result)rP   fieldr'   c                 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|   <ir   <qrp   r   Nr   )r   TINYSHORTINT24LONGLONGLONGr   ZUNSIGNEDupperr9   rt   )rP   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   rp   <dr   z<fNr   )r   DOUBLEr9   rt   )rP   r   r   r   r+   r+   r,   _parse_binary_float  s    z!MySQLProtocol._parse_binary_floatr(   )rP   rA   r'   c                 C   s    t | \} }| t||fS )z(Parse a New Decimal from a binary packet)r   r   r   rv   )rP   rA   valuer+   r+   r,   _parse_binary_new_decimal  s    z'MySQLProtocol._parse_binary_new_decimal)rP   
field_typer'   c              	   C   s   | d }d}|dkrpt d| dd d }| d }| d }|tjtjfkr^tj|||d}qtj|||d}np|dkrd}|d	krt 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   rg   r   r   )yearmonthdayr      <Irp   rj      )r   r   r   hourminutesecondmicrosecond)r9   rt   r   DATETIME	TIMESTAMPdatetimedate)rP   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rTt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   Nrp   r   rj   rq   r   r   )dayssecondsmicrosecondsminuteshours)r   	timedeltar9   rt   )rP   r   rb   r   r   tmpr+   r+   r,   _parse_binary_timeD  s$    z MySQLProtocol._parse_binary_time)fieldsrP   rA   r'   c           
   	   C   s  t |d d d }dd |d| D }||d }g }d}t|D ]~\}}	|t|d d  d|d d > @ r|d qF|	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fkr| ||\}}|| qF|	d tjtjtjfkrX| ||	d \}}|| qF|	d tjkr| |\}}|| qFt|\}}z||| W qF tk
r   || Y qFX qFt|S )	z(Parse values from a binary result packetr   r|   rp   c                 S   s   g | ]}t |qS r+   )r   )rS   r   r+   r+   r,   r   c  s     z6MySQLProtocol._parse_binary_values.<locals>.<listcomp>r   Nr   )r8   	enumerater   r   r   r   r   r   r   r   r   r   FLOATr   DECIMALZ
NEWDECIMALr   r   DATEr   r   TIMEr   r   r   rv   UnicodeDecodeErrortuple)
rM   r   rP   rA   Znull_bitmap_lengthnull_bitmaprY   r   posr   r+   r+   r,   _parse_binary_values[  sP    $
z"MySQLProtocol._parse_binary_values)r   columnsr   rA   r'   c           
      C   s   g }d}d}d}|dk	rq||kr$q|  }	|	d dkrH| |	}d}n&|	d dkrnd}| ||	dd |}|dkr|dk	r|| n|dkr|dkrt|	|d7 }q||fS )zwRead MySQL binary protocol result

        Reads all or given number of binary resultset rows from the socket.
        Nr   r   r   rj   r   )r   r   r   r   r   )
rM   r   r   r   rA   re   r   rY   r   rP   r+   r+   r,   read_binary_result  s*    

z MySQLProtocol.read_binary_resultc              
   C   s   | d dkst di }zht| dd d\} |d< t| d\} |d< t| d\} |d	< | d
d } t| d\} |d< W n, tk
r } zt d|W 5 d}~X Y nX |S )z'Parse a MySQL Binary Protocol OK packetr   r   zFailed parsing Binary OK packetrj   Nrd   r|   Znum_columnsZ
num_paramsr   r   )r   r   r}   r   )rP   Zok_pktr<   r+   r+   r,   parse_binary_prepare_ok  s    z%MySQLProtocol.parse_binary_prepare_ok)r   r'   c                 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}qd	}t j}nJd
}| dkrpd}t j}n2| dkrd}t j}n| dkrd}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  rg   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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   r   r   r]   r   ra   r   r   r   r   r   r   r\   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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   NrF   r   i  <   )r   r   r   timer   r   r   r   divmodr   r   r\   absra   r   r   r   r   r   r8   )	r   r   negativer   r   r   	remainderZminsZsecsr+   r+   r,   prepare_binary_time  sH    



z!MySQLProtocol.prepare_binary_time)	statementparamrb   r'   c                 C   s   t | t | | }|S )zMPrepare long data for prepared statements

        Returns a string.
        r[   )r   r   rb   rP   r+   r+   r,   prepare_stmt_send_long_dataC  s    z)MySQLProtocol.prepare_stmt_send_long_datar+   )	rd   rb   
parametersr   long_data_usedrA   query_attrsconverter_str_fallbackr'   c	              	   C   s  d}	dgt |d d  }
g }g }d}t |}g }|s:|n|t }|dkrNd}|dkrZi }|rt|}|D ]\}}|| qjdgt |d d  }
|s|r*|t |krtd	t|D ]l\}}d}|dkr|
|d   d|d > O  < |ttj	t|  q||kr6|| d r,tj
}ntj}nt|tr`| |\}}}|| npt|tr||}|tt ||  tj}n8t|tr|tt ||  tj
}n
t|tr|tt t||t||  tj}nt|tr,|td
| tj}nt|tjtjfrZ| |\}}|| nvt|tjtjfr| |\}}|| nH|rt||}|tt ||  tj}nt d|j!j" d|t|t|  |r|d |kr|||  d |}|tt ||  qt#|t| t#|	 }|dk	r`|t | }n|}|r
|dk	r|t|7 }|d$dd |
D td 7 }d}|D ]H}||7 }|dk	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   rp   rF   Z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:   )rS   bitr+   r+   r,   r     s     z3MySQLProtocol.make_stmt_execute.<locals>.<listcomp>r)   )%r8   r   listr   r   r   r   ra   r   ZNULLZBLOBSTRINGr   r   r   strr*   Zlc_intZVARCHARbytesr   r   floatr9   r:   r   r   r   r   r   r   r   r   	__class____name__r\   r   )rM   rd   rb   r   r   r   rA   r   r   Ziteration_countr   rY   typesr   data_lenZquery_attr_namesr   Zattr_valr   r   _flagsr   r   rP   Zparameter_countr   a_typeZa_valuer+   r+   r,   make_stmt_executeN  s    









zMySQLProtocol.make_stmt_executec                 C   sX   | d dkst dtj| dd dd\} }| rJ| d d	krJ| dd } |d
| fS )z&Parse a MySQL AuthSwitchRequest-packetr   r   z'Failed parsing AuthSwitchRequest packetrj   Nr)   rl   rq   r   r(   )r   r   ru   rv   )rP   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-packetr   r   z"Failed parsing AuthMoreData packetrj   N)r   )rP   r+   r+   r,   parse_auth_more_data  s    z"MySQLProtocol.parse_auth_more_data)
NNNr>   r   r?   FNNN)r>   r   r?   )N)r   )	NNNr>   r   FNNN)rr   )T)r   )r(   )rr   )r   rr   )r+   r+   r   Nr(   NF)Ar  
__module____qualname____doc__staticmethodr   r   r   r   r-   r    boolr=   r   r   rQ   rL   r   r^   rc   rf   rh   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   r   r  r	  r
  r+   r+   r+   r,   r$   B   sj  '          A                =3   
 ) 
 
  
 
7  %!
(
2          r$   )-r  r   r9   decimalr   r   typingr   r   r   r   r   r	   r
   rR   r   Zauthenticationr   	constantsr   r   r   r   r   errorsr   r   r   r   r  r   r   r   r   r   r   r   r   r   r    r!   r#   r   __annotations__r$   r+   r+   r+   r,   <module>   s   $4