B
    Ñš[Ü  ã               @   sè  d Z ddlZddlZddlZddlZddlmZ ddlmZ ddlm	Z	 ddl
Z
ddlZddlZy,ddlmZmZmZ ddlZddlmZ W n@ ek
rÌ   ddlmZmZmZ ddlmZ ddlmZ Y nX ejd dk�rydd	lmZ W n ek
�r   d
ZY nX dZn0ydd	lmZ W n ek
�r:   d
ZY nX dZddlZddl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)m*Z* ddl+m,Z,m-Z-m.Z.m/Z/ ddl0m1Z1 ddl0m2Z2m3Z3 ddl4m5Z5 ddl6m7Z7 ddl0m8Z8 ddl9m:Z:m;Z;m<Z< e1j=e1j>fZ?e1j=e1j@e1jAe1jBe1jCfZDg aEdZFdddœZGi ZHdZIdZJdZKdZLdZMdZNdZOdZPdZQdZRdZSdZTdZUdZVeWfd dfeXeYeWejejZge[e<ƒ ƒd!dfeXe[fd"dfeYfd#eOfeWfd$dfeWfd%dfeWfd&eUfeYfd'eLfeYfd(eKfd)œ	Z\e
 ]d*¡Z^G d+d,„ d,e_ƒZ`G d-d.„ d.e_ƒZaG d/d0„ d0e_ƒZbG d1d2„ d2ebƒZcG d3d4„ d4e_ƒZdG d5d6„ d6edƒZed7d8„ Zfd9d:„ Zgd;d<„ Zhd=d>„ Zie�r„G d?d@„ d@ejjƒZkG dAdB„ dBeƒZlG dCdD„ dDe_ƒZmG dEdF„ dFe_ƒZnG dGdH„ dHenƒZoG dIdJ„ dJenƒZpG dKdL„ dLe_ƒZqdS )Mz,Implementing communication with MySQL Fabricé    N)Ú	b16decode)Úbisect)Úmd5)ÚFaultÚServerProxyÚ	Transport)ÚBadStatusLineé   )ÚHTTPSConnectionFT)ÚMySQLConnection)ÚMySQLConverter)ÚMySQLConnectionPool)ÚErrorÚInterfaceErrorÚNotSupportedErrorÚMySQLFabricErrorÚInternalErrorÚDatabaseError)ÚMySQLCursorÚMySQLCursorBufferedÚMySQLCursorRawÚMySQLCursorBufferedRaw)Ú	errorcodeé   )ÚFabricMySQLServerÚFabricShard)ÚFabricCache)ÚWeightedRoundRobin)Úversion)ÚPY2Ú	isunicodeÚUNICODE_TYPESÚxmlrpci~  i~  )r"   Úmysqlé   ÚGLOBALÚLOCALZFAULTYzName of group of serverszSharding keyzList of tables in queryz#Read-Only, Write-Only or Read-Writez+Identity of the shard for direct connectionÚ z+GLOBAL for accessing Global Group, or LOCALzAttempts for getting connectionz$Seconds to wait between each attempt)	ÚgroupÚkeyÚtablesÚmodeZshardÚmappingÚscopeÚattemptsÚattempt_delayzmyconnpy-fabricc               @   sB   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	d
„Zdd„ Zdd„ Z	dS )ÚMySQLRPCProtocolz0Class using MySQL protocol to query Fabric.
    c             C   s(   t ƒ | _t|||||ƒ| _| j ¡  d S )N)r   Ú	converterÚFabricMySQLConnectionÚhandlerÚconnect)ÚselfÚfabricÚhostÚportÚconnect_attemptsÚconnect_delay© 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\fabric\connection.pyÚ__init__™   s
    zMySQLRPCProtocol.__init__c          
   C   sž   y`g }xVt | ¡ ƒD ]F\}}|}| j |¡}| j |¡}| j |¡}| d |t|ƒ¡¡ qW W n4 t	k
r” } zt
jj d| ¡‚W dd}~X Y nX |S dS )z,Process query parameters given as dictionaryz{0}={1}z)Failed processing pyformat-parameters; %sN)ÚlistÚitemsr1   Úto_mysqlÚescapeÚquoteÚappendÚformatÚstrÚ	Exceptionr#   Ú	connectorÚerrorsÚProgrammingError)r5   ÚparamsÚresr)   ÚvalueÚconvÚerrr;   r;   r<   Ú_process_params_dict    s    z%MySQLRPCProtocol._process_params_dictc          
      sŽ   yL|}‡ fdd„|D ƒ}‡ fdd„|D ƒ}‡ fdd„|D ƒ}dd„ |D ƒ}W n4 t k
r€ } ztjj d| ¡‚W dd}~X Y n
X t|ƒS dS )zProcess query parameters.c                s   g | ]}ˆ j  |¡‘qS r;   )r1   r@   )Ú.0Úi)r5   r;   r<   ú
<listcomp>´   s    z4MySQLRPCProtocol._process_params.<locals>.<listcomp>c                s   g | ]}ˆ j  |¡‘qS r;   )r1   rA   )rP   rQ   )r5   r;   r<   rR   µ   s    c                s   g | ]}ˆ j  |¡‘qS r;   )r1   rB   )rP   rQ   )r5   r;   r<   rR   ¶   s    c             S   s   g | ]}t |ƒ‘qS r;   )rE   )rP   rQ   r;   r;   r<   rR   ·   s    z'Failed processing format-parameters; %sN)rF   r#   rG   rH   rI   Útuple)r5   rJ   rK   rN   r;   )r5   r<   Ú_process_params°   s    z MySQLRPCProtocol._process_paramsNc             C   sH   |sd}| j jjdd�}g }x&|j||dd�D ]}| | ¡ ¡ q.W |S )zYExecutes the given query

        Returns a list containing response from Fabric
        r;   T)Ú
dictionary)Zmulti)r3   Ú
connectionÚcursorÚexecuterC   Zfetchall)r5   ZstmtrJ   ÚcurÚresultsrK   r;   r;   r<   Ú_execute_cmd¾   s    zMySQLRPCProtocol._execute_cmdc             O   sB   g }|r|   |¡}| |¡ |r4|  |¡}| |¡ d |¡}|S )z6Process arguments to create query parameters.
        z, )rT   ÚextendrO   Újoin)r5   ÚargsÚkwargsrJ   r;   r;   r<   Úcreate_paramsÍ   s    




zMySQLRPCProtocol.create_paramsc          
   O   s€   | j ||Ž}d |||¡}d}y|  |¡}t|ƒ}W nF ttjtfk
rz }	 z dj||t|	ƒd�}
t|
ƒ‚W dd}	~	X Y nX |S )zÝExecutes the given command with MySQL protocol

        Executes the given command with the given parameters.

        Returns an iterator to navigate to navigate through the result set
        returned by Fabric
        zCALL {0}.{1}({2})Nz+Executing {group}.{command} failed: {error})r(   ÚcommandÚerror)	r`   rD   r[   ÚFabricMySQLSetr   Úsocketrb   r   rE   )r5   r(   ra   r^   r_   rJ   ÚcmdÚfab_setÚdataÚexcÚmsgr;   r;   r<   rX   Û   s    
zMySQLRPCProtocol.execute)N)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r=   rO   rT   r[   r`   rX   r;   r;   r;   r<   r0   –   s   
r0   c               @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚXMLRPCProtocolz2Class using XML-RPC protocol to query Fabric.
    c             C   s    t |||||ƒ| _| j ¡  d S )N)ÚFabricXMLRPCConnectionr3   r4   )r5   r6   r7   r8   r9   r:   r;   r;   r<   r=   õ   s    
zXMLRPCProtocol.__init__c          
   O   s¾   yt | jj|ƒ}t ||ƒ}W n: tk
rV } ztdj||t|ƒd�ƒ‚W dd}~X Y nX d}y|||Ž}	t|	ƒ}W nF tt	j
tfk
r¸ } z dj||t|ƒd�}
t|
ƒ‚W dd}~X Y nX |S )zÞExecutes the given command with XML-RPC protocol

        Executes the given command with the given parameters

        Returns an iterator to navigate to navigate through the result set
        returned by Fabric
        z'{group}.{command} not available ({err}))r(   ra   rN   Nz+Executing {group}.{command} failed: {error})r(   ra   rb   )Úgetattrr3   ÚproxyÚAttributeErrorÚ
ValueErrorrD   rE   Ú	FabricSetr   rd   rb   r   )r5   r(   ra   r^   r_   Úgrpre   rh   rf   rg   ri   r;   r;   r<   rX   ú   s    $
zXMLRPCProtocol.executeN)rj   rk   rl   rm   r=   rX   r;   r;   r;   r<   rn   ò   s   rn   c               @   s   e Zd ZdZdd„ ZdS )ÚFabricMySQLResponsezHClass used to parse a response got from Fabric with MySQL protocol.
    c             C   sN   |d d }|d |d |d   }}}|r4t |ƒ‚|| _|| _|d | _d S )Nr   Úfabric_uuidÚttlÚmessager   )r   Úfabric_uuid_strrx   Ú
coded_rows)r5   rg   Úinforz   rx   rb   r;   r;   r<   r=     s    zFabricMySQLResponse.__init__N)rj   rk   rl   rm   r=   r;   r;   r;   r<   rv     s   rv   c                   s8   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Z‡  ZS )
rc   z^Iterator to navigate through the result set returned from Fabric
    with MySQL Protocol.
    c                s<   t t| ƒ |¡ | jd  ¡ | _| j| _t d| j¡| _	dS )z)Initialize the FabricSet object.
        r   Ú	ResultSetN)
Úsuperrc   r=   r{   ÚkeysZ_FabricMySQLSet__namesÚ_FabricMySQLSet__rowsÚcollectionsÚ
namedtupleÚ_FabricMySQLSet__result)r5   rg   )Ú	__class__r;   r<   r=   (  s    zFabricMySQLSet.__init__c             C   s
   t | jƒS )z.The number of rows in the result set.
        )Úlenr€   )r5   r;   r;   r<   Úrowcount0  s    zFabricMySQLSet.rowcountc             c   s"   x| j D ]}| jf |ŽV  qW dS )zUIterate over the rows of the result set.

        Each row is a named tuple.
        N)r€   rƒ   )r5   Úrowr;   r;   r<   Úrows5  s    zFabricMySQLSet.rowsc             C   s   | j f | j| ŽS )zGIndexing method for a row.

        Each row is a named tuple.
        )rƒ   r€   )r5   Úindexr;   r;   r<   r‡   =  s    zFabricMySQLSet.row)	rj   rk   rl   rm   r=   r†   rˆ   r‡   Ú__classcell__r;   r;   )r„   r<   rc   $  s
   rc   c               @   s   e Zd ZdZdZdd„ ZdS )ÚFabricResponsez4Class used to parse a response got from Fabric.
    r   c             C   sT   |\}}}}}|rt |ƒ‚|tjkr8t djtj|d�ƒ‚|| _|| _|| _|| _dS )z-Initialize the FabricResponse object
        zdSupported protocol has version {sversion}. Got a response from MySQL Fabric with version {gversion}.)ZsversionZgversionN)r   r‹   ÚSUPPORTED_VERSIONrD   Úformat_versionrz   rx   r{   )r5   rg   r�   rz   rx   rb   rˆ   r;   r;   r<   r=   K  s    

zFabricResponse.__init__N)rj   rk   rl   rm   rŒ   r=   r;   r;   r;   r<   r‹   E  s   r‹   c                   s8   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Z‡  ZS )
rt   zEIterator to navigate through the result set returned from Fabric
    c                s„   t tˆ ƒ |¡ tˆ jƒdks"t‚ˆ jd d d ˆ _ˆ jd d ˆ _t‡ fdd„ˆ jD ƒƒsptˆ jƒdkspt‚t	 
dˆ j¡ˆ _d	S )
z)Initialize the FabricSet object.
        r   r   r|   Únamesrˆ   c             3   s    | ]}t ˆ jƒt |ƒkV  qd S )N)r…   Ú_FabricSet__names)rP   r‡   )r5   r;   r<   ú	<genexpr>h  s    z%FabricSet.__init__.<locals>.<genexpr>r}   N)r~   rt   r=   r…   r{   ÚAssertionErrorr�   Ú_FabricSet__rowsÚallr�   r‚   Ú_FabricSet__result)r5   rg   )r„   )r5   r<   r=   a  s    zFabricSet.__init__c             C   s
   t | jƒS )z.The number of rows in the result set.
        )r…   r’   )r5   r;   r;   r<   r†   l  s    zFabricSet.rowcountc             c   s    x| j D ]}| j|Ž V  qW dS )zUIterate over the rows of the result set.

        Each row is a named tuple.
        N)r’   r”   )r5   r‡   r;   r;   r<   rˆ   q  s    zFabricSet.rowsc             C   s   | j | j| Ž S )zGIndexing method for a row.

        Each row is a named tuple.
        )r”   r’   )r5   r‰   r;   r;   r<   r‡   y  s    zFabricSet.row)	rj   rk   rl   rm   r=   r†   rˆ   r‡   rŠ   r;   r;   )r„   r<   rt   ^  s
   rt   c             C   sZ   | sg a t| ttfƒs| g} x8| D ]0}t|tƒr@|dkr@|dk sHtdƒ‚t  |¡ q"W dS )ax  Add MySQL error to be reported to Fabric

    This function adds error_codes to the error list to be reported to
    Fabric. To reset the custom error reporting list, pass None or empty
    list.

    The error_codes argument can be either a MySQL error code defined in the
    errorcode module, or list of error codes.

    Raises AttributeError when code is not an int.
    iè  i¸  zUnknown or invalid error code.N)ÚREPORT_ERRORS_EXTRAÚ
isinstancer>   rS   Úintrr   rC   )Zerror_codesÚcoder;   r;   r<   Úextra_failure_report�  s    
r™   c             C   s   dj | |d�S )zÀCreate an XMLRPC URI for connecting to Fabric

    This method will create a URI using the host and TCP/IP
    port suitable for connecting to a MySQL Fabric instance.

    Returns a URI.
    zhttp://{host}:{port})r7   r8   )rD   )r7   r8   r;   r;   r<   Ú_fabric_xmlrpc_uri›  s    rš   c             C   s   t  t jt| |ƒ¡S )z!Create a UUID using host and port)ÚuuidÚuuid3ÚNAMESPACE_URLrš   )r7   r8   r;   r;   r<   Ú_fabric_server_uuid¦  s    rž   c             C   sN   t stdƒ‚t| ||gƒrJ| s&tdƒ‚|s.|r>|r6|s>tdƒ‚| ||dœS dS )zvValidate the SSL argument.

    Raises AttributeError is required argument is not set.

    Returns dict or None.
    zPython does not support SSLzMissing ssl_ca argument.z;ssl_key and ssl_cert need to be both specified, or neither.)Úcar)   ÚcertN)ÚHAVE_SSLr   Úanyrr   )Ússl_caÚssl_keyÚssl_certr;   r;   r<   Ú_validate_ssl_args«  s    r¦   c                   s2   e Zd ZdZ‡ fdd„Zdd„ Zd	dd„Z‡  ZS )
ÚFabricHTTPSHandlerz Class handling HTTPS connectionsc                s&   t rtj | ¡ n
tƒ  ¡  || _dS )Ú
InitializeN)r   Úurllib2ÚHTTPSHandlerr=   r~   Ú_ssl_config)r5   Ú
ssl_config)r„   r;   r<   r=   Ê  s    
zFabricHTTPSHandler.__init__c             C   s   |   | j|¡S )zOpen HTTPS connection)Údo_openÚget_https_connection)r5   Úreqr;   r;   r<   Ú
https_openÒ  s    zFabricHTTPSHandler.https_opené,  c             C   s   t || jd | jd d�S )zReturns a HTTPSConnectionr)   r    )Úkey_fileÚ	cert_file)r
   r«   )r5   r7   Útimeoutr;   r;   r<   r®   Ö  s    z'FabricHTTPSHandler.get_https_connection)r±   )rj   rk   rl   rm   r=   r°   r®   rŠ   r;   r;   )r„   r<   r§   Æ  s   r§   c                   s8   e Zd ZdZd ej¡Zd
‡ fdd„	Zddd	„Z	‡  Z
S )ÚFabricTransportz"Custom XMLRPC Transport for FabriczMySQL Connector Python/{0}r   FNc                s´   t rtj| dd� ntƒ jdd� || _|| _|| _|| _|| _|| _g | _| jrr| jrrt	 
¡ | _t	 | j¡| _nd| _d| _|r–| j |¡ d| _nd| _| jr°| j | j¡ dS )r¨   F)Úuse_datetimeNÚhttpsÚhttp)r   r   r=   r~   Ú	_usernameÚ	_passwordÚ_use_datetimeÚverboseÚ	_handlersr©   ÚHTTPPasswordMgrWithDefaultRealmÚ_passmgrÚHTTPDigestAuthHandlerZ_auth_handlerrC   Ú_scheme)r5   ÚusernameÚpasswordr¼   r¶   Úhttps_handler)r„   r;   r<   r=   å  s*    
zFabricTransport.__init__c             C   s8  dj | j||d�}| jr.| j d|| j| j¡ | jrDt d  |¡¡ t	j
| jŽ }d| jdœ}t	j|||d�}y|  | |¡¡S  t	jt	jfk
�r }	 zry2d}
|	jd	kr´d
}|	j}
n|	j}dj ||
d�}W n. tk
rø   dt|	ƒkrìd}nt|	ƒ}Y nX td| ƒ‚W dd}	~	X Y n tk
�r2   tdƒ‚Y nX dS )zSend XMLRPC requestz{scheme}://{host}{handler})Úschemer7   r3   NzFabricTransport: {0}ztext/xml)zContent-Typez
User-Agent)Úheaderséÿÿÿÿi�  zPermission deniedz{reason} ({code}))Úreasonr˜   ZSSLz	SSL errorzConnection with Fabric failed: z(Connection with Fabric failed: check SSL)rD   rÁ   r¿   Úadd_passwordr¹   rº   r¼   Ú_LOGGERÚdebugr©   Úbuild_openerr½   Ú
user_agentÚRequestÚparse_responseÚopenÚURLErrorÚ	HTTPErrorr˜   rÈ   rr   rE   r   r   )r5   r7   r3   Úrequest_bodyr¼   ÚuriÚopenerrÆ   r¯   rh   r˜   rÈ   ri   r;   r;   r<   Úrequest  s8    


zFabricTransport.request)r   FN)r   )rj   rk   rl   rm   rD   r   ZVERSION_TEXTrÍ   r=   rÖ   rŠ   r;   r;   )r„   r<   rµ   ß  s   rµ   c               @   s¶   e Zd ZdZdddeedddddefdd„Zedd„ ƒZ	edd	„ ƒZ
ed
d„ ƒZd!dd„Zd"dd„Zdd„ Zdd„ Zd#dd„Zd$dd„Zd%dd„Zd&dd„Zedfdd„Zdd „ ZdS )'ÚFabricz%Class managing MySQL Fabric instancesNFc             C   s¶   |dkrt | _n|dkr t| _ntd |¡ƒ‚|s:t| }i | _d| _d| _d| _	|| _
|| _tƒ | _i | _|| _|| _t||	|
ƒ| _|| _|| _|r¢|r¢tdƒ‚|p¨|| _|| _dS )r¨   r"   r#   z0Protocol not supported by MySQL Fabric, was '{}'Né<   z&can not specify both user and username)rn   Ú_protocol_classr0   r   rD   ÚMYSQL_FABRIC_PORTÚ_fabric_instancesÚ_fabric_uuidÚ_ttlÚ_version_tokenÚ_connect_attemptsÚ_connect_delayr   Ú_cacheÚ_group_balancersÚ
_init_hostÚ
_init_portr¦   Ú_sslÚ_report_errorsÚ	_protocolrs   r¹   rº   )r5   r7   rÂ   rÃ   r8   r9   r:   Zreport_errorsr£   r¤   r¥   ÚuserÚprotocolr;   r;   r<   r=   1  s4    
zFabric.__init__c             C   s   | j S )z0Return username used to authenticate with Fabric)r¹   )r5   r;   r;   r<   rÂ   W  s    zFabric.usernamec             C   s   | j S )z0Return password used to authenticate with Fabric)rº   )r5   r;   r;   r<   rÃ   \  s    zFabric.passwordc             C   s   | j S )zReturn the SSL configuration)rå   )r5   r;   r;   r<   r¬   a  s    zFabric.ssl_configc             C   sî   |p| j }|p| j}| j| ||| j| jd�}|  |¡\}}}}|sJtdƒ‚| j|krXdS t 	dj
|d�¡ || _|| _|dkr„|| _xd|D ]\}| j| |d |d | j| jd�}	|	jj}
|
| jkrŠ|	| j|
< t d	j
|	jj|	jjd
�¡ qŠW dS )z×Get MySQL Fabric Instances

        This method uses host and port to connect to a MySQL Fabric server
        and get all the instances managing the same metadata.

        Raises InterfaceError on errors.
        )r9   r:   z%Failed getting list of Fabric serversNz.Loading Fabric configuration version {version})r   r   r7   r8   z%Added new Fabric server {host}:{port})r7   r8   )rã   rä   rÙ   rß   rà   Úget_fabric_serversr   rÞ   rÊ   r|   rD   rÜ   rÝ   r3   r›   rÛ   rË   r7   r8   )r5   r7   r8   Zfabinstrw   Úfabric_versionrx   Zfabricsr6   ÚinstZ	inst_uuidr;   r;   r<   Úseedf  s8    









zFabric.seedc             C   s<   |r&t  dj|d�¡ | j|dd� nt  d¡ tƒ | _dS )zWReset cached information

        This method destroys all cached information.
        z#Resetting cache for group '{group}')r(   F)Ú	use_cachezResetting cacheN)rÊ   rË   rD   Úget_group_serversr   rá   )r5   r(   r;   r;   r<   Úreset_cache“  s    

zFabric.reset_cachec             C   sb   d}d}| j st|d ƒ‚tr8| j  ¡ }| j ||  }n| j t| j ƒ|  }|jjs^|j ¡  |S )z·Get a MySQL Fabric Instance

        This method will get the next available MySQL Fabric Instance.

        Raises InterfaceError when no instance is available or connected.
        r   z"No MySQL Fabric instance availablez (not seeded?))rÛ   r   r   r   r>   r3   Úis_connectedr4   )r5   ZnxtÚerrmsgZinstance_listrì   r;   r;   r<   Úget_instance   s    

zFabric.get_instancec          
   C   sœ   | j s
dS t|ƒ}t ¡ }|tks*|tkr˜t d||¡ |  ¡ }y| 	dd|||¡}t
|ƒ W n8 ttjfk
r– } zt dt|ƒ¡ W dd}~X Y nX dS )z{Report failure to Fabric

        This method sets the status of a MySQL server identified by
        server_uuid.
        NzReporting error %d of server %sZthreatÚreport_failurez&Failed reporting server to Fabric (%s))ræ   r—   rd   ÚgetfqdnÚREPORT_ERRORSr•   rÊ   rË   ró   rX   r‹   r   rb   rE   )r5   Úserver_uuidÚerrnoZcurrent_hostrì   rg   rh   r;   r;   r<   rô   ´  s    
zFabric.report_failurec          
   C   s,  |p
|   ¡ }g }d}y>| ddd| j ¡}x$| ¡ D ]}| |j|jdœ¡ q4W W n– ttj	fk
rž } z(|j
t|ƒ|jj|jjd�}t|ƒ‚W dd}~X Y nL ttfk
rè } z*|j
d 
|¡|jj|jjd�}t|ƒ‚W dd}~X Y nX yt |j¡}	W n tk
�r   t ¡ }	Y nX d	}
|	|
|j|fS )
aÀ  Get all MySQL Fabric instances

        This method looks up the other MySQL Fabric instances which uses
        the same metadata. The returned list contains dictionaries with
        connection information such ass host and port. For example:

        [
            {'host': 'fabric_prod_1.example.com', 'port': 32274 },
            {'host': 'fabric_prod_2.example.com', 'port': 32274 },
        ]

        Returns a list of dictionaries
        z;Looking up Fabric servers failed using {host}:{port}: {err}ÚdumpZfabric_nodesz	protocol.)r7   r8   )rN   r7   r8   Nz No Fabric server available ({0})r   )ró   rX   rç   rˆ   rC   r7   r8   r   rd   rb   rD   rE   r3   r   Ú	TypeErrorrr   r›   ÚUUIDrz   Úuuid4rx   )r5   Z
fabric_cnxrì   ÚresultZerr_msgÚfsetr‡   rh   ri   rw   rë   r;   r;   r<   rê   Í  s.    zFabric.get_fabric_serversTc          
   C   s  |r| j  |¡}|r|jS |  ¡ }g }y| dd| j|¡}W nB ttjfk
r~ } zdj	t
|ƒ|d�}t|ƒ‚W dd}~X Y nX g }	xb| ¡ D ]V}
|
j|krŽt|
j|
j|
j|
j|
j|
j|
jƒ}| |¡ |jtkrŽ|	 |j|jf¡ qŽW | j  ||¡ |	�r
t|	Ž | j|< |S )a?  Get all MySQL servers in a group

        This method returns information about all MySQL part of the
        given high-availability group. When use_cache is set to
        True, the cached information will be used.

        Raises InterfaceError on errors.

        Returns list of FabricMySQLServer objects.
        rù   Úserversz:Looking up MySQL servers failed for group {group}: {error})rb   r(   N)rá   Zgroup_searchrÿ   ró   rX   rÞ   r   rd   rb   rD   rE   r   rˆ   Úgroup_idr   r÷   r7   r8   r+   ÚstatusZweightrC   ÚSTATUS_SECONDARYr›   Zcache_groupr   râ   )r5   r(   rî   Úentryrì   rý   rþ   rh   ri   Úweightsr‡   Úmysqlserverr;   r;   r<   rï   ÷  s2    


zFabric.get_group_serversc             C   s$  |r|rt dƒ‚d}| j|dd�}|s6t|j|d�ƒ‚d}g }x0|D ](}|jtkr^| |¡ qD|jtkrD|}qDW |tt	fks„|tkr¼|s¸| j
|d� t|d j|r¦dnd	||p°|d
�ƒ‚|S |sÈ|rÈ|S || jk�r| j|  ¡ d }	x|D ]}
|	|
jkrì|
S qìW | j
|d� t|j||d�ƒ‚dS )a†  Get a MySQL server from a group

        The method uses MySQL Fabric to get the correct MySQL server
        for the specified group. You can specify mode or status, but
        not both.

        The mode argument will decide whether the primary or a secondary
        server is returned. When no secondary server is available, the
        primary is returned.

        Status is used to force getting either a primary or a secondary.

        The returned tuple contains host, port and uuid.

        Raises InterfaceError on errors; ValueError when both mode
        and status are given.

        Returns a FabricMySQLServer object.
        z-Either mode or status must be given, not bothz-No MySQL server available for group '{group}'T)rî   )r(   Nz {query}={value}r  r+   )Úqueryr(   rL   r   )r(   r+   )rs   rï   r   rD   r  r  rC   ÚSTATUS_PRIMARYÚMODE_WRITEONLYÚMODE_READWRITErð   râ   Zget_nextr›   )r5   r(   r+   r  rò   rÿ   ZprimaryZ	secondaryÚserverZnext_secondaryr  r;   r;   r<   Úget_group_server$  s>    






zFabric.get_group_serverc             C   s,  t |ttfƒstdƒ‚g }xf|D ]^}t |ttfƒsD|sDtd |¡ƒ‚t |ttfƒrd|d }|d }n|}|}| d ||¡¡ q W |  ¡ }y| dd| jd 	|¡¡}W n@ t
tjfk
ræ }	 zd	jt|	ƒd
�}
t|
ƒ‚W dd}	~	X Y nX x>| ¡ D ]2}| j t|j|j|j|j|j|j|j|jƒ¡ qòW dS )aÏ  Get and cache the sharding information for given tables

        This method is fetching sharding information from MySQL Fabric
        and caches the result. The tables argument must be sequence
        of sequences contain the name of the database and table. If no
        database is given, the value for the database argument will
        be used.

        Examples:
          tables = [('salary',), ('employees',)]
          get_sharding_information(tables, database='employees')

          tables = [('salary', 'employees'), ('employees', employees)]
          get_sharding_information(tables)

        Raises InterfaceError on errors; ValueError when something is wrong
        with the tables argument.
        ztables should be a sequencez#No database specified for table {0}r   r   z{0}.{1}rù   Zsharding_informationú,z0Looking up sharding information failed : {error})rb   N)r–   r>   rS   rs   rD   rC   ró   rX   rÞ   r]   r   rd   rb   rE   r   rˆ   rá   Zsharding_cache_tabler   Zschema_nameZ
table_nameZcolumn_nameZlower_boundZshard_idZ	type_namer   Úglobal_group)r5   r*   ÚdatabaseÚpatternsÚtableZdbaseÚtblrì   rþ   rh   ri   r‡   r;   r;   r<   Úget_sharding_information`  s6    

zFabric.get_sharding_informationc          	      sÄ  t |ttfƒstdƒ‚g ‰ �x”|D �]Š}y| d¡\}}W n" tk
r\   td |¡ƒ‚Y nX | j ||¡}|s¨|  |f|¡ | j ||¡}|s¨t	t
jdj||d�d�‚|dkrÀ| j|j|d�S |jd	k�ryt|ƒ}	W n tk
rô   td
ƒ‚Y nX |j}
|
t|
|	ƒd  }|j| }�nf|jdk�r t |tjtjfƒ�sDtdƒ‚d}x |jD ]}||k�rP|}P �qPW y|j| }W n$ tk
�rœ   td |¡ƒ‚Y nX nâ|jdk�rt|ƒ�s¾tdƒ‚d}x |jD ]}||k�rÊ|}P �qÊW y|j| }W n$ tk
�r   td |¡ƒ‚Y nX nh|jdk�rrtt|ƒƒ}|jd }x(|jD ]}| ¡ t|ƒk�rD|}P �qDW |j| }ntd |j¡ƒ‚ˆ  |d ¡ t‡ fdd„ˆ D ƒƒs"t	dƒ‚q"W | jˆ d |d�S )a"  Get MySQL server information for a particular shard

        Raises DatabaseError when the table is unknown or when tables are not
        on the same shard. ValueError is raised when there is a problem
        with the methods arguments. InterfaceError is raised for other errors.
        ztables should be a sequenceÚ.z5tables should be given as <database>.<table>, was {0}z"Unknown table '{database}.{table}')r  r  )rø   ri   r%   )r+   ÚRANGEz Key must be an integer for RANGEr   ZRANGE_DATETIMEzAKey must be datetime.date or datetime.datetime for RANGE_DATETIMENzKey invalid; was '{0}'ZRANGE_STRINGzKey must be a unicode valueÚHASHrÇ   zUnsupported sharding type {0}r(   c             3   s   | ]}|ˆ d  kV  qdS )r   Nr;   )rP   r(   )Úgroupsr;   r<   r�   ç  s    z*Fabric.get_shard_server.<locals>.<genexpr>z'Tables are located in different shards.r   )r–   r>   rS   rs   ÚsplitrD   rá   Zsharding_searchr  r   r   ZER_BAD_TABLE_ERRORr  r  Z
shard_typer—   r   r   ZpartitioningÚdatetimeÚdateZkeys_reversedÚKeyErrorr    r   rE   Údigestr   r   rC   r“   )r5   r*   r)   r-   r+   Zdbobjr  r  r  Z	range_keyZ
partitionsr‰   Ú	partitionZpartkeyZmd5keyr;   )r  r<   Úget_shard_server—  sŠ    




zFabric.get_shard_serverc             O   s   |   ¡ }|j||f|ž|ŽS )ai  Execute a Fabric command from given group

        This method will execute the given Fabric command from the given group
        using the given arguments. It returns an instance of FabricSet.

        Raises ValueError when group.command is not valid and raises
        InterfaceError when an error occurs while executing.

        Returns FabricSet.
        )ró   rX   )r5   r(   ra   r^   r_   rì   r;   r;   r<   rX   í  s    zFabric.execute)NN)N)N)T)NN)NN)rj   rk   rl   rm   Ú_CNX_ATTEMPT_MAXÚ_CNX_ATTEMPT_DELAYÚDEFAULT_FABRIC_PROTOCOLr=   ÚpropertyrÂ   rÃ   r¬   rí   rð   ró   rô   rê   rï   r  r  ÚSCOPE_LOCALr  rX   r;   r;   r;   r<   r×   -  s*    
-

*
-
<
7Vr×   c               @   sd   e Zd ZdZee eefdd„Ze	dd„ ƒZ
e	dd„ ƒZe	dd	„ ƒZd
d„ Ze	dd„ ƒZdd„ ZdS )ÚFabricConnectionzIBase Class for a class holding a connection to a MySQL Fabric server
    c             C   s4   t |tƒstdƒ‚|| _|| _|| _|| _|| _dS )r¨   z'fabric must be instance of class FabricN)r–   r×   rs   Ú_fabricÚ_hostÚ_portrß   rà   )r5   r6   r7   r8   r9   r:   r;   r;   r<   r=   ÿ  s    
zFabricConnection.__init__c             C   s   | j S )z6Returns server IP or name of current Fabric connection)r%  )r5   r;   r;   r<   r7     s    zFabricConnection.hostc             C   s   | j S )z0Returns TCP/IP port of current Fabric connection)r&  )r5   r;   r;   r<   r8     s    zFabricConnection.portc             C   s   t | j| jƒS )z7Returns UUID of the Fabric server we are connected with)rž   r%  r&  )r5   r;   r;   r<   r›     s    zFabricConnection.uuidc             C   s   dS )zConnect with MySQL FabricNr;   )r5   r;   r;   r<   r4     s    zFabricConnection.connectc             C   s   dS )z²Check whether connection with Fabric is valid

        Return True if we can still interact with the Fabric server; False
        if Not.

        Returns True or False.
        Nr;   )r5   r;   r;   r<   rñ     s    	zFabricConnection.is_connectedc             C   s   dj | j| j| jd�S )Nz"{class_}(host={host}, port={port}))Úclass_r7   r8   )rD   r„   r%  r&  )r5   r;   r;   r<   Ú__repr__*  s    zFabricConnection.__repr__N)rj   rk   rl   rm   rÚ   r   r  r  r=   r!  r7   r8   r›   r4   rñ   r(  r;   r;   r;   r<   r#  ü  s   
r#  c                   s`   e Zd ZdZed eef‡ fdd„	Zedd„ ƒZ	edd„ ƒZ
d	d
„ Zdd„ Zedd„ ƒZ‡  ZS )ro   zCClass holding a connection to a MySQL Fabric server through XML-RPCr"   c                s"   t t| ƒ |||||¡ d| _dS )r¨   N)r~   ro   r=   Ú_proxy)r5   r6   r7   r8   r9   r:   )r„   r;   r<   r=   6  s    
zFabricXMLRPCConnection.__init__c             C   s   | j S )z5Returns the XMLRPC Proxy of current Fabric connection)r)  )r5   r;   r;   r<   rq   ?  s    zFabricXMLRPCConnection.proxyc             C   s   t | j| jƒS )z4Returns the XMLRPC URI for current Fabric connection)rš   r%  r&  )r5   r;   r;   r<   rÔ   D  s    zFabricXMLRPCConnection.uric          
   C   s  | j r| jS | j}| j}d}d}xê||k�r
|d7 }yZ| jjrXtsJtdƒ‚t| jjƒ}nd}t	| jj
| jjd|d�}t| j|dd�}| ¡  W nf tk
r¢   |S  tjk
rô } z4||krÊtd |¡ƒ‚t dj| j| j|d	�¡ W dd}~X Y nX |dkr"t |¡ q"W dS )
zÇReturn the XMLRPC server proxy instance to MySQL Fabric

        This method tries to get a valid connection to a MySQL Fabric
        server.

        Returns a XMLRPC ServerProxy instance.
        Nr   r   zPython does not support SSL)r¼   rÄ   )Ú	transportr¼   z'Connection to MySQL Fabric failed ({0})z*Retrying {host}:{port}, attempts {counter})r7   r8   Úcounter)rñ   r)  rß   rà   r$  r¬   r¡   r   r§   rµ   rÂ   rÃ   r   rÔ   Ú_some_nonexisting_methodr   rd   rb   rD   rÊ   rË   r7   r8   ÚtimeÚsleep)r5   r.   Údelayrq   r+  rÄ   r*  rh   r;   r;   r<   Ú_xmlrpc_get_proxyI  s>    $z(FabricXMLRPCConnection._xmlrpc_get_proxyc             C   s   |   ¡ | _dS )zConnect with MySQL FabricN)r0  r)  )r5   r;   r;   r<   r4   v  s    zFabricXMLRPCConnection.connectc          	   C   sB   y| j  ¡  W n* tk
r"   dS  ttfk
r8   dS X dS dS )z²Check whether connection with Fabric is valid

        Return True if we can still interact with the Fabric server; False
        if Not.

        Returns True or False.
        TFN)r)  r,  r   rú   rr   )r5   r;   r;   r<   rñ   z  s    	z#FabricXMLRPCConnection.is_connected)rj   rk   rl   rm   rÚ   r  r  r=   r!  rq   rÔ   r0  r4   rñ   rŠ   r;   r;   )r„   r<   ro   2  s   -ro   c                   sT   e Zd ZdZed eef‡ fdd„	Zedd„ ƒZ	dd„ Z
d	d
„ Zedd„ ƒZ‡  ZS )r2   zT
    Class holding a connection to a MySQL Fabric server through MySQL protocol
    r#   c                s$   t t| ƒj|||||d� d| _dS )r¨   )r8   r9   r:   N)r~   r2   r=   Ú_connection)r5   r6   r7   r8   r9   r:   )r„   r;   r<   r=   ‘  s    

zFabricMySQLConnection.__init__c             C   s   | j S )z*Returns the MySQL RPC Connection to Fabric)r1  )r5   r;   r;   r<   rV   ›  s    z FabricMySQLConnection.connectionc          
   C   sô   | j r| jS | j}| j}d}xÒ||krî|d7 }yX| j| j| jj| jjdœ}| jj	r~t
s^tdƒ‚| jj	d |d< | jj	d |d< tf |ŽS  tk
rØ } z4||kr®td	 |¡ƒ‚t d
j| j| j|d�¡ W dd}~X Y nX |dkrt |¡ qW dS )zÍReturn the connection instance to MySQL Fabric through MySQL RPC

        This method tries to get a valid connection to a MySQL Fabric
        server.

        Returns a MySQLConnection instance.
        r   r   )r7   r8   rè   rÃ   zPython does not support SSLr)   r¤   r    r¥   z'Connection to MySQL Fabric failed ({0})z*Retrying {host}:{port}, attempts {counter})r7   r8   r+  N)rñ   r1  rß   rà   r%  r&  r$  rÂ   rÃ   r¬   r¡   r   r   rr   rD   rÊ   rË   r7   r8   r-  r.  )r5   r.   r/  r+  Údbconfigrh   r;   r;   r<   Ú_get_connection   s6    

$z%FabricMySQLConnection._get_connectionc             C   s   |   ¡ | _dS )zConnect with MySQL FabricN)r3  r1  )r5   r;   r;   r<   r4   Ë  s    zFabricMySQLConnection.connectc             C   s$   y
| j  ¡ S  tk
r   dS X dS )z²Check whether connection with Fabric is valid

        Return True if we can still interact with the Fabric server; False
        if Not.

        Returns True or False.
        FN)r1  rñ   rr   )r5   r;   r;   r<   rñ   Ï  s    	
z"FabricMySQLConnection.is_connected)rj   rk   rl   rm   rÚ   r  r  r=   r!  rV   r3  r4   rñ   rŠ   r;   r;   )r„   r<   r2   �  s   +r2   c               @   s°   e Zd ZdZdd„ Zdd„ Zedd„ ƒZedd	„ ƒZd'dd„Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZeZd(dd„Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd
S ))ÚMySQLFabricConnectionz1Connection to a MySQL server through MySQL Fabricc             K   sJ   d| _ d| _d| _d| _i | _|  ¡  d|kr6tdƒ‚|rF| jf |Ž dS )r¨   Nr6   z+Configuration parameters for Fabric missing)Ú
_mysql_cnxr$  Ú_fabric_mysql_serverÚ_mysql_configÚ_cnx_propertiesÚreset_propertiesrs   Ústore_config)r5   r_   r;   r;   r<   r=   â  s    zMySQLFabricConnection.__init__c             C   s&   |  d¡rtdj|d�ƒ‚t| j|ƒS )z7Return the return value of the MySQLConnection instanceZcmd_zHCalling {attr} is not supported for connections managed by MySQL Fabric.)Úattr)Ú
startswithr   rD   rp   r5  )r5   r;  r;   r;   r<   Ú__getattr__ò  s
    

z!MySQLFabricConnection.__getattr__c             C   s   | j r| j jS dS )z+Returns the Fabric UUID of the MySQL serverN)r6  r›   )r5   r;   r;   r<   rw   ú  s    z!MySQLFabricConnection.fabric_uuidc             C   s   | j S )zReturns connection properties)r8  )r5   r;   r;   r<   Ú
properties  s    z MySQLFabricConnection.propertiesNc             C   s$   |s| j r| j j}| jj|d� dS )z'Reset cache for this connection's group)r(   N)r6  r(   r$  rð   )r5   r(   r;   r;   r<   rð     s    
z!MySQLFabricConnection.reset_cachec             C   s
   | j dk	S )z\Check whether we are connected with the MySQL server

        Returns True or False
        N)r5  )r5   r;   r;   r<   rñ     s    z"MySQLFabricConnection.is_connectedc             C   s.   i | _ x"t ¡ D ]\}}|d | j |< qW dS )z�Resets the connection properties

        This method can be called to reset the connection properties to
        their default values.
        r	   N)r8  Ú_CNX_PROPERTIESr?   )r5   r)   r;  r;   r;   r<   r9    s    z&MySQLFabricConnection.reset_propertiesc             K   sH  y|   ¡  W n tk
r    Y nX | j}�x| ¡ D �]
\}}|tkrVtd |¡ƒ‚nD|ršt|t| d ƒsšd dd„ t| d D ƒ¡}t	dj||d�ƒ‚|dkrÀ|rÀ|d	 s¶|d
 rÀtdƒ‚n\|dkrÞ|rÞ|d rÞtdƒ‚n>|dkrü|t
tfkrütdƒ‚n |dk�r|ttfk�rtdƒ‚|dk�r8t| d ||< q4|||< q4W dS )at  Set one or more connection properties

        Arguments to the set_property() method will be used as properties.
        They are validated against the _CNX_PROPERTIES constant.

        Raise ValueError in case an invalid property is being set. TypeError
        is raised when the type of the value is not correct.

        To unset a property, set it to None.
        zInvalid property connection {0}r   z or c             S   s   g | ]
}|j ‘qS r;   )rj   )rP   Zatyper;   r;   r<   rR   6  s    z6MySQLFabricConnection.set_property.<locals>.<listcomp>z({name} is not valid, excepted {typename})ÚnameÚtypenamer(   r)   r*   z>'group' property can not be set when 'key' or 'tables' are set)r)   r*   z@'key' and 'tables' property can not be set together with 'group'r-   zInvalid value for 'scope'r+   zInvalid value for 'mode'Nr	   )Úcloser   r8  r?   r?  rs   rD   r–   r]   rú   r"  ÚSCOPE_GLOBALr	  ÚMODE_READONLY)r5   r>  Úpropsr@  rL   Zvalid_types_strr;   r;   r<   Úset_property  s<    

z"MySQLFabricConnection.set_propertyc             C   sæ   t |tƒr|| _nÐdg}x$|D ]}||krtdj|d�ƒ‚qW |d }| dt¡}y| dt| ¡}W n" tk
rˆ   t	d |¡ƒ‚Y nX t
||ƒ}yt| | _W n> tk
rà   t d¡ tf |Ž| _| j ¡  | jt|< Y nX dS )	zÖConfigure the Fabric connection

        The config argument can be either a dictionary containing the
        necessary information to setup the connection. Or config can
        be an instance of Fabric.
        r7   z8Missing configuration parameter '{parameter}' for fabric)Z	parameterré   r8   z{0} protocol is not availablezNew Fabric connectionN)r–   r×   r$  rs   rD   Úgetr   rÚ   r  r   rž   ÚFABRICSrÊ   rË   rí   )r5   ÚconfigZrequired_keysZrequired_keyr7   ré   r8   r÷   r;   r;   r<   Ú_configure_fabricP  s.    




z'MySQLFabricConnection._configure_fabricc          
   K   sÎ   |  ¡ }d|kr$|  |d ¡ |d= d|kr>t d¡ d|d< |  ¡ }d|krT|d= d|krb|d= d|krp|d= y"ttt ¡ ƒd�}|jf |Ž W n0 t	k
rÂ } zt	d	 
|¡ƒ‚W dd}~X Y nX || _dS )
a­  Store configuration of MySQL connections to use with Fabric

        The configuration found in the dictionary kwargs is used
        when instanciating a MySQLConnection object. The host and port
        entries are used to connect to MySQL Fabric.

        Raises ValueError when the Fabric configuration parameter
        is not correct or missing; AttributeError is raised when
        when a paramater is not valid.
        r6   Zunix_socketz'MySQL Fabric does not use UNIX sockets.NÚ	pool_nameZ	pool_sizeZpool_reset_session)rK  z'Connection configuration not valid: {0})ÚcopyrJ  rÊ   Úwarningr   rE   r›   rü   Z
set_configrr   rD   r7  )r5   r_   rI  Ztest_configÚpoolrN   r;   r;   r<   r:  q  s*    
z"MySQLFabricConnection.store_configc       	   
   C   sæ  |   ¡ rdS | j}|d }|d }| j ¡ }d}�x®||k�rà|d7 }y€d}|d r–|d dkrp|d	 sptd
ƒ‚| jj|d |d	 |d |d d�}n.|d r¼|d }| jj||d d�}ntdƒ‚W nt tk
�r: } zTt	 
d ||¡¡ ||k�rtd |¡ƒ‚|dk�r(t	 
d |¡¡ t |¡ w4W dd}~X Y nX |j|d< |j|d< ytjjf |Ž| _W np tk
�rÔ } zP||k�r®|  |j¡ | j |j|j¡ td |¡ƒ‚|dk�rÂt |¡ w4W dd}~X Y q4X || _P q4W dS )aª  Get a MySQL server based on properties and connect

        This method gets a MySQL server from MySQL Fabric using already
        properties set using the set_property() method. You can specify how
        many times and the delay between trying using attempts and
        attempt_delay.

        Raises ValueError when there are problems with arguments or
        properties; InterfaceError on connectivity errors.
        Nr.   r/   r   r   r*   r-   r&   r)   z*Scope 'LOCAL' needs key property to be setr+   )r-   r+   r(   )r+   z*Missing group or key and tables propertiesz-Trying to get MySQL server (attempt {0}; {1})zError getting connection: {0}zWaiting {0}r7   r8   z&Reported faulty server to Fabric ({0}))rñ   r8  r7  rL  rs   r$  r  r  r   rÊ   rË   rD   r-  r.  r7   r8   r#   rG   r4   r5  r   rð   r(   rô   r›   rø   r6  )	r5   rE  r.   r/   r2  r+  r(   r  rh   r;   r;   r<   Ú_connect˜  sf    










zMySQLFabricConnection._connectc             C   sX   zDy|   ¡  | j ¡  W n( tk
r,   Y n tk
r@   ‚ Y nX W dd| _d| _X dS )z Close connection to MySQL serverN)Úrollbackr5  rB  rr   r   r6  )r5   r;   r;   r<   Ú
disconnectÜ  s    z MySQLFabricConnection.disconnectc             C   s‚   |   ¡  |rtdƒ‚|r tdƒ‚| jdkr2tdƒ‚|p:| j}|pD| j}d}|dkrZ|dO }|dkrj|dO }tttt	f}|| | ƒS )ai  Instantiates and returns a cursor

        This method is similar to MySQLConnection.cursor() except that
        it checks whether the connection is available and raises
        an InterfaceError when not.

        cursor_class argument is not supported and will raise a
        NotSupportedError exception.

        Returns a MySQLCursor or subclass.
        z.Custom cursors not supported with MySQL Fabricz7Prepared Statements are not supported with MySQL FabricTzUnread result found.r   r   r	   )
rO  r   Z_unread_resultr   Z	_bufferedÚ_rawr   r   r   r   )r5   ZbufferedÚrawÚpreparedZcursor_classZcursor_typeÚtypesr;   r;   r<   rW   ê  s*    


zMySQLFabricConnection.cursorc             C   s6   |j tkr.|  ¡  |  ¡  tdjt|ƒd�ƒ‚|‚dS )zÕHandles MySQL errors

        This method takes a mysql.connector.errors.Error exception
        and checks the error code. Based on the value, it takes
        certain actions such as clearing the cache.
        z,Temporary error ({error}); retry transaction)rb   N)rø   ÚRESET_CACHE_ON_ERRORrð   rQ  r   rD   rE   )r5   rh   r;   r;   r<   Úhandle_mysql_error  s    
z(MySQLFabricConnection.handle_mysql_errorc          
   C   s@   y| j  ¡  W n, tk
r: } z|  |¡ W dd}~X Y nX dS )zÀCommit current transaction

        Raises whatever MySQLConnection.commit() raises, but
        raises MySQLFabricError when MySQL returns error
        ER_OPTION_PREVENTS_STATEMENT.
        N)r5  Úcommitr   rW  )r5   rh   r;   r;   r<   rX  #  s    zMySQLFabricConnection.commitc          
   C   s@   y| j  ¡  W n, tk
r: } z|  |¡ W dd}~X Y nX dS )zÄRollback current transaction

        Raises whatever MySQLConnection.rollback() raises, but
        raises MySQLFabricError when MySQL returns error
        ER_OPTION_PREVENTS_STATEMENT.
        N)r5  rP  r   rW  )r5   rh   r;   r;   r<   rP  /  s    zMySQLFabricConnection.rollbackc          
   C   sF   |   ¡  y| j |¡S  tk
r@ } z|  |¡ W dd}~X Y nX dS )zìSend a statement to the MySQL server

        Raises whatever MySQLConnection.cmd_query() raises, but
        raises MySQLFabricError when MySQL returns error
        ER_OPTION_PREVENTS_STATEMENT.

        Returns a dictionary.
        N)rO  r5  Ú	cmd_queryr   rW  )r5   Z	statementrh   r;   r;   r<   rY  ;  s
    	zMySQLFabricConnection.cmd_queryc          
   C   sF   |   ¡  y| j |¡S  tk
r@ } z|  |¡ W dd}~X Y nX dS )züSend one or more statements to the MySQL server

        Raises whatever MySQLConnection.cmd_query_iter() raises, but
        raises MySQLFabricError when MySQL returns error
        ER_OPTION_PREVENTS_STATEMENT.

        Returns a dictionary.
        N)rO  r5  Úcmd_query_iterr   rW  )r5   Z
statementsrh   r;   r;   r<   rZ  J  s
    	z$MySQLFabricConnection.cmd_query_iter)N)NNNN)rj   rk   rl   rm   r=   r=  r!  rw   r>  rð   rñ   r9  rF  rJ  r:  rO  rQ  rB  rW   rW  rX  rP  rY  rZ  r;   r;   r;   r<   r4  Þ  s(   

3!'D
)r4  )rrm   Úsysr  r-  r›   Úbase64r   r   Úhashlibr   Úloggingrd   r�   Ú	xmlrpclibr   r   r   r©   Úhttplibr   ÚImportErrorÚxmlrpc.clientÚurllib.requestrÖ   Úhttp.clientÚversion_infor
   r¡   Zmysql.connectorr#   rV   r   Ú
conversionr   Zpoolingr   rH   r   r   r   r   r   r   rW   r   r   r   r   r'   r   r   r   Zcachingr   Z	balancingr   r   Zcatch23r   r    r!   ZCR_SERVER_LOSTZER_OPTION_PREVENTS_STATEMENTrV  ZCR_SERVER_GONE_ERRORZCR_CONN_HOST_ERRORZCR_CONNECTION_ERRORZCR_IPSOCK_ERRORrö   r•   r   rÚ   rH  r  r  Z_GETCNX_ATTEMPT_DELAYZ_GETCNX_ATTEMPT_MAXrD  r  r	  ZSTATUS_FAULTYZSTATUS_SPAREr  r  rC  r"  Z_SERVER_STATUS_FAULTYrE   rS   r—   r  r>   r?  Ú	getLoggerrÊ   Úobjectr0   rn   rv   rc   r‹   rt   r™   rš   rž   r¦   rª   r§   rµ   r×   r#  ro   r2   r4  r;   r;   r;   r<   Ú<module>   sÎ   

 






\#!#N   R6[Q