U
    [hf4                     @  s  d dl mZ d dl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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 ejrd
dlmZ d
dlmZ d
dlmZ G dd dZe Zedd Zedd Zedd Zedd Z d6ddZ!G dd dZ"d7d d!Z#ej$d8d#d$d%d&d'd(d)d*Z%ej$d9d#d$d,d&d-d(d.d*Z%d:d/d*Z%d;d0d1Z&G d2d3 d3Z'G d4d5 d5Z(dS )<    )annotationsN)Any)Dict)Optional   )config)	decorator)
gc_collect   )event)pool)
await_only)Literal)Engine)URL)AsyncEnginec                   @  s   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#S )$ConnectionKillerc                 C  s"   t  | _tt| _t | _d S N)weakrefWeakKeyDictionary
proxy_refscollectionsdefaultdictsettesting_enginesdbapi_connectionsself r   @./venv/lib/python3.8/site-packages/sqlalchemy/testing/engines.py__init__%   s    
zConnectionKiller.__init__c                 C  sD   t |d| j t |d| j t |d| j t |d| j d S )NZcheckoutZcheckincloseZclose_detached)r   Zlisten	_add_conn_remove_conn)r   r   r   r   r   add_pool*   s    zConnectionKiller.add_poolc                 C  s   | j | d| j|< d S )NT)r   addr   )r   Z	dbapi_conZ
con_recordZ	con_proxyr   r   r   r"   2   s    zConnectionKiller._add_connc                 G  s   | j | d S r   )r   discard)r   Z
dbapi_connargr   r   r   r#   6   s    zConnectionKiller._remove_connc                 C  s,   |  |j |dkst| j| | d S )N)classglobalfunctionZfixture)r$   r   AssertionErrorr   r%   )r   enginescoper   r   r   
add_engine9   s    zConnectionKiller.add_enginec              
   C  s@   z
|  W n0 t k
r: } ztd|  W 5 d }~X Y nX d S )Nz5testing_reaper couldn't rollback/close connection: %s	Exceptionwarningswarnr   fner   r   r   _safe?   s    
zConnectionKiller._safec                 C  s.   t | jD ]}|d k	r
|jr
| |j q
d S r   )listr   is_validr6   rollbackr   recr   r   r   rollback_allG   s    zConnectionKiller.rollback_allc                 C  s^   t | jD ],}|d k	r
|jr
| j|j | |j q
| jD ]}| |j q>| j	  d S r   )
r7   r   r8   r   r&   dbapi_connectionr6   _checkinr9   clear)r   r;   Zconr   r   r   checkin_allL   s    
zConnectionKiller.checkin_allc                 C  s   |    d S r   )r@   r   r   r   r   	close_all[   s    zConnectionKiller.close_allc                 C  s*   t js
d S ddlm} ||jj| d S Nr   )	provision)r   bootstrapped_as_sqlalchemy rC   prepare_for_drop_tablesr,   url)r   
connectionrC   r   r   r   rF   ^   s    z(ConnectionKiller.prepare_for_drop_tablesc                 C  s   | j | }t|D ]d}t| jD ]4}|d k	r |jr |jd k	r |j|jkr | |j q t|drnt	|
  q|
  q|  d S )Nsync_engine)r   r7   r   r8   Z_poolr   r6   r>   hasattrr   disposer?   )r   r-   Zengr;   Z	proxy_refr   r   r   _drop_testing_enginesg   s    



z&ConnectionKiller._drop_testing_enginesc                 C  s   |  d d S )Nr*   )rL   r   r   r   r   
after_testx   s    zConnectionKiller.after_testc              	   C  sT   t js
d S |jjrd S |   ddlm} t j }|	|j
j| W 5 Q R X d S rB   )r   rD   	__class__Z"__leave_connections_for_teardown__r@   rE   rC   dbconnectrF   r,   rG   )r   ZtestrC   connr   r   r   after_test_outside_fixtures{   s    z,ConnectionKiller.after_test_outside_fixturesc                 C  s    |    | d | d d S )Nr*   r(   )r@   rL   r   r   r   r   stop_test_class_inside_fixtures   s    
z0ConnectionKiller.stop_test_class_inside_fixturesc                 C  sB   t jjr>t  t jjr>tt jj}t jj  ds>td| d S )NFz/%d connection recs not cleared after test suite)r   baseZ_strong_ref_connection_recordsr	   lenr?   r+   )r   Zlnr   r   r    stop_test_class_outside_fixtures   s    z1ConnectionKiller.stop_test_class_outside_fixturesc                 C  s"   |    | jD ]}| | qd S r   )r@   r   rL   )r   r-   r   r   r   final_cleanup   s    
zConnectionKiller.final_cleanupc                 C  s   | j D ]}|jrdstqd S NF)r   r8   r+   r:   r   r   r   assert_all_closed   s    
z"ConnectionKiller.assert_all_closedN)__name__
__module____qualname__r    r$   r"   r#   r.   r6   r<   r@   rA   rF   rL   rM   rR   rS   rV   rW   rY   r   r   r   r   r   $   s"   	r   c                 O  s   z| || W 5 t   X d S r   )testing_reaperrY   r4   argskwr   r   r   assert_conns_closed   s    ra   c                 O  s   z| || W 5 t   X dS )zBDecorator that rolls back all open connections after fn execution.N)r]   r<   r^   r   r   r   rollback_open_connections   s    rb   c                 O  s   t   | || dS )z:Decorator that closes all connections before fn execution.Nr]   r@   r^   r   r   r   close_first   s    rd   c                 O  s   z| || W 5 t   X dS )z9Decorator that closes all connections after fn execution.Nrc   r^   r   r   r   close_open_connections   s    re   c                 c  sX   dd l m} |jD ]@}| r$|| kr$qt||d }|sHttd| j|}| V  qd S )Nr   zsqlalchemy.dialects.%s)Zsqlalchemy.dialectsZdialects__all__getattr
__import__dialect)Zexcludednamemodr   r   r   all_dialects   s    
 rm   c                   @  s>   e Zd Zdd Zdd Zdd Zdd Zdd
dZdd ZdS )ReconnectFixturec                 C  s   || _ g | _d| _d S rX   )dbapiconnections
is_stopped)r   ro   r   r   r   r       s    zReconnectFixture.__init__c                 C  s   t | j|S r   )rg   ro   r   keyr   r   r   __getattr__   s    zReconnectFixture.__getattr__c                 O  sT   | j j||}| jr@| |j | }|d dsPtdn| j	| |S d S )Nzselect 1Fz%simulated connect failure didn't work)
ro   rP   rq   r6   r!   cursorexecuter+   rp   append)r   r_   kwargsrQ   Zcursr   r   r   rP      s    
zReconnectFixture.connectc              
   C  s@   z
|  W n0 t k
r: } ztd|  W 5 d }~X Y nX d S )Nz.ReconnectFixture couldn't close connection: %sr/   r3   r   r   r   r6      s    
zReconnectFixture._safeFc                 C  s,   || _ t| jD ]}| |j qg | _d S r   )rq   r7   rp   r6   r!   )r   stopcr   r   r   shutdown   s    zReconnectFixture.shutdownc                 C  s
   d| _ d S rX   )rq   r   r   r   r   restart  s    zReconnectFixture.restartN)F)	rZ   r[   r\   r    rt   rP   r6   r{   r|   r   r   r   r   rn      s   
rn   c                   sj   | p
t jj} t jjj}|si }t||d< t| |j  fdd}jjj_	jjj
_|_S )Nmodulec                     s    j j  dj j_   d S rX   )ri   ro   r{   rq   r   Z_disposer,   r   r   rK     s    
z$reconnecting_engine.<locals>.dispose)r   rO   rG   ri   ro   rn   testing_enginerK   r{   Ztest_shutdownr|   Ztest_restart)rG   optionsro   rK   r   r~   r   reconnecting_engine
  s    

r   FzOptional[URL]zOptional[Dict[str, Any]]zLiteral[False]boolr   )rG   r   asynciotransfer_staticpoolreturnc                 C  s   d S r   r   rG   r   r   r   r   r   r   r     s    r   TzLiteral[True]r   c                 C  s   d S r   r   r   r   r   r   r   '  s    c                 C  s  |r|rt ddlm} nddlm} ddlm} |sDd}d}	d}
n$|dd}|d	d}	|d
d}
| prtj	j
} || } tj	d ks| jtj	j
jkrtjrtj }ni }|d k	r|| || f|}|
r|jdkrt|ddd }t|ddd }|rHddlm} tj	d k	rXttj	j|rXd}|jtj	j n|rXtj	j|_|	dkrx|rrd|j_nd|_t|jtjrd|krd|krd|krd|j_d|j_|rt||	 |S )Nr   )create_async_engine)create_engine)make_urlTr*   F
use_reaperr-   sqlite_savepointZsqliterP   c                 S  s
   d | _ d S r   )Zisolation_level)r=   Zconnection_recordr   r   r   
do_connect\  s    z"testing_engine.<locals>.do_connectZbeginc                 S  s   |  d d S )NZBEGIN)Zexec_driver_sql)rQ   r   r   r   do_begin`  s    z testing_engine.<locals>.do_begin)
StaticPoolr)   r   Zpool_timeoutZmax_overflow)r+   Zsqlalchemy.ext.asyncior   
sqlalchemyr   Zsqlalchemy.engine.urlr   popr   rO   rG   Z
drivernameZdb_optscopyupdaterk   r   Zlistens_forZsqlalchemy.poolr   
isinstancer   Z_transfer_fromrI   Z_has_eventsZ	QueuePool_timeoutZ_max_overflowr]   r.   )rG   r   r   r   Z
share_poolZ_sqlite_savepointr   r   r   r-   r   Zuse_optionsr,   r   r   r   r   r   r   r   0  sn    







c                   sr   ddl m} | stjj} g   fdd} fdd}fdd}|| d	 |td
r\t _|_|_	S )a'  Provides a mocking engine based on the current testing.db.

    This is normally used to test DDL generation flow as emitted
    by an Engine.

    It should not be used in other cases, as assert_compile() and
    assert_sql_execution() are much better choices with fewer
    moving parts.

    r   )create_mock_enginec                   s     |  d S r   )rw   )Zsqlar`   bufferr   r   executor  s    zmock_engine.<locals>.executorc                   s"   dd  D }|| kst |d S )Nc                 S  s   g | ]}t d dt|qS )z[\n\t]rE   )resubstr.0sr   r   r   
<listcomp>  s     z3mock_engine.<locals>.assert_sql.<locals>.<listcomp>)r+   )ZstmtsZrecvr   r   r   
assert_sql  s    zmock_engine.<locals>.assert_sqlc                     s    j  d fddjD S )N
c                 3  s   | ]}t |j d V  qdS ))ri   N)r   compiler   rj   r   r   	<genexpr>  s     z1mock_engine.<locals>.print_sql.<locals>.<genexpr>)ri   joinmockr   )r,   r   r   	print_sql  s    zmock_engine.<locals>.print_sqlz://r   )
r   r   r   rO   rk   rJ   r+   r   r   r   )Zdialect_namer   r   r   r   r   )r   r,   r   mock_engine  s    r   c                   @  s:   e Zd ZdZdd ZdddZdd Zd	d
 Zdd ZdS )DBAPIProxyCursorzuProxy a DBAPI cursor.

    Tests can provide subclasses of this to intercept
    DBAPI-level cursor operations.

    c                 O  s   || _ || _|j||| _d S r   )r,   rH   ru   )r   r,   rQ   r_   rx   r   r   r   r      s    zDBAPIProxyCursor.__init__Nc                 K  s*   |r| j j||f|S | j j|f|S d S r   )ru   rv   )r   stmtZ
parametersr`   r   r   r   rv     s    zDBAPIProxyCursor.executec                 K  s   | j j||f|S r   )ru   executemany)r   r   paramsr`   r   r   r   r     s    zDBAPIProxyCursor.executemanyc                 C  s
   t | jS r   )iterru   r   r   r   r   __iter__  s    zDBAPIProxyCursor.__iter__c                 C  s   t | j|S r   )rg   ru   rr   r   r   r   rt     s    zDBAPIProxyCursor.__getattr__)N)	rZ   r[   r\   __doc__r    rv   r   r   rt   r   r   r   r   r     s   
r   c                   @  s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )DBAPIProxyConnectionz}Proxy a DBAPI connection.

    Tests can provide subclasses of this to intercept
    DBAPI-level connection operations.

    c                 C  s   || _ || _|| _d S r   )rQ   r,   
cursor_cls)r   r,   rQ   r   r   r   r   r      s    zDBAPIProxyConnection.__init__c                 O  s   | j | j| jf||S r   )r   r,   rQ   )r   r_   rx   r   r   r   ru     s    zDBAPIProxyConnection.cursorc                 C  s   | j   d S r   )rQ   r!   r   r   r   r   r!     s    zDBAPIProxyConnection.closec                 C  s   t | j|S r   )rg   rQ   rr   r   r   r   rt     s    z DBAPIProxyConnection.__getattr__N)rZ   r[   r\   r   r    ru   r!   rt   r   r   r   r   r     s
   r   )N)NN)NNFF)NNTF)NNFFFF)N))Z
__future__r   r   r   typingr   r   r   r1   r   rE   r   utilr   r	   r   r   r   Zutil.typingr   ZTYPE_CHECKINGr,   r   Z
engine.urlr   Zext.asyncior   r   r]   ra   rb   rd   re   rm   rn   r   Zoverloadr   r   r   r   r   r   r   r   <module>
   sn    

	


+
        	      
S
&