U
    h                     @  s   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ dd	l	m
Z
 d
dlmZ d
dlmZ erd
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ G dd de
ZeZdS )a  

.. dialect:: mysql+pymysql
    :name: PyMySQL
    :dbapi: pymysql
    :connectstring: mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
    :url: https://pymysql.readthedocs.io/

Unicode
-------

Please see :ref:`mysql_unicode` for current recommendations on unicode
handling.

.. _pymysql_ssl:

SSL Connections
------------------

The PyMySQL DBAPI accepts the same SSL arguments as that of MySQLdb,
described at :ref:`mysqldb_ssl`.   See that section for additional examples.

If the server uses an automatically-generated certificate that is self-signed
or does not match the host name (as seen from the client), it may also be
necessary to indicate ``ssl_check_hostname=false`` in PyMySQL::

    connection_uri = (
        "mysql+pymysql://scott:tiger@192.168.0.134/test"
        "?ssl_ca=/home/gord/client-ssl/ca.pem"
        "&ssl_cert=/home/gord/client-ssl/client-cert.pem"
        "&ssl_key=/home/gord/client-ssl/client-key.pem"
        "&ssl_check_hostname=false"
    )

MySQL-Python Compatibility
--------------------------

The pymysql DBAPI is a pure Python port of the MySQL-python (MySQLdb) driver,
and targets 100% compatibility.   Most behavioral notes for MySQL-python apply
to the pymysql driver as well.

    )annotations)Any)Dict)Optional)TYPE_CHECKING)Union   )MySQLDialect_mysqldb   )langhelpers)Literal)ConnectArgsType)DBAPIConnection)DBAPICursor)DBAPIModule)PoolProxiedConnection)URLc                      s   e Zd ZdZdZdZejddddZe	ddd	d
Z
ejddddZdddddZd#dddd fddZddddd fddZddd d!d"Z  ZS )$MySQLDialect_pymysqlpymysqlTNbool)returnc              	   C  s8   zt dj}|j| _W dS  ttfk
r2   Y dS X d S )Nzpymysql.cursorsTF)
__import__cursorsZSSCursorZ	_sscursorImportErrorAttributeError)selfr    r   E/tmp/pip-unpacked-wheel-y9ln43lq/sqlalchemy/dialects/mysql/pymysql.pysupports_server_side_cursorsN   s    
z1MySQLDialect_pymysql.supports_server_side_cursorsr   c                 C  s   t dS )Nr   )r   )clsr   r   r   import_dbapiW   s    z!MySQLDialect_pymysql.import_dbapic              	   C  s   zt djj}W n ttfk
r*   Y dS X t|j}z|jd }W n t	k
r\   Y dS X |dkoz|j
 pz|j
d dk	S dS )a  determine if pymysql has deprecated, changed the default of,
        or removed the 'reconnect' argument of connection.ping().

        See #10492 and
        https://github.com/PyMySQL/mysqlclient/discussions/651#discussioncomment-7308971
        for background.

        zpymysql.connectionsTr   FZ	reconnectr   N)r   connections
Connectionr   r   r   Zget_callable_argspecpingargs
IndexErrordefaults)r   r"   ZinspZreconnect_argr   r   r   _send_false_to_ping[   s    z(MySQLDialect_pymysql._send_false_to_pingr   zLiteral[True])dbapi_connectionr   c                 C  s   | j r|d n|  dS )NFT)r'   r#   )r   r(   r   r   r   do_pingw   s    zMySQLDialect_pymysql.do_pingr   zOptional[Dict[str, Any]]r   )url_translate_argsr   c                   s"   |d krt dd}t j||dS )Nuser)username)r+   )dictsupercreate_connect_args)r   r*   r+   	__class__r   r   r0      s    
 z(MySQLDialect_pymysql.create_connect_argszDBAPIModule.Errorz7Optional[Union[PoolProxiedConnection, DBAPIConnection]]zOptional[DBAPICursor])e
connectioncursorr   c                   sF   t  |||rdS t|| jjr>t| }d|kp<d|kS dS d S )NTzalready closedzconnection was killedF)r/   is_disconnect
isinstanceZloaded_dbapiErrorstrlower)r   r3   r4   r5   Zstr_er1   r   r   r6      s    z"MySQLDialect_pymysql.is_disconnectBaseExceptionr   )	exceptionr   c                 C  s$   t |jd tr|jd }|jd S )Nr   )r7   r$   	Exception)r   r<   r   r   r   _extract_error_code   s    
z(MySQLDialect_pymysql._extract_error_code)N)__name__
__module____qualname__ZdriverZsupports_statement_cacheZdescription_encodingr   Zmemoized_propertyr   classmethodr    r'   r)   r0   r6   r>   __classcell__r   r   r1   r   r   H   s   	 	r   N)__doc__
__future__r   typingr   r   r   r   r   Zmysqldbr	   utilr   Zutil.typingr   Zengine.interfacesr   r   r   r   r   Z
engine.urlr   r   dialectr   r   r   r   <module>   s$   *V