o
     h>&                     @  s\  d Z ddlm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 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 ddlmZ ddlmZ ddlm Z  G dd deZ!G dd deZ"G d d! d!eZ#e#Z$dS )"a  

.. dialect:: mysql+mysqldb
    :name: mysqlclient (maintained fork of MySQL-Python)
    :dbapi: mysqldb
    :connectstring: mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
    :url: https://pypi.org/project/mysqlclient/

Driver Status
-------------

The mysqlclient DBAPI is a maintained fork of the
`MySQL-Python <https://sourceforge.net/projects/mysql-python>`_ DBAPI
that is no longer maintained.  `mysqlclient`_ supports Python 2 and Python 3
and is very stable.

.. _mysqlclient: https://github.com/PyMySQL/mysqlclient-python

.. _mysqldb_unicode:

Unicode
-------

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

.. _mysqldb_ssl:

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

The mysqlclient and PyMySQL DBAPIs accept an additional dictionary under the
key "ssl", which may be specified using the
:paramref:`_sa.create_engine.connect_args` dictionary::

    engine = create_engine(
        "mysql+mysqldb://scott:tiger@192.168.0.134/test",
        connect_args={
            "ssl": {
                "ca": "/home/gord/client-ssl/ca.pem",
                "cert": "/home/gord/client-ssl/client-cert.pem",
                "key": "/home/gord/client-ssl/client-key.pem",
            }
        },
    )

For convenience, the following keys may also be specified inline within the URL
where they will be interpreted into the "ssl" dictionary automatically:
"ssl_ca", "ssl_cert", "ssl_key", "ssl_capath", "ssl_cipher",
"ssl_check_hostname". An example is as follows::

    connection_uri = (
        "mysql+mysqldb://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"
    )

.. seealso::

    :ref:`pymysql_ssl` in the PyMySQL dialect


Using MySQLdb with Google Cloud SQL
-----------------------------------

Google Cloud SQL now recommends use of the MySQLdb dialect.  Connect
using a URL like the following:

.. sourcecode:: text

    mysql+mysqldb://root@/<dbname>?unix_socket=/cloudsql/<projectid>:<instancename>

Server Side Cursors
-------------------

The mysqldb dialect supports server-side cursors. See :ref:`mysql_ss_cursors`.

    )annotationsN)Any)Callable)cast)Dict)Optional)Tuple)TYPE_CHECKING   )MySQLCompiler)MySQLDialect)MySQLExecutionContext)MySQLIdentifierPreparer   )util)Literal)
Connection)_DBAPIMultiExecuteParams)ConnectArgsType)DBAPIConnection)DBAPICursor)DBAPIModule)ExecutionContext)IsolationLevel)URLc                   @     e Zd ZdS )MySQLExecutionContext_mysqldbN__name__
__module____qualname__ r!   r!   T/var/www/html/venv/lib/python3.10/site-packages/sqlalchemy/dialects/mysql/mysqldb.pyr   v       r   c                   @  r   )MySQLCompiler_mysqldbNr   r!   r!   r!   r"   r$   z   r#   r$   c                      s   e Zd ZU dZdZdZdZdZdZdZ	e
ZeZeZded< dC fdd	ZdDddZejjdEddZedFddZdG fddZdHddZ	dIdJd&d'Z	dIdKd-d.ZdLd0d1ZdMd5d6ZdNd9d:ZdOd=d>Z dP fdAdBZ!  Z"S )QMySQLDialect_mysqldbmysqldbTformatTuple[int, ...]server_version_infokwargsr   c                   sF   t  jdi | | jd urt| jdr| | jj| _d S d| _d S )N__version__r   r   r   r!   )super__init__dbapihasattr_parse_dbapi_versionr+   _mysql_dbapi_version)selfr*   	__class__r!   r"   r.      s   zMySQLDialect_mysqldb.__init__versionstrreturnc                 C  s0   t d|}|rtdd |dddD S dS )Nz(\d+)\.(\d+)(?:\.(\d+))?c                 s  s     | ]}|d urt |V  qd S N)int).0xr!   r!   r"   	<genexpr>   s    z<MySQLDialect_mysqldb._parse_dbapi_version.<locals>.<genexpr>r
      r   r,   )rematchtuplegroup)r3   r6   mr!   r!   r"   r1      s   z)MySQLDialect_mysqldb._parse_dbapi_versionboolc              	   C  s2   zt dj}|j| _W dS  ttfy   Y dS w )NzMySQLdb.cursorsTF)
__import__cursorsSSCursor	_sscursorImportErrorAttributeError)r3   rF   r!   r!   r"   supports_server_side_cursors   s   
z1MySQLDialect_mysqldb.supports_server_side_cursorsr   c                 C  s   t dS )NMySQLdb)rE   )clsr!   r!   r"   import_dbapi   s   z!MySQLDialect_mysqldb.import_dbapi!Callable[[DBAPIConnection], None]c                   s   t    d fdd}|S )Nconnr   r8   Nonec                   sF    d ur |  |   }|d ur!|  }|d|  |  d S d S )NzSET NAMES %s)character_set_namecursorexecuteclose)rP   charset_namerS   super_r!   r"   
on_connect   s   z3MySQLDialect_mysqldb.on_connect.<locals>.on_connect)rP   r   r8   rQ   )r-   rY   )r3   rY   r4   rW   r"   rY      s   
zMySQLDialect_mysqldb.on_connectdbapi_connectionr   Literal[True]c                 C  s   |   dS )NT)ping)r3   rZ   r!   r!   r"   do_ping   s   zMySQLDialect_mysqldb.do_pingNrS   r   	statement
parametersr   contextOptional[ExecutionContext]rQ   c                 C  s(   | ||}|d ur|tt|_d S d S r9   )executemanyr   r   	_rowcount)r3   rS   r^   r_   r`   rowcountr!   r!   r"   do_executemany   s   z#MySQLDialect_mysqldb.do_executemanyurlr   _translate_argsOptional[Dict[str, Any]]r   c           
      C  sT  |d u rt dddd}|jdi |}||j t|dt t|dt t|dt t|dt t|d	t t|d
t t|dt t|dt i }dtfdtfdtfdtfdtfdtfg}|D ] \}}||v r|| ||dd  < t||dd  | ||= qi|r||d< |	d	d}| 
 }	|	d ur||	O }||d	< g |fS )Ndbuserpasswd)databaseusernamepasswordcompressconnect_timeoutread_timeoutwrite_timeoutclient_flaglocal_infileuse_unicodecharsetssl_cassl_keyssl_cert
ssl_capath
ssl_cipherssl_check_hostname   sslr   r!   )dicttranslate_connect_argsupdatequeryr   coerce_kw_typerD   r:   r7   get_found_rows_client_flag)
r3   rf   rg   optsr~   keyskeykw_typers   client_flag_found_rowsr!   r!   r"   create_connect_args   sH   z(MySQLDialect_mysqldb.create_connect_argsOptional[int]c              	   C  sD   | j d ur zt| j jd jj}W |jS  ttfy   Y d S w d S )Nz.constants.CLIENT)r/   rE   r   	constantsCLIENTrJ   rI   
FOUND_ROWS)r3   CLIENT_FLAGSr!   r!   r"   r      s   

z,MySQLDialect_mysqldb._found_rows_client_flag	exceptionDBAPIModule.Errorr:   c                 C  s
   |j d S )Nr   )args)r3   r   r!   r!   r"   _extract_error_code
  s   
z(MySQLDialect_mysqldb._extract_error_code
connectionr   c                 C  s0   z|j j}W | S  ty   td Y dS w )z:Sniff out the character set in use for connection results.zNo 'character_set_name' can be detected with this MySQL-Python version; please upgrade to a recent version of MySQL-Python.  Assuming latin1.latin1)r   rR   rJ   r   warn)r3   r   	cset_namer!   r!   r"   _detect_charset  s   z$MySQLDialect_mysqldb._detect_charset
dbapi_connTuple[IsolationLevel, ...]c                 C  s   dS )N)SERIALIZABLEzREAD UNCOMMITTEDzREAD COMMITTEDzREPEATABLE READ
AUTOCOMMITr!   )r3   r   r!   r!   r"   get_isolation_level_values"  s   z/MySQLDialect_mysqldb.get_isolation_level_valueslevelr   c                   s2   |dkr| d d S | d t || d S )Nr   TF)
autocommitr-   set_isolation_level)r3   rZ   r   r4   r!   r"   r   -  s   
z(MySQLDialect_mysqldb.set_isolation_level)r*   r   )r6   r7   r8   r(   )r8   rD   )r8   r   )r8   rO   )rZ   r   r8   r[   r9   )
rS   r   r^   r7   r_   r   r`   ra   r8   rQ   )rf   r   rg   rh   r8   r   )r8   r   )r   r   r8   r:   )r   r   r8   r7   )r   r   r8   r   )rZ   r   r   r   r8   rQ   )#r   r   r    driversupports_statement_cachesupports_unicode_statementssupports_sane_rowcountsupports_sane_multi_rowcountsupports_native_decimaldefault_paramstyler   execution_ctx_clsr$   statement_compilerr   preparer__annotations__r.   r1   r   langhelpersmemoized_propertyrK   classmethodrN   rY   r]   re   r   r   r   r   r   r   __classcell__r!   r!   r4   r"   r%   ~   s:   
 

	
5


r%   )%__doc__
__future__r   r?   typingr   r   r   r   r   r   r	   baser   r   r   r    r   util.typingr   engine.baser   engine.interfacesr   r   r   r   r   r   r   
engine.urlr   r   r$   r%   dialectr!   r!   r!   r"   <module>   s>   O :