a
    ’éi3¦  ã                   @  sL  d Z ddlmZ ddlZddlZddlm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mZ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 ddlmZm Z m!Z!m"Z" ddl#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.m/Z/m0Z0 e�rddl1m2Z2 dZ3dZ4dZ5dZ6dZ7dZ8dZ9dZ:dZ;dZ<G dd„ dƒZ=dS )z,Implements the MySQL Client/Server protocol.é    )ÚannotationsN)Údeque)ÚDecimalÚDecimalException)	ÚTYPE_CHECKINGÚAnyÚDequeÚDictÚListÚOptionalÚSequenceÚTupleÚUnioné   )Úutils)ÚPARAMETER_COUNT_AVAILABLEÚ
ClientFlagÚ	FieldFlagÚ	FieldTypeÚ	ServerCmd)ÚMySQLConverter)ÚDatabaseErrorÚInterfaceErrorÚProgrammingErrorÚget_exception)Úlogger)ÚMySQLAuthPluginÚget_auth_plugin)Ú"MySQLCachingSHA2PasswordAuthPlugin)ÚBinaryProtocolTypeÚDescriptionTypeÚEofPacketTypeÚHandShakeTypeÚOkPacketTypeÚStatsPacketTypeÚ
StrOrBytes)ÚMySQLSocketé
   éþ   é   éÿ   éû   é-   i   @c                   @  sä  e Zd ZdZedddœdd„ƒZedddœdd„ƒZedddœd	d
„ƒZedddœdd„ƒZeddddœdd„ƒZ	ed~dddddddddœdd„ƒZ
edededdddddf
ddddddddddddddd œd!d"„ƒZeedefddddd#œd$d%„ƒZeddd&dd'œd(d)„ƒZed€dddd+œd,d-„ƒZeddd.œd/d0„ƒZedd1d.œd2d3„ƒZedd4d.œd5d6„ƒZed�ddd8d9œd:d;„ƒZdd<d.œd=d>„Zed‚ddd@dAœdBdC„ƒZdƒdDdEdd4dFdGœdHdI„Zedd8dJdKœdLdM„ƒZedd8dNdKœdOdP„ƒZed„dddRdSœdTdU„ƒZedddVdWœdXdY„ƒZeddZd.œd[d\„ƒZd…d]ddd^d_œd`da„Zd†dDd]ddd4dbdcœddde„Zeddfd.œdgdh„ƒZeddidjœdkdl„ƒZ edmdJdjœdndo„ƒZ!edpdJdjœdqdr„ƒZ"edddddsœdtdu„ƒZ#d‡ddwdxddyddzddd{œ	d|d}„Z$dS )ˆÚMySQLProtocolzRImplements MySQL client/server protocol

    Create and parses MySQL packets.
    Úbytes)ÚpktÚreturnc                 C  s    | d t kstdƒ‚| dd… S )a  Parse a MySQL auth more data packet.

        Args:
            pkt: Packet representing an `auth more data` response.

        Returns:
            auth_data: Authentication method data (see [1]).

        Raises:
            InterfaceError: If packet's status tag doesn't
                            match `protocol.EXCHANGE_FURTHER_STATUS`.

        References:
            [1]: https://dev.mysql.com/doc/dev/mysql-server/latest/                page_protocol_connection_phase_packets_protocol_auth_more_data.html
        é   z"Failed parsing AuthMoreData packeté   N)ÚEXCHANGE_FURTHER_STATUSr   )r/   © r4   úH/home/Claro/venv/lib/python3.9/site-packages/mysql/connector/protocol.pyÚparse_auth_more_data^   s    z"MySQLProtocol.parse_auth_more_datazTuple[str, bytes]c                 C  sV   | d t krtdƒ‚tj| dd… dd�\} }| rJ| d dkrJ| dd… } | ¡ | fS )	a|  Parse a MySQL auth switch request packet.

        Args:
            pkt: Packet representing an `auth switch request` response.

        Returns:
            plugin_name: Name of the client authentication plugin to switch to.
            plugin_provided_data: Plugin provided data (see [1]).

        Raises:
            InterfaceError: If packet's status tag doesn't
                            match `protocol.AUTH_SWITCH_STATUS`.

        References:
            [1]: https://dev.mysql.com/doc/dev/mysql-server/                latest/page_protocol_connection_phase_packets_protocol_
                auth_switch_request.html
        r1   z'Failed parsing AuthSwitchRequest packetr2   Nó    ©Úendéÿÿÿÿr   )ÚAUTH_SWITCH_STATUSr   r   Úread_stringÚdecode)r/   Úplugin_namer4   r4   r5   Úparse_auth_switch_requestt   s    z'MySQLProtocol.parse_auth_switch_requestc                 C  sF   t  | dd… d¡\} }|tkr(tdƒ‚t j| dd�\} }| ¡ | fS )a¦  Parse a MySQL auth next factor packet.

        Args:
            pkt: Packet representing an `auth next factor` response.

        Returns:
            plugin_name: Name of the client authentication plugin.
            plugin_provided_data: Initial authentication data for that
                                  client plugin (see [1]).

        Raises:
            InterfaceError: If packet's packet type doesn't
                            match `protocol.MFA_STATUS`.

        References:
            [1]: https://dev.mysql.com/doc/dev/mysql-server/latest/                page_protocol_connection_phase_packets_protocol_auth_                next_factor_request.html
        r1   Nr   z.Failed parsing AuthNextFactor packet (invalid)r7   r8   )r   Úread_intÚ
MFA_STATUSr   r<   r=   )r/   Ústatusr>   r4   r4   r5   Úparse_auth_next_factor�   s
    z$MySQLProtocol.parse_auth_next_factorzDict[str, str])Ú
conn_attrsr0   c              	     s¾   ˆ D ]}ˆ | du rdˆ |< qt ‡ fdd„ˆ D ƒƒtˆ  ¡ ƒ tˆ  ¡ ƒ }t d|¡g}ˆ D ]T}| t dt|ƒ¡¡ | | ¡ ¡ | t dtˆ | ƒ¡¡ | ˆ |  ¡ ¡ q^d |¡S )az  Encode the connection attributes.

        Args:
            conn_attrs: Connection attributes.

        Returns:
            serialized_conn_attrs: Serialized connection attributes as per [1].

        References:
            [1]: https://dev.mysql.com/doc/dev/mysql-server/latest/                page_protocol_connection_phase_packets_protocol_handshake_response.html
        NÚ c                 3  s"   | ]}t |ƒt ˆ | ƒ V  qd S )N)Úlen)Ú.0Úx©rD   r4   r5   Ú	<genexpr>¼   ó    z0MySQLProtocol.make_conn_attrs.<locals>.<genexpr>ú<BrK   )	ÚsumrF   ÚkeysÚvaluesÚstructÚpackÚappendÚencodeÚjoin)rD   Ú	attr_nameZconn_attrs_lenZconn_attrs_packetr4   rI   r5   Úmake_conn_attrsª   s     

ÿ
þÿzMySQLProtocol.make_conn_attrsÚintzOptional[str])Úclient_flagsÚdatabaser0   c                 C  s   | t j@ r|r| ¡ d S dS )aÙ  Prepare database string for handshake response.

        Args:
            client_flags: Integer representing client capabilities flags.
            database: Initial database name for the connection.

        Returns:
            serialized_database: Serialized database name as per [1].

        References:
            [1]: https://dev.mysql.com/doc/dev/mysql-server/latest/                page_protocol_connection_phase_packets_protocol_handshake_response.html
        r7   )r   ZCONNECT_WITH_DBrS   )rX   rY   r4   r4   r5   Úconnect_with_dbÉ   s    ÿÿýzMySQLProtocol.connect_with_dbNFÚstrÚboolzOptional[Dict[str, Any]]zTuple[bytes, MySQLAuthPlugin])Ú	auth_dataÚusernameÚpasswordÚauth_pluginÚauth_plugin_classÚssl_enabledÚplugin_configr0   c           
   
   C  sÀ   |s|dkrdt |||d�fS |du r*i }z*t||ƒ|||d�}|j| fi |¤Ž}W n8 ttfyŒ }	 ztd|	› �ƒ|	‚W Y d}	~	n
d}	~	0 0 |du r¦td|j› �ƒ‚t t|ƒ¡| }||fS )a  Prepare the first authentication response.

        Args:
            auth_data: Authorization data from initial handshake.
            username: Account's username.
            password: Account's password.
            client_flags: Integer representing client capabilities flags.
            auth_plugin: Authorization plugin name.
            auth_plugin_class: Authorization plugin class (has higher precedence
                               than the authorization plugin name).
            ssl_enabled: Whether SSL is enabled or not.
            plugin_config: Custom configuration to be passed to the auth plugin
                           when invoked. The parameters defined here will override
                           the ones defined in the auth plugin itself.

        Returns:
            auth_response: Authorization plugin response.
            auth_strategy: Authorization plugin instance created based
                           on the provided `auth_plugin` and `auth_plugin_class`
                           parameters.

        Raises:
            InterfaceError: If authentication fails or when got a NULL auth response.
        rE   r7   )rb   NzFailed authentication: z8Got NULL auth response while authenticating with plugin )	r   r   Úauth_responseÚ	TypeErrorr   Únamer   Úlc_intrF   )
r]   r^   r_   r`   ra   rb   rc   Úauth_strategyrd   Úerrr4   r4   r5   Úauth_plugin_first_responseÞ   s*    "ÿÿ&ÿÿz(MySQLProtocol.auth_plugin_first_responser   r"   zOptional[Dict[str, str]])Ú	handshaker^   r_   rY   ÚcharsetrX   Úmax_allowed_packetr`   ra   rD   Úis_change_user_requestrb   rc   r0   c              
   C  s   |  ¡ }g }|
rt d¡ t d¡ | du r6tdƒd‚|  d¡du rNtdƒd‚z|pZ| d }W n: ttfy˜ } ztd|› d	�ƒd‚W Y d}~n
d}~0 0 t d
|¡ |
rÎ| t 	dt
|ƒ› d�tj|¡¡ n,d}| t 	d|› t
|ƒ› d�||||¡¡ tj| d ||||||d�\}}| |¡ | t ||¡¡ |
�rN| t 	d|¡¡ |tj@ �rl| |  ¡ d ¡ |tj@ �r’|	du�r’| t |	¡¡ d |¡|fS )a²  Make a MySQL Authentication packet.

        Args:
            handshake: Initial handshake.
            username: Account's username.
            password: Account's password.
            database: Initial database name for the connection
            charset: Client charset (see [2]), only the lower 8-bits.
            client_flags: Integer representing client capabilities flags.
            max_allowed_packet: Maximum packet size.
            auth_plugin: Authorization plugin name.
            auth_plugin_class: Authorization plugin class (has higher precedence
                               than the authorization plugin name).
            conn_attrs: Connection attributes.
            is_change_user_request: Whether is a `change user request` operation or not.
            ssl_enabled: Whether SSL is enabled or not.
            plugin_config: Custom configuration to be passed to the auth plugin
                           when invoked. The parameters defined here will override
                           the one defined in the auth plugin itself.

        Returns:
            handshake_response: Handshake response as per [1].
            auth_strategy: Authorization plugin instance created based
                           on the provided `auth_plugin` and `auth_plugin_class`.

        Raises:
            ProgrammingError: Handshake misses authentication info.

        References:
            [1]: https://dev.mysql.com/doc/dev/mysql-server/latest/                page_protocol_connection_phase_packets_protocol_handshake_response.html

            [2]: https://dev.mysql.com/doc/dev/mysql-server/latest/                page_protocol_basic_character_set.html#a_protocol_character_set
        zGot a `change user` requestzStarting authorization phaseNzGot a NULL handshaker]   z$Handshake misses authentication infor`   z-Handshake misses authentication plugin info (ú)z#The provided initial strategy is %srL   ZsxZxxxxxxxxxxxxxxxxxxxxxxxz<IIB)r]   r^   r_   r`   ra   rb   rc   ú<Hr7   rK   )rS   r   Údebugr   Úgetre   ÚKeyErrorrR   rP   rQ   rF   r   ZCHANGE_USERr-   rj   rZ   r   ÚPLUGIN_AUTHZCONNECT_ARGSrV   rT   )rk   r^   r_   rY   rl   rX   rm   r`   ra   rD   rn   rb   rc   Z
b_usernameZresponse_payloadri   Zfillerrd   rh   r4   r4   r5   Ú	make_auth  sl    3




ÿþýÿûÿù
	
zMySQLProtocol.make_auth)rl   rX   rm   r0   c                 C  s$   d  t |¡t |¡t | ¡dg¡S )a“  Make a SSL authentication packet (see [1]).

        Args:
            charset: Client charset (see [2]), only the lower 8-bits.
            client_flags: Integer representing client capabilities flags.
            max_allowed_packet: Maximum packet size.

        Returns:
            ssl_request_pkt: SSL connection request packet.

        References:
            [1]: https://dev.mysql.com/doc/dev/mysql-server/latest/                page_protocol_connection_phase_packets_protocol_ssl_request.html

            [2]: https://dev.mysql.com/doc/dev/mysql-server/latest/                page_protocol_basic_character_set.html#a_protocol_character_set
        rK   s                          )rT   r   Ú	int4storeÚ	int1store)rl   rX   rm   r4   r4   r5   Úmake_auth_ssl•  s    üÿzMySQLProtocol.make_auth_sslzOptional[bytes])ÚcommandÚargumentr0   c                 C  s   t  | ¡}|du r|S || S )z(Make a MySQL packet containing a commandN)r   rw   )ry   rz   Údatar4   r4   r5   Úmake_command¶  s    
zMySQLProtocol.make_commandr   )Ústatement_idÚrowsr0   c                 C  s   t  | ¡t  |¡ S )z0Make a MySQL packet with Fetch Statement command)r   rv   )r}   r~   r4   r4   r5   Úmake_stmt_fetch¼  s    zMySQLProtocol.make_stmt_fetch)Úpacketr0   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|rÜt
d|d ƒnd}| d|… }| |d… } |d dk�r|dd… }|tj@ �rrd| v�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   r2   Úprotocolz$Protocol mismatch; server version = z, client version = Nr7   r8   Zserver_version_originalz<I8sx2sBH2sBxxxxxxxxxxé   Zserver_threadidrl   Zserver_statusrK   é   é   r:   z5.5.8r`   úutf-8Zmysql_native_passwordr]   Úcapabilities)rP   ÚunpackÚPROTOCOL_VERSIONr   r   r<   r=   Zintreadr   ZSECURE_CONNECTIONÚminrt   Ú
startswith)	r€   ÚresZ
auth_data1Zcapabilities1Zcapabilities2Zauth_data_lengthr‡   Z
auth_data2Úsizer4   r4   r5   Úparse_handshakeÁ  sR    ÿÿÿøÿzMySQLProtocol.parse_handshaker#   c              
   C  sì   | d dkst dƒ‚i }z 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yæ } zt dƒ|‚W Y d}~n
d}~0 0 |S )zParse a MySQL OK-packetr1   r   z#Failed parsing OK packet (invalid).r�   r2   Zfield_countNZaffected_rowsZ	insert_idz<HHÚstatus_flagÚwarning_countZinfo_msgr†   zFailed parsing OK packet.)r   rP   rˆ   r   Úread_lc_intÚread_lc_stringr=   Ú
ValueError)r€   Z	ok_packetri   r4   r4   r5   Úparse_okõ  s$    ý zMySQLProtocol.parse_okzOptional[int]c              
   C  sV   zt  | dd… ¡d }|W S  tjtfyP } ztdƒ|‚W Y d}~n
d}~0 0 dS )z=Parse a MySQL packet with the number of columns in result setr1   Nr   zFailed parsing column count)r   r‘   rP   Úerrorr“   r   )r€   Úcountri   r4   r4   r5   Úparse_column_count  s
    z MySQLProtocol.parse_column_countr†   r    )r€   Úencodingr0   c              	   C  sº   t  | dd… ¡\} }t  | ¡\} }t  | ¡\} }t  | ¡\} }t  | ¡\} }t  | ¡\} }zt d| ¡\}}}}}W n tjy”   tdƒd‚Y n0 | |¡|dddd| tj@ ||f	S )zParse a MySQL column-packet.r1   Nz	<xHIBHBxxz!Failed parsing column information)	r   r’   rP   rˆ   r•   r   r=   r   ZNOT_NULL)r€   r˜   Ú_rf   rl   Zcolumn_typeÚflagsr4   r4   r5   Úparse_column  s6    
úû
÷zMySQLProtocol.parse_columnr!   c              
   C  sœ   |d dkr|   |¡S d}i }zt d|¡}W n0 tjy^ } zt|ƒ|‚W Y d}~n
d}~0 0 |d dkrxt|ƒdks€t|ƒ‚|d	 |d
< |d |d< |S )zParse a MySQL EOF-packetr1   r   zFailed parsing EOF packet.z<xxxBBHHNr   r(   é	   r)   r�   é   r�   )r”   rP   rˆ   r•   r   rF   )Úselfr€   Úerr_msgrŒ   Úunpackedri   r4   r4   r5   Ú	parse_eof6  s    
 zMySQLProtocol.parse_eofTr$   )r€   Úwith_headerr0   c           	      C  s"  d}i }dg}d}|r*| dd…   d¡}n
|   d¡}|D ]ä}zdd„ |  dd	¡D ƒ\}}W n. tyˆ } zt|ƒ|‚W Y d}~n
d}~0 0 | d
¡}zt|ƒ||< W q8 ttf�y   zt| d
¡ƒ||< W nF t�y } z,t|› d|› dt|ƒ› d�ƒ|‚W Y d}~n
d}~0 0 Y q80 q8|S )zParse the statistics packetz)Failed getting COM_STATISTICS informationrK   r1   Ns     c                 S  s   g | ]}|  ¡ ‘qS r4   )Ústrip)rG   Úvr4   r4   r5   Ú
<listcomp>X  rK   z2MySQLProtocol.parse_statistics.<locals>.<listcomp>ó   :r)   r†   z (ú:ro   )	Úsplitr“   r   r=   rW   rs   r   r   Úrepr)	r€   r¢   ÚerrmsgrŒ   ÚpairsZlblÚpairÚvalri   r4   r4   r5   Úparse_statisticsJ  s*    
 
>zMySQLProtocol.parse_statisticsr&   zTuple[int, ...]zATuple[List[Tuple[Optional[bytes], ...]], Optional[EofPacketType]])ÚsockÚversionr–   Úread_timeoutr0   c                 C  s(  |}g }d}d}d}	|s |	|kr$�q |  |¡}
|
 d¡rœ|
dd… g}|  |¡}
|
 d¡rx| |
dd… ¡ |  |¡}
qP| |
dd… ¡ t d |¡¡}nB|
d dkrÄ|
d dk rÄ|  |
¡}d}nd}t t|
dd… ƒ¡}|du rú|durú| |¡ n|du �r|du �rt|
ƒ‚|	d7 }	q||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   s   ÿÿÿr1   rK   r(   é   r   )	Úrecvr‹   rR   r   Zread_lc_string_listrT   r¡   r.   r   )rž   r¯   r°   r–   r±   r™   r~   ÚeofZrowdataÚir€   Zdatasr4   r4   r5   Úread_text_resultg  s6    





zMySQLProtocol.read_text_resultzTuple[bytes, int])r€   Úfieldr0   c                 C  s¨   |d t jkrd}d}nV|d t jkr0d}d}n>|d t jt jfv rNd}d}n |d t jkrfd}d}ntd	ƒ‚|d
 tj@ r„| 	¡ }| |d… t
 || d|… ¡d fS )z%Parse an integer from a binary packetr   ú<bú<hr)   ú<ir1   ú<qr…   zUnknown integer typer²   Nr   )r   ÚTINYÚSHORTÚINT24ÚLONGÚLONGLONGr“   r   ZUNSIGNEDÚupperrP   rˆ   )r€   r·   Úformat_Úlengthr4   r4   r5   Ú_parse_binary_integer—  s     z#MySQLProtocol._parse_binary_integerzTuple[bytes, float]c                 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…   ú<dr1   z<fNr   )r   ÚDOUBLErP   rˆ   )r€   r·   rÃ   rÂ   r4   r4   r5   Ú_parse_binary_float±  s    z!MySQLProtocol._parse_binary_floatÚutf8zTuple[bytes, Decimal])r€   rl   r0   c                 C  s    t  | ¡\} }| t| |¡ƒfS )z(Parse a New Decimal from a binary packet)r   r’   r   r=   )r€   rl   Úvaluer4   r4   r5   Ú_parse_binary_new_decimal¿  s    z'MySQLProtocol._parse_binary_new_decimalz?Tuple[bytes, Optional[Union[datetime.date, datetime.datetime]]])r€   Ú
field_typer0   c              	   C  sô   | d }d}|dkrpt  d| dd… ¡d }| d }| d }|tjtjfv r^tj|||d�}qàtj|||d�}np|dkràd}|d	kr t  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   Nr1   rp   r   r�   )ÚyearÚmonthÚdayr²   é   ú<Ir…   r2   é   )rÌ   rÍ   rÎ   ÚhourÚminuteÚsecondÚmicrosecond)rP   rˆ   r   ÚDATETIMEÚ	TIMESTAMPÚdatetimeÚdate)r€   rË   rÃ   rÉ   rÌ   rÍ   rÎ   Úmcsr4   r4   r5   Ú_parse_binary_timestampÇ  s.    ù
z%MySQLProtocol._parse_binary_timestampz Tuple[bytes, datetime.timedelta]c                 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   Nr…   rÐ   r2   r:   r²   rÑ   )ÚdaysÚsecondsÚmicrosecondsÚminutesÚhours)rØ   Ú	timedeltarP   rˆ   )r€   rÃ   r{   rÚ   rÜ   Útmpr4   r4   r5   Ú_parse_binary_timeç  s$    ûz MySQLProtocol._parse_binary_timezList[DescriptionType]zTuple[BinaryProtocolType, ...])Úfieldsr€   rl   r0   c           
   	   C  s6  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v r¼|  
||	¡\}}| |¡ qF|	d tjtjfv rì|  ||	¡\}}| |¡ qF|	d tjtjfv �r|  ||¡\}}| |¡ qF|	d tjtjtjfv �rX|  ||	d ¡\}}| |¡ qF|	d tjk�r‚|  |¡\}}| |¡ qF|	d tjk�r²t |¡\}}| t |¡¡ qF|	d tjk�sÐ|	d d	k�rêt |¡\}}| |¡ qFt |¡\}}z| | |¡¡ W qF t�y*   | |¡ Y qF0 qFt |ƒS )
z(Parse values from a binary result packetr²   r)   r…   c                 S  s   g | ]}t |ƒ‘qS r4   )rW   )rG   rµ   r4   r4   r5   r¥     rK   z6MySQLProtocol._parse_binary_values.<locals>.<listcomp>r   Nr   é?   )!rF   Ú	enumeraterW   rR   r   r¼   r½   r¾   r¿   rÀ   rÄ   rÆ   ÚFLOATrÇ   ÚDECIMALZ
NEWDECIMALrÊ   rÖ   ÚDATEr×   rÛ   ÚTIMErã   ZVECTORr   r’   r   Z_vector_to_pythonr   ZBINARYr=   ÚUnicodeDecodeErrorÚtuple)
rž   rä   r€   rl   Znull_bitmap_lengthÚnull_bitmaprO   rÉ   Úposr·   r4   r4   r5   Ú_parse_binary_valuesþ  s\    $
ûýz"MySQLProtocol._parse_binary_valueszDTuple[List[Tuple[BinaryProtocolType, ...]], Optional[EofPacketType]])r¯   Úcolumnsr–   rl   r±   r0   c                 C  sº   g }d}d}d}	|durq²|	|kr$q²t | |¡ƒ}
|
d dkrN|  |
¡}d}n&|
d dkrtd}|  ||
dd… |¡}|du r�|dur�| |¡ n|du r¨|du r¨t|
ƒ‚|	d7 }	q||fS )zwRead MySQL binary protocol result

        Reads all or given number of binary resultset rows from the socket.
        Nr   r1   r(   r2   r   )r.   r³   r¡   rï   rR   r   )rž   r¯   rð   r–   rl   r±   r~   r´   rO   rµ   r€   r4   r4   r5   Úread_binary_result8  s*    

z MySQLProtocol.read_binary_resultzDict[str, int]c              
   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y® } zt dƒ|‚W Y d}~n
d}~0 0 |S )z(Parse a MySQL Binary Protocol OK packet.r1   r   zFailed parsing Binary OK packetr2   Nr}   r)   Znum_columnsZ
num_paramsr   r�   )r   r   r@   r“   )r€   Zok_pktri   r4   r4   r5   Úparse_binary_prepare_ok^  s     z%MySQLProtocol.parse_binary_prepare_okzTuple[bytes, int, int])rÉ   r0   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}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   €rº   r»   é€   r*   rL   iÿÿ  rp   l   ÿÿ rÐ   z<Q)r   r¼   r½   r¿   rÀ   rP   rQ   )rÉ   rË   rš   rÂ   r4   r4   r5   Úprepare_binary_integerp  s6    z$MySQLProtocol.prepare_binary_integerz'Union[datetime.date, datetime.datetime]c                 C  sÂ   t | tjƒrtj}nt | tjƒr(tj}ntdƒ‚t | j	¡t 
| j¡t 
| j¡g}t | tjƒr¢| t 
| j¡t 
| j¡t 
| j¡g¡ | jdkr¢| t | j¡¡ d |¡}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   rK   )Ú
isinstancerØ   r   rÖ   rÙ   ré   r“   r   Ú	int2storerÌ   rw   rÍ   rÎ   ÚextendrÒ   rÓ   rÔ   rÕ   rR   rv   rT   rF   )rÉ   rË   ÚchunksÚpackedr4   r4   r5   Úprepare_binary_timestamp’  s(    


ý


ýÿ

z&MySQLProtocol.prepare_binary_timestampz(Union[datetime.timedelta, datetime.time]c           
      C  s  t | tjtjfƒstdƒ‚tj}d}d}tg ƒ}t | tjƒr | jdk rJd}t	| j
dƒ\}}t	|dƒ\}}| t t| jƒ¡t |¡t |¡t |¡g¡ | j}n6| t d¡t | j¡t | j¡t | j¡g¡ | j}|rê| t |¡¡ | t |¡¡ d |¡}	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   i  é<   rK   )rõ   rØ   rá   Útimer“   r   rê   r   rÜ   ÚdivmodrÝ   r÷   r   rv   Úabsrw   rÞ   rÒ   rÓ   rÔ   rÕ   rR   Ú
appendleftrT   rF   )
rÉ   rË   ÚnegativerÚ   rø   rà   Ú	remainderZminsZsecsrù   r4   r4   r5   Úprepare_binary_time½  s@    
üÿ


üÿ
z!MySQLProtocol.prepare_binary_time)Ú	statementÚparamr{   r0   c                 C  s   d  t | ¡t |¡|g¡S )zMPrepare long data for prepared statements

        Returns a string.
        rK   )rT   r   rv   rö   )r  r  r{   r4   r4   r5   Úprepare_stmt_send_long_dataõ  s    z)MySQLProtocol.prepare_stmt_send_long_datar4   zSequence[BinaryProtocolType]r   z Optional[Dict[int, Tuple[bool]]]z.Optional[List[Tuple[str, BinaryProtocolType]]])	r}   r{   Ú
parametersrš   Úlong_data_usedrl   Úquery_attrsÚconverter_str_fallbackr0   c	              	   C  s  d}	dgt |ƒd d  }
g }g }d}t |ƒ}g }|s:|n|t }|dkrNd}|du rZi }|r”t|ƒ}|D ]\}}| |¡ qjdgt |ƒd d  }
|sž|�r*|t |ƒkr²td	ƒ‚t|ƒD �]l\}}d}|du �r|
|d   d|d > O  < | t tj	¡t |¡ ¡ qº||v �r6|| d �r,tj
}ntj}�nšt|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}nÊt|tƒ�r,| t d
|¡¡ tj}n¤t|tjtjfƒ�rZ|  |¡\}}| |¡ nvt|tjtjfƒ�rˆ|  |¡\}}| |¡ nH|�r¼t|ƒ |¡}| t t |ƒ¡| ¡ tj}ntd|j j!› d�ƒ‚| t |¡t |¡ ¡ |rº|d |krº|||  d  |¡}| t t |ƒ¡| ¡ qºt "|¡t |¡t "|	¡g}|du�r^|t |ƒ }n|}|�r|du�r‚| t |¡¡ | #dd„ |
D ƒ¡ | t d¡¡ d}|D ]N}| |¡ |du�rò|d |k�rè| |||  ¡ n
| d¡ |d7 }�q®|D ]}| |¡ �qd $|¡S )z6Make a MySQL packet with the Statement Execute commandr   r   r²   r…   rK   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)rP   rQ   )rG   Úbitr4   r4   r5   r¥   n  rK   z3MySQLProtocol.make_stmt_execute.<locals>.<listcomp>r7   )%rF   r   ÚlistrR   r   ræ   r   rw   r   ZNULLZBLOBÚSTRINGrõ   rW   rô   r[   rS   rg   r.   r   rè   ÚfloatrP   rQ   rÆ   rØ   rÙ   rú   rá   rü   r  r   Ú	__class__Ú__name__rv   r÷   rT   )rž   r}   r{   r  rš   r  rl   r  r	  Ziteration_countrí   rO   Útypesrù   Zdata_lenZquery_attr_namesr™   Zattr_valrî   rÉ   Ú_flagsrË   rf   r€   Zparameter_countr–   Úa_typeZa_valuer4   r4   r5   Úmake_stmt_executeý  sÈ    
ÿ
ÿ

ü


ÿÿÿÿý




zMySQLProtocol.make_stmt_execute)NFN)N)r   )r†   )T)r   N)rÈ   )r†   )r   r†   N)r4   r4   r   NrÈ   NF)%r  Ú
__module__Ú__qualname__Ú__doc__Ústaticmethodr6   r?   rC   rV   rZ   rj   ÚDEFAULT_CHARSET_IDÚDEFAULT_MAX_ALLOWED_PACKETru   rx   r|   r   rŽ   r”   r—   r›   r¡   r®   r¶   rÄ   rÇ   rÊ   rÛ   rã   rï   rñ   rò   rô   rú   r  r  r  r4   r4   r4   r5   r-   X   s¬      ù <ó,yý 3    û0 ÿ ü>   ú&!*7
       ÷r-   )>r  Ú
__future__r   rØ   rP   Úcollectionsr   Údecimalr   r   Útypingr   r   r   r	   r
   r   r   r   r   rE   r   Ú	constantsr   r   r   r   r   Ú
conversionr   Úerrorsr   r   r   r   r   Zpluginsr   r   Zplugins.caching_sha2_passwordr   r  r   r    r!   r"   r#   r$   r%   Únetworkr&   r‰   r;   r3   Z	OK_STATUSZ
EOF_STATUSrA   Z
ERR_STATUSZLOCAL_INFILE_STATUSr  r  r-   r4   r4   r4   r5   Ú<module>   s6   ,$
