U
    h                     @  s*  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 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 G dd deZG dd deZ G dd deeZ!e!Z"dS )aH  

.. dialect:: mysql+pyodbc
    :name: PyODBC
    :dbapi: pyodbc
    :connectstring: mysql+pyodbc://<username>:<password>@<dsnname>
    :url: https://pypi.org/project/pyodbc/

.. note::

    The PyODBC for MySQL dialect is **not tested as part of
    SQLAlchemy's continuous integration**.
    The recommended MySQL dialects are mysqlclient and PyMySQL.
    However, if you want to use the mysql+pyodbc dialect and require
    full support for ``utf8mb4`` characters (including supplementary
    characters like emoji) be sure to use a current release of
    MySQL Connector/ODBC and specify the "ANSI" (**not** "Unicode")
    version of the driver in your DSN or connection string.

Pass through exact pyodbc connection string::

    import urllib

    connection_string = (
        "DRIVER=MySQL ODBC 8.0 ANSI Driver;"
        "SERVER=localhost;"
        "PORT=3307;"
        "DATABASE=mydb;"
        "UID=root;"
        "PWD=(whatever);"
        "charset=utf8mb4;"
    )
    params = urllib.parse.quote_plus(connection_string)
    connection_uri = "mysql+pyodbc:///?odbc_connect=%s" % params

    )annotationsN)Any)Callable)Optional)Tuple)TYPE_CHECKING)Union   )MySQLDialect)MySQLExecutionContext)TIME   )exc)util)PyODBCConnector)Time)
Connection)DBAPIConnection)Dialect)_ResultProcessorTypec                   @  s   e Zd ZddddddZdS )_pyodbcTIMEr   objectz#_ResultProcessorType[datetime.time])dialectcoltypereturnc                 C  s   ddddd}|S )Nr   zUnion[datetime.time, None])valuer   c                 S  s   | S N )r   r   r   D/tmp/pip-unpacked-wheel-y9ln43lq/sqlalchemy/dialects/mysql/pyodbc.pyprocessK   s    z-_pyodbcTIME.result_processor.<locals>.processr   )selfr   r   r   r   r   r   result_processorH   s    z_pyodbcTIME.result_processorN)__name__
__module____qualname__r!   r   r   r   r   r   G   s   r   c                   @  s   e Zd ZddddZdS )MySQLExecutionContext_pyodbcintr   c                 C  s*   |   }|d | d }|  |S )NzSELECT LAST_INSERT_ID()r   )Zcreate_cursorexecuteZfetchoneclose)r    cursorZ	lastrowidr   r   r   get_lastrowidS   s
    
z*MySQLExecutionContext_pyodbc.get_lastrowidN)r"   r#   r$   r+   r   r   r   r   r%   R   s   r%   c                      st   e Zd ZdZeejee	iZdZ
eZdZdddddZdddd	d
ZdddddZdd fddZ  ZS )MySQLDialect_pyodbcTZMySQLr   str)
connectionr   c                 C  sF   d| _ z| |d}|r|W S W n tjk
r6   Y nX td dS )z:Sniff out the character set in use for connection results.NZcharacter_set_clientz@Could not detect the connection character set.  Assuming latin1.latin1)Z_connection_charsetZ_fetch_settingr   Z
DBAPIErrorr   warn)r    r.   r   r   r   r   _detect_charsetc   s    
z#MySQLDialect_pyodbc._detect_charsetzTuple[int, ...]c                 C  s   t | |S r   )r
   _get_server_version_info)r    r.   r   r   r   r2   |   s    z,MySQLDialect_pyodbc._get_server_version_infoBaseExceptionzOptional[int])	exceptionr   c                 C  s@   t dt|j}|d kr"d S |d}|r8t|S d S d S )Nz	\((\d+)\)r	   )recompilesearchr-   argsgroupr&   )r    r4   mcr   r   r   _extract_error_code   s    
z'MySQLDialect_pyodbc._extract_error_codez!Callable[[DBAPIConnection], None]r'   c                   s"   t    ddd fdd}|S )Nr   None)connr   c                   sD    d k	r |  d}d}| j |dd | j |dd | jdd d S )Nr	   izutf-8)encoding)ZsetdecodingZsetencoding)r>   Zpyodbc_SQL_CHARZpyodbc_SQL_WCHARZsuper_r   r   
on_connect   s    z2MySQLDialect_pyodbc.on_connect.<locals>.on_connect)superrA   )r    rA   	__class__r@   r   rA      s    
zMySQLDialect_pyodbc.on_connect)r"   r#   r$   Zsupports_statement_cacher   Zupdate_copyr
   Zcolspecsr   r   Zsupports_unicode_statementsr%   Zexecution_ctx_clsZpyodbc_driver_namer1   r2   r<   rA   __classcell__r   r   rC   r   r,   [   s   
r,   )#__doc__
__future__r   datetimer5   typingr   r   r   r   r   r   baser
   r   typesr    r   r   Zconnectors.pyodbcr   Zsql.sqltypesr   Zenginer   Zengine.interfacesr   r   Zsql.type_apir   r   r%   r,   r   r   r   r   r   <module>	   s2   $	B