o
    ŠågŠ3  ã                   @   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 ddlmZ ddlmZ G dd„ dƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ dƒZG dd„ deƒZG dd„ de	ƒZeZdS )až  

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

Similarly to pysqlite, aiosqlite does not support SAVEPOINT feature.

The solution is similar to :ref:`pysqlite_serializable`. This is achieved by the event listeners in async::

    from sqlalchemy import create_engine, event
    from sqlalchemy.ext.asyncio import create_async_engine

    engine = create_async_engine("sqlite+aiosqlite:///myfile.db")


    @event.listens_for(engine.sync_engine, "connect")
    def do_connect(dbapi_connection, connection_record):
        # disable aiosqlite's emitting of the BEGIN statement entirely.
        # also stops it from emitting COMMIT before any DDL.
        dbapi_connection.isolation_level = None


    @event.listens_for(engine.sync_engine, "begin")
    def do_begin(conn):
        # emit our own BEGIN
        conn.exec_driver_sql("BEGIN")

.. warning:: When using the above recipe, it is advised to not use the
   :paramref:`.Connection.execution_options.isolation_level` setting on
   :class:`_engine.Connection` and :func:`_sa.create_engine`
   with the SQLite driver,
   as this function necessarily will also alter the ".isolation_level" setting.

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

é    N)Údeque)Úpartialé   )ÚSQLiteExecutionContext)ÚSQLiteDialect_pysqliteé   )Úpool)Úutil)ÚAdaptedConnection)Úawait_fallback)Ú
await_onlyc                   @   s`   e Zd ZdZdZdd„ Zdd„ Zddd	„Zd
d„ Zdd„ Z	dd„ Z
dd„ Zddd„Zdd„ ZdS )ÚAsyncAdapt_aiosqlite_cursor)Ú_adapt_connectionÚ_connectionÚdescriptionÚawait_Ú_rowsÚ	arraysizeÚrowcountÚ	lastrowidFc                 C   s4   || _ |j| _|j| _d| _d| _d | _tƒ | _d S )Nr   éÿÿÿÿ)r   r   r   r   r   r   r   r   )ÚselfÚadapt_connection© r   ú`/var/www/html/flaskapp/venv/lib/python3.10/site-packages/sqlalchemy/dialects/sqlite/aiosqlite.pyÚ__init__‡   s   z$AsyncAdapt_aiosqlite_cursor.__init__c                 C   s   | j  ¡  d S ©N)r   Úclear©r   r   r   r   Úclose�   ó   z!AsyncAdapt_aiosqlite_cursor.closeNc              
   C   sâ   zW|   | j ¡ ¡}|d u r|   | |¡¡ n	|   | ||¡¡ |jr:|j| _d | _| _| js9t|   | 	¡ ¡ƒ| _
nd | _|j| _|j| _| jsR|   | ¡ ¡ W d S || _W d S  typ } z| j |¡ W Y d }~d S d }~ww )Nr   )r   r   ÚcursorÚexecuter   r   r   Úserver_sider   Úfetchallr   r   Ú_cursorÚ	Exceptionr   Ú_handle_exception)r   Ú	operationÚ
parametersr%   Úerrorr   r   r   r"   “   s*   €€ÿz#AsyncAdapt_aiosqlite_cursor.executec              
   C   s€   z&|   | j ¡ ¡}|   | ||¡¡ d | _|j| _|j| _|   | ¡ ¡ W d S  ty? } z| j	 
|¡ W Y d }~d S d }~ww r   )r   r   r!   Úexecutemanyr   r   r   r   r&   r   r'   )r   r(   Úseq_of_parametersr%   r*   r   r   r   r+   ®   s   €ÿz'AsyncAdapt_aiosqlite_cursor.executemanyc                 G   s   d S r   r   )r   Ú
inputsizesr   r   r   Úsetinputsizes¹   s   z)AsyncAdapt_aiosqlite_cursor.setinputsizesc                 c   s"   � | j r| j  ¡ V  | j sd S d S r   ©r   Úpopleftr   r   r   r   Ú__iter__¼   s   €ÿz$AsyncAdapt_aiosqlite_cursor.__iter__c                 C   s   | j r| j  ¡ S d S r   r/   r   r   r   r   ÚfetchoneÀ   s   
z$AsyncAdapt_aiosqlite_cursor.fetchonec                    s4   |d u r| j }| j‰ ‡ fdd„tt|tˆ ƒƒƒD ƒS )Nc                    s   g | ]}ˆ   ¡ ‘qS r   )r0   )Ú.0Ú_©Úrrr   r   Ú
<listcomp>Ë   s    z9AsyncAdapt_aiosqlite_cursor.fetchmany.<locals>.<listcomp>)r   r   ÚrangeÚminÚlen©r   Úsizer   r5   r   Ú	fetchmanyÆ   s    z%AsyncAdapt_aiosqlite_cursor.fetchmanyc                 C   s   t | jƒ}| j ¡  |S r   )Úlistr   r   )r   Úretvalr   r   r   r$   Í   s   

z$AsyncAdapt_aiosqlite_cursor.fetchallr   )Ú__name__Ú
__module__Ú__qualname__Ú	__slots__r#   r   r   r"   r+   r.   r1   r2   r=   r$   r   r   r   r   r   v   s    	

r   c                       sF   e Zd ZdZdZ‡ fdd„Zdd„ Zdd„ Zdd
d„Zdd„ Z	‡  Z
S )ÚAsyncAdapt_aiosqlite_ss_cursorr%   Tc                    s   t ƒ j|i |¤Ž d | _d S r   )Úsuperr   r%   )r   ÚargÚkw©Ú	__class__r   r   r   Ú   s   
z'AsyncAdapt_aiosqlite_ss_cursor.__init__c                 C   s(   | j d ur|  | j  ¡ ¡ d | _ d S d S r   )r%   r   r   r   r   r   r   r   Þ   s   

þz$AsyncAdapt_aiosqlite_ss_cursor.closec                 C   ó   |   | j ¡ ¡S r   )r   r%   r2   r   r   r   r   r2   ã   ó   z'AsyncAdapt_aiosqlite_ss_cursor.fetchoneNc                 C   s"   |d u r| j }|  | jj|d�¡S )N)r<   )r   r   r%   r=   r;   r   r   r   r=   æ   s   z(AsyncAdapt_aiosqlite_ss_cursor.fetchmanyc                 C   rJ   r   )r   r%   r$   r   r   r   r   r$   ë   rK   z'AsyncAdapt_aiosqlite_ss_cursor.fetchallr   )r@   rA   rB   rC   r#   r   r   r2   r=   r$   Ú__classcell__r   r   rH   r   rD   Ó   s    
rD   c                   @   st   e Zd ZeeƒZdZdd„ Zedd„ ƒZ	e	j
dd„ ƒZ	dd„ Zdd
d„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )ÚAsyncAdapt_aiosqlite_connection)Údbapic                 C   s   || _ || _d S r   )rN   r   )r   rN   Ú
connectionr   r   r   r   ó   s   
z(AsyncAdapt_aiosqlite_connection.__init__c                 C   s   | j jS r   )r   Úisolation_levelr   r   r   r   rP   ÷   s   z/AsyncAdapt_aiosqlite_connection.isolation_levelc              
   C   st   dd„ }t || jj|ƒ}t ¡  ¡ }| jj ||f¡ z|  |¡W S  t	y9 } z|  
|¡ W Y d }~d S d }~ww )Nc                 S   s
   || _ d S r   )rP   )rO   Úvaluer   r   r   Úset_iso  s   
z@AsyncAdapt_aiosqlite_connection.isolation_level.<locals>.set_iso)r   r   Ú_connÚasyncioÚget_event_loopÚcreate_futureÚ_txÚ
put_nowaitr   r&   r'   )r   rQ   rR   ÚfunctionÚfuturer*   r   r   r   rP   û   s   €ÿc              
   O   sP   z|   | jj|i |¤Ž¡ W d S  ty' } z|  |¡ W Y d }~d S d }~ww r   )r   r   Úcreate_functionr&   r'   )r   ÚargsrG   r*   r   r   r   r[     s   €ÿz/AsyncAdapt_aiosqlite_connection.create_functionFc                 C   s   |rt | ƒS t| ƒS r   )rD   r   )r   r#   r   r   r   r!     s   z&AsyncAdapt_aiosqlite_connection.cursorc                 O   s   |   | jj|i |¤Ž¡S r   )r   r   r"   )r   r\   rG   r   r   r   r"     s   z'AsyncAdapt_aiosqlite_connection.executec              
   C   óH   z|   | j ¡ ¡ W d S  ty# } z|  |¡ W Y d }~d S d }~ww r   )r   r   Úrollbackr&   r'   ©r   r*   r   r   r   r^     ó   €ÿz(AsyncAdapt_aiosqlite_connection.rollbackc              
   C   r]   r   )r   r   Úcommitr&   r'   r_   r   r   r   ra   $  r`   z&AsyncAdapt_aiosqlite_connection.commitc              
   C   sZ   z|   | j ¡ ¡ W d S  ty   Y d S  ty, } z|  |¡ W Y d }~d S d }~ww r   )r   r   r   Ú
ValueErrorr&   r'   r_   r   r   r   r   *  s   	€ÿz%AsyncAdapt_aiosqlite_connection.closec                 C   s,   t |tƒr|jd dkr| jj d¡|‚|‚)Nr   úno active connection)Ú
isinstancerb   r\   rN   ÚsqliteÚOperationalErrorr_   r   r   r   r'   :  s   ÿÿþz1AsyncAdapt_aiosqlite_connection._handle_exceptionN)F)r@   rA   rB   Ústaticmethodr   r   rC   r   ÚpropertyrP   Úsetterr[   r!   r"   r^   ra   r   r'   r   r   r   r   rM   ï   s    


rM   c                   @   s   e Zd ZdZeeƒZdS )Ú'AsyncAdaptFallback_aiosqlite_connectionr   N)r@   rA   rB   rC   rg   r   r   r   r   r   r   rj   F  s    rj   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚAsyncAdapt_aiosqlite_dbapic                 C   s   || _ || _d| _|  ¡  d S )NÚqmark)Ú	aiosqlitere   Ú
paramstyleÚ_init_dbapi_attributes)r   rm   re   r   r   r   r   M  s   z#AsyncAdapt_aiosqlite_dbapi.__init__c                 C   s^   dD ]}t | |t| j|ƒƒ qdD ]}t | |t| j|ƒƒ qdD ]}t | |t| j|ƒƒ q d S )N)ÚDatabaseErrorÚErrorÚIntegrityErrorÚNotSupportedErrorrf   ÚProgrammingErrorÚsqlite_versionÚsqlite_version_info)ÚPARSE_COLNAMESÚPARSE_DECLTYPES)ÚBinary)ÚsetattrÚgetattrrm   re   )r   Únamer   r   r   ro   S  s   
ÿz1AsyncAdapt_aiosqlite_dbapi._init_dbapi_attributesc                 O   sj   |  dd¡}|  dd ¡}|r||i |¤Ž}n| jj|i |¤Ž}d|_t |¡r.t| t|ƒƒS t| t	|ƒƒS )NÚasync_fallbackFÚasync_creator_fnT)
Úpoprm   ÚconnectÚdaemonr	   Úasboolrj   r   rM   r   )r   rF   rG   r}   Ú
creator_fnrO   r   r   r   r€   f  s   
þþz"AsyncAdapt_aiosqlite_dbapi.connectN)r@   rA   rB   r   ro   r€   r   r   r   r   rk   L  s    rk   c                   @   s   e Zd Zdd„ ZdS )Ú SQLiteExecutionContext_aiosqlitec                 C   s   | j jdd�S )NT)r#   )Ú_dbapi_connectionr!   r   r   r   r   Úcreate_server_side_cursor~  r    z:SQLiteExecutionContext_aiosqlite.create_server_side_cursorN)r@   rA   rB   r†   r   r   r   r   r„   }  s    r„   c                       sP   e Zd ZdZdZdZdZeZe	dd„ ƒZ
e	dd„ ƒZ‡ fdd„Zd	d
„ Z‡  ZS )ÚSQLiteDialect_aiosqliterm   Tc                 C   s   t tdƒtdƒƒS )Nrm   Úsqlite3)rk   Ú
__import__)Úclsr   r   r   Úimport_dbapiŒ  s   ÿz$SQLiteDialect_aiosqlite.import_dbapic                 C   s   |   |¡rtjS tjS r   )Ú_is_url_file_dbr   ÚAsyncAdaptedQueuePoolÚ
StaticPool)rŠ   Úurlr   r   r   Úget_pool_class’  s   
z&SQLiteDialect_aiosqlite.get_pool_classc                    s.   t || jjƒrdt|ƒv rdS tƒ  |||¡S )Nrc   T)rd   rN   rf   ÚstrrE   Úis_disconnect)r   ÚerO   r!   rH   r   r   r’   ™  s   ÿz%SQLiteDialect_aiosqlite.is_disconnectc                 C   s   |j S r   )r   )r   rO   r   r   r   Úget_driver_connection¡  s   z-SQLiteDialect_aiosqlite.get_driver_connection)r@   rA   rB   ÚdriverÚsupports_statement_cacheÚis_asyncÚsupports_server_side_cursorsr„   Úexecution_ctx_clsÚclassmethodr‹   r�   r’   r”   rL   r   r   rH   r   r‡   ‚  s    

r‡   )Ú__doc__rT   Úcollectionsr   Ú	functoolsr   Úbaser   Úpysqliter   Ú r   r	   Úenginer
   Úutil.concurrencyr   r   r   rD   rM   rj   rk   r„   r‡   Údialectr   r   r   r   Ú<module>   s&   	_]W1#