o
    =a)                     @   s   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 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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": {
                "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"
            }
        }
    )

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"
    )

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``::

    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"
    )


.. 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::

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

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

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

    N   )MySQLCompiler)MySQLDialect)MySQLExecutionContext)MySQLIdentifierPreparer)TEXT   )sql)utilc                   @   s   e Zd Zedd ZdS )MySQLExecutionContext_mysqldbc                 C   s   t | dr| jS | jjS )N	_rowcount)hasattrr   cursorrowcount)self r   W/var/www/html/gps/gps/lib/python3.10/site-packages/sqlalchemy/dialects/mysql/mysqldb.pyr   o   s   
z&MySQLExecutionContext_mysqldb.rowcountN)__name__
__module____qualname__propertyr   r   r   r   r   r   n   s    r   c                   @      e Zd ZdS )MySQLCompiler_mysqldbNr   r   r   r   r   r   r   r   w       r   c                   @   r   )MySQLIdentifierPreparer_mysqldbNr   r   r   r   r   r   {   r   r   c                       s   e Zd ZdZdZdZdZdZdZdZ	e
ZeZeZ fddZdd Zejjdd	 Zed
d Z fddZdd Zd ddZ fddZd ddZdd Zdd Zdd Ze g dZ! fddZ"  Z#S )!MySQLDialect_mysqldbmysqldbTformatc                    sJ   t 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   )superr   __init__dbapir   _parse_dbapi_versionr   _mysql_dbapi_version)r   kwargs	__class__r   r   r"      s   
zMySQLDialect_mysqldb.__init__c                 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)r   versionmr   r   r   r$      s   z)MySQLDialect_mysqldb._parse_dbapi_versionc              	   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)r   r6   r   r   r   supports_server_side_cursors   s   
z1MySQLDialect_mysqldb.supports_server_side_cursorsc                 C   s   t dS )NMySQLdb)r5   )clsr   r   r   r#      s   zMySQLDialect_mysqldb.dbapic                    s   t t|    fdd}|S )Nc                    sF    d ur |  |   }|d ur!|  }|d|  |  d S d S )NzSET NAMES %s)character_set_namer   executeclose)conncharset_namer   super_r   r   
on_connect   s   z3MySQLDialect_mysqldb.on_connect.<locals>.on_connect)r!   r   rE   )r   rE   r'   rC   r   rE      s   zMySQLDialect_mysqldb.on_connectc              
   C   sL   z| d W dS  | jjy% } z| ||d r W Y d }~dS  d }~ww )NFT)pingr#   Erroris_disconnect)r   dbapi_connectionerrr   r   r   do_ping   s   zMySQLDialect_mysqldb.do_pingNc                 C   s"   | ||}|d ur||_d S d S r)   )executemanyr   )r   r   	statement
parameterscontextr   r   r   r   do_executemany   s   
z#MySQLDialect_mysqldb.do_executemanyc                    sr   | d| jd| jdf  }| jdko|}|r.tttdt	dddg}ng }t
t| ||S )	Nz:show collation where %s = 'utf8mb4' and %s = 'utf8mb4_bin'Charset	Collation)   z'test collated returns'utf8mb4)charsetutf8mb4_bin)exec_driver_sqlidentifier_preparerquotescalarserver_version_infor	   collatecastliteral_columnr   r!   r   _check_unicode_returns)r   
connection	collationhas_utf8mb4_binadditional_testsr'   r   r   r_      s.   



z+MySQLDialect_mysqldb._check_unicode_returnsc           
      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 |gS )Ndbuserpasswd)databaseusernamepasswordcompressconnect_timeoutread_timeoutwrite_timeoutclient_flaglocal_infileuse_unicoderU   ssl_cassl_keyssl_cert
ssl_capath
ssl_cipherssl_check_hostname   sslr   r   )dicttranslate_connect_argsupdatequeryr
   coerce_kw_typeboolr*   strget_found_rows_client_flag)
r   url_translate_argsoptsrx   keyskeykw_typern   client_flag_found_rowsr   r   r   create_connect_args   sH   z(MySQLDialect_mysqldb.create_connect_argsc              	   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#   r5   r   	constantsCLIENTr:   r9   
FOUND_ROWS)r   CLIENT_FLAGSr   r   r   r     s   

z,MySQLDialect_mysqldb._found_rows_client_flagc                 C   s
   |j d S )Nr   )args)r   	exceptionr   r   r   _extract_error_code&  s   
z(MySQLDialect_mysqldb._extract_error_codec                 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`   r>   r:   r
   warn)r   r`   	cset_namer   r   r   _detect_charset)  s   

z$MySQLDialect_mysqldb._detect_charset)SERIALIZABLEzREAD UNCOMMITTEDzREAD COMMITTEDzREPEATABLE READ
AUTOCOMMITc                    s6   |dkr| d d S | d tt| || d S )Nr   TF)
autocommitr!   r   _set_isolation_level)r   r`   levelr'   r   r   r   E  s   

z)MySQLDialect_mysqldb._set_isolation_levelr)   )$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   preparerr"   r$   r
   langhelpersmemoized_propertyr;   classmethodr#   rE   rK   rP   r_   r   r   r   r   set_isolation_lookupr   __classcell__r   r   r'   r   r      s:    



3
r   )__doc__r/   baser   r   r   r   r    r	   r
   r   r   r   r   dialectr   r   r   r   <module>   s   [	 Q