U
    h9                     @  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 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, dd#l-m.Z. G d$d% d%Z/G d&d' d'e/Z0G d(d) d)eZ1G d*d+ d+e1Z2G d,d- d-eZ3G d.d/ d/eZ4G d0d1 d1eZ5e5Z6dS )2a	  

.. dialect:: sqlite+aiosqlite
    :name: aiosqlite
    :dbapi: aiosqlite
    :connectstring: sqlite+aiosqlite:///file_path
    :url: https://pypi.org/project/aiosqlite/

The aiosqlite dialect provides support for the SQLAlchemy asyncio interface
running on top of pysqlite.

aiosqlite is a wrapper around pysqlite that uses a background thread for
each connection.   It does not actually use non-blocking IO, as SQLite
databases are not socket-based.  However it does provide a working asyncio
interface that's useful for testing and prototyping purposes.

Using a special asyncio mediation layer, the aiosqlite dialect is usable
as the backend for the :ref:`SQLAlchemy asyncio <asyncio_toplevel>`
extension package.

This dialect should normally be used only with the
:func:`_asyncio.create_async_engine` engine creation function::

    from sqlalchemy.ext.asyncio import create_async_engine

    engine = create_async_engine("sqlite+aiosqlite:///filename")

The URL passes through all arguments to the ``pysqlite`` driver, so all
connection arguments are the same as they are for that of :ref:`pysqlite`.

.. _aiosqlite_udfs:

User-Defined Functions
----------------------

aiosqlite extends pysqlite to support async, so we can create our own user-defined functions (UDFs)
in Python and use them directly in SQLite queries as described here: :ref:`pysqlite_udfs`.

.. _aiosqlite_serializable:

Serializable isolation / Savepoints / Transactional DDL (asyncio version)
-------------------------------------------------------------------------

A newly revised version of this important section is now available
at the top level of the SQLAlchemy SQLite documentation, in the section
:ref:`sqlite_transactions`.


.. _aiosqlite_pooling:

Pooling Behavior
----------------

The SQLAlchemy ``aiosqlite`` DBAPI establishes the connection pool differently
based on the kind of SQLite database that's requested:

* When a ``:memory:`` SQLite database is specified, the dialect by default
  will use :class:`.StaticPool`. This pool maintains a single
  connection, so that all access to the engine
  use the same ``:memory:`` database.
* When a file-based database is specified, the dialect will use
  :class:`.AsyncAdaptedQueuePool` as the source of connections.

  .. versionchanged:: 2.0.38

    SQLite file database engines now use :class:`.AsyncAdaptedQueuePool` by default.
    Previously, :class:`.NullPool` were used.  The :class:`.NullPool` class
    may be used by specifying it via the
    :paramref:`_sa.create_engine.poolclass` parameter.

    )annotationsN)deque)partial)
ModuleType)Any)cast)Deque)Iterator)NoReturn)Optional)Sequence)TYPE_CHECKING)Union   )SQLiteExecutionContext)SQLiteDialect_pysqlite   )pool)util)AsyncAdapt_dbapi_module)AdaptedConnection)await_fallback)
await_only)AsyncIODBAPIConnection)AsyncIODBAPICursor)_DBAPICursorDescription)_DBAPIMultiExecuteParams)_DBAPISingleExecuteParams)DBAPIConnection)DBAPICursor)DBAPIModule)URL)PoolProxiedConnectionc                   @  s   e Zd ZdZdZddddZddd	d
Zd%ddddddZddddddZdddddZ	ddddZ
ddddZd&ddd d!d"Zddd#d$ZdS )'AsyncAdapt_aiosqlite_cursor)_adapt_connection_connectiondescriptionawait__rows	arraysizerowcount	lastrowidFAsyncAdapt_aiosqlite_connection)adapt_connectionc                 C  s4   || _ |j| _|j| _d| _d| _d | _t | _d S )Nr   )r$   r%   r'   r)   r*   r&   r   r(   )selfr-    r0   H/tmp/pip-unpacked-wheel-y9ln43lq/sqlalchemy/dialects/sqlite/aiosqlite.py__init__   s    z$AsyncAdapt_aiosqlite_cursor.__init__Nonereturnc                 C  s   | j   d S N)r(   clearr/   r0   r0   r1   close   s    z!AsyncAdapt_aiosqlite_cursor.closeNr   z#Optional[_DBAPISingleExecuteParams])	operation
parametersr5   c              
   C  s   z|  | j }|d kr,|  || n|  ||| |jrt|j| _d | _| _| jst|  |	 | _
nd | _|j| _|j| _| js|  |  n|| _W n. tk
r } z| j| W 5 d }~X Y nX d S )Nr.   )r'   r%   cursorexecuter&   r+   r*   server_sider   fetchallr(   r9   _cursor	Exceptionr$   _handle_exception)r/   r:   r;   r@   errorr0   r0   r1   r=      s$    
z#AsyncAdapt_aiosqlite_cursor.executer   )r:   seq_of_parametersr5   c              
   C  s~   zJ|  | j }|  ||| d | _|j| _|j| _|  |  W n. tk
rx } z| j	
| W 5 d }~X Y nX d S r6   )r'   r%   r<   executemanyr&   r+   r*   r9   rA   r$   rB   )r/   r:   rD   r@   rC   r0   r0   r1   rE      s    z'AsyncAdapt_aiosqlite_cursor.executemany)
inputsizesr5   c                 G  s   d S r6   r0   )r/   rF   r0   r0   r1   setinputsizes   s    z)AsyncAdapt_aiosqlite_cursor.setinputsizeszIterator[Any]c                 c  s   | j r| j  V  q d S r6   r(   popleftr8   r0   r0   r1   __iter__   s    z$AsyncAdapt_aiosqlite_cursor.__iter__Optional[Any]c                 C  s   | j r| j  S d S d S r6   rH   r8   r0   r0   r1   fetchone   s    
z$AsyncAdapt_aiosqlite_cursor.fetchoneOptional[int]Sequence[Any]sizer5   c                   s4   |d kr| j }| j  fddtt|t D S )Nc                   s   g | ]}   qS r0   )rI   ).0_rrr0   r1   
<listcomp>   s     z9AsyncAdapt_aiosqlite_cursor.fetchmany.<locals>.<listcomp>)r)   r(   rangeminlenr/   rP   r0   rS   r1   	fetchmany   s    z%AsyncAdapt_aiosqlite_cursor.fetchmanyc                 C  s   t | j}| j  |S r6   )listr(   r7   )r/   retvalr0   r0   r1   r?      s    

z$AsyncAdapt_aiosqlite_cursor.fetchall)N)N)__name__
__module____qualname__	__slots__r>   r2   r9   r=   rE   rG   rJ   rL   rZ   r?   r0   r0   r0   r1   r#   v   s   	  r#   c                      sj   e Zd ZdZdZdddd fddZddd	d
ZddddZddddddZddddZ	  Z
S )AsyncAdapt_aiosqlite_ss_cursorr@   Tr   r3   argkwr5   c                   s   t  j|| d | _d S r6   )superr2   r@   )r/   rc   rd   	__class__r0   r1   r2      s    z'AsyncAdapt_aiosqlite_ss_cursor.__init__r4   c                 C  s$   | j d k	r | | j   d | _ d S r6   )r@   r'   r9   r8   r0   r0   r1   r9      s    
z$AsyncAdapt_aiosqlite_ss_cursor.closerK   c                 C  s   | j d k	st| | j  S r6   )r@   AssertionErrorr'   rL   r8   r0   r0   r1   rL      s    z'AsyncAdapt_aiosqlite_ss_cursor.fetchoneNrM   rN   rO   c                 C  s0   | j d k	st|d kr| j}| | j j|dS )N)rP   )r@   rh   r)   r'   rZ   rY   r0   r0   r1   rZ      s    z(AsyncAdapt_aiosqlite_ss_cursor.fetchmanyc                 C  s   | j d k	st| | j  S r6   )r@   rh   r'   r?   r8   r0   r0   r1   r?      s    z'AsyncAdapt_aiosqlite_ss_cursor.fetchall)N)r]   r^   r_   r`   r>   r2   r9   rL   rZ   r?   __classcell__r0   r0   rf   r1   ra      s   ra   c                   @  s   e Zd ZeeZdZddddddZedd	d
dZ	e	j
dddddZ	ddddddZd%dddddZddddddZdd	ddZdd	ddZdd	ddZdd d!d"d#Zd$S )&r,   )dbapir   r   r3   )rj   
connectionr5   c                 C  s   || _ || _d S r6   )rj   r%   )r/   rj   rk   r0   r0   r1   r2      s    z(AsyncAdapt_aiosqlite_connection.__init__Optional[str]r4   c                 C  s   t t| jjS r6   )r   strr%   isolation_levelr8   r0   r0   r1   rn     s    z/AsyncAdapt_aiosqlite_connection.isolation_level)valuer5   c              
   C  s   dddddd}t || jj|}t  }| jj||f z| | W n, t	k
rz } z| 
| W 5 d }~X Y nX d S )Nr,   rl   r3   )rk   ro   r5   c                 S  s
   || _ d S r6   )rn   )rk   ro   r0   r0   r1   set_iso  s    z@AsyncAdapt_aiosqlite_connection.isolation_level.<locals>.set_iso)r   r%   Z_connasyncioZget_event_loopZcreate_futureZ_tx
put_nowaitr'   rA   rB   )r/   ro   rp   functionfuturerC   r0   r0   r1   rn     s    )argsrd   r5   c              
   O  sJ   z|  | jj|| W n, tk
rD } z| | W 5 d }~X Y nX d S r6   )r'   r%   create_functionrA   rB   )r/   ru   rd   rC   r0   r0   r1   rv     s    z/AsyncAdapt_aiosqlite_connection.create_functionFboolr#   )r>   r5   c                 C  s   |rt | S t| S d S r6   )ra   r#   )r/   r>   r0   r0   r1   r<   #  s    z&AsyncAdapt_aiosqlite_connection.cursorc                 O  s   |  | jj||S r6   )r'   r%   r=   )r/   ru   rd   r0   r0   r1   r=   )  s    z'AsyncAdapt_aiosqlite_connection.executec              
   C  sF   z|  | j  W n, tk
r@ } z| | W 5 d }~X Y nX d S r6   )r'   r%   rollbackrA   rB   r/   rC   r0   r0   r1   rx   ,  s    z(AsyncAdapt_aiosqlite_connection.rollbackc              
   C  sF   z|  | j  W n, tk
r@ } z| | W 5 d }~X Y nX d S r6   )r'   r%   commitrA   rB   ry   r0   r0   r1   rz   2  s    z&AsyncAdapt_aiosqlite_connection.commitc              
   C  sX   z|  | j  W n> tk
r(   Y n, tk
rR } z| | W 5 d }~X Y nX d S r6   )r'   r%   r9   
ValueErrorrA   rB   ry   r0   r0   r1   r9   8  s    	z%AsyncAdapt_aiosqlite_connection.closerA   r
   )rC   r5   c                 C  s2   t |tr*|jd dkr*| jjd|n|d S )Nr   no active connection)
isinstancer{   ru   rj   sqliteOperationalErrorry   r0   r0   r1   rB   H  s    z1AsyncAdapt_aiosqlite_connection._handle_exceptionN)F)r]   r^   r_   staticmethodr   r'   r`   r2   propertyrn   setterrv   r<   r=   rx   rz   r9   rB   r0   r0   r0   r1   r,      s   r,   c                   @  s   e Zd ZdZeeZdS )'AsyncAdaptFallback_aiosqlite_connectionr0   N)r]   r^   r_   r`   r   r   r'   r0   r0   r0   r1   r   T  s   r   c                   @  s<   e Zd ZdddddZddddZd	d	d
dddZdS )AsyncAdapt_aiosqlite_dbapir   )	aiosqliter~   c                 C  s   || _ || _d| _|   d S )NZqmark)r   r~   Z
paramstyle_init_dbapi_attributes)r/   r   r~   r0   r0   r1   r2   [  s    z#AsyncAdapt_aiosqlite_dbapi.__init__r3   r4   c                 C  s^   dD ]}t | |t| j| qdD ]}t | |t| j| q"dD ]}t | |t| j| q@d S )N)ZDatabaseErrorErrorZIntegrityErrorZNotSupportedErrorr   ZProgrammingErrorZsqlite_versionZsqlite_version_info)ZPARSE_COLNAMESZPARSE_DECLTYPES)Binary)setattrgetattrr   r~   )r/   namer0   r0   r1   r   a  s    
z1AsyncAdapt_aiosqlite_dbapi._init_dbapi_attributesr   r,   rb   c                 O  sf   | dd}| dd }|r(|||}n| jj||}d|_t|rTt| t|S t| t	|S d S )Nasync_fallbackFZasync_creator_fnT)
popr   connectdaemonr   Zasboolr   r   r,   r   )r/   rc   rd   r   Z
creator_fnrk   r0   r0   r1   r   t  s    
z"AsyncAdapt_aiosqlite_dbapi.connectN)r]   r^   r_   r2   r   r   r0   r0   r0   r1   r   Z  s   r   c                   @  s   e Zd ZddddZdS ) SQLiteExecutionContext_aiosqliter   r4   c                 C  s   | j jddS )NT)r>   )Z_dbapi_connectionr<   r8   r0   r0   r1   create_server_side_cursor  s    z:SQLiteExecutionContext_aiosqlite.create_server_side_cursorN)r]   r^   r_   r   r0   r0   r0   r1   r     s   r   c                      sr   e Zd ZdZdZdZdZeZe	ddddZ
e	ddd	d
dZddddd fddZdddddZ  ZS )SQLiteDialect_aiosqliter   Tr   r4   c                 C  s   t tdtdS )Nr   Zsqlite3)r   
__import__)clsr0   r0   r1   import_dbapi  s     z$SQLiteDialect_aiosqlite.import_dbapir!   ztype[pool.Pool])urlr5   c                 C  s   |  |rtjS tjS d S r6   )Z_is_url_file_dbr   ZAsyncAdaptedQueuePoolZ
StaticPool)r   r   r0   r0   r1   get_pool_class  s    
z&SQLiteDialect_aiosqlite.get_pool_classzDBAPIModule.Errorz7Optional[Union[PoolProxiedConnection, DBAPIConnection]]zOptional[DBAPICursor]rw   )erk   r<   r5   c                   s<   t d| j| _t|| jjr,dt|kr,dS t |||S )Nr    r|   T)r   rj   r}   r   rm   re   is_disconnect)r/   r   rk   r<   rf   r0   r1   r     s     
z%SQLiteDialect_aiosqlite.is_disconnectr   r   )rk   r5   c                 C  s   |j S r6   )r%   )r/   rk   r0   r0   r1   get_driver_connection  s    z-SQLiteDialect_aiosqlite.get_driver_connection)r]   r^   r_   ZdriverZsupports_statement_cacheZis_asyncZsupports_server_side_cursorsr   Zexecution_ctx_clsclassmethodr   r   r   r   ri   r0   r0   rf   r1   r     s   r   )7__doc__
__future__r   rq   collectionsr   	functoolsr   typesr   typingr   r   r   r	   r
   r   r   r   r   baser   Zpysqliter    r   r   Zconnectors.asyncior   Zenginer   Zutil.concurrencyr   r   r   r   Zengine.interfacesr   r   r   r   r   r    Z
engine.urlr!   Z	pool.baser"   r#   ra   r,   r   r   r   r   dialectr0   r0   r0   r1   <module>	   sR   GfY1+