o
    Rc!6                     @   s0  d dl mZ d dl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mZ dd	lmZ dd
lmZ G dd deZe Ze	dd Ze	dd Ze	dd Ze	dd Zd&ddZG dd deZd'ddZ						d(ddZd&ddZG d d! d!eZG d"d# d#eZeefd$d%ZdS ))    )absolute_importN   )config)	decorator)
gc_collect   )event)pool)
await_onlyc                   @   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   <D:\Flask\env\Lib\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 )NcheckoutZcheckincloseZclose_detached)r   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   %   s   zConnectionKiller._add_connc                 G   s   | j | d S r   )r   discard)r   
dbapi_connargr   r   r   r   )   s   zConnectionKiller._remove_connc                 C   s,   |  |j |dv sJ | j| | d S )N)classglobalfunctionZfixture)r   r	   r   r    )r   enginescoper   r   r   
add_engine,   s   zConnectionKiller.add_enginec              
   C   B   z|  W d S  t y  } ztd|  W Y d }~d S d }~ww )Nz5testing_reaper couldn't rollback/close connection: %s	Exceptionwarningswarnr   fner   r   r   _safe2   s   zConnectionKiller._safec                 C   s.   t | jD ]}|d ur|jr| |j qd S r   )listr   is_validr2   rollbackr   recr   r   r   rollback_all:   s
   zConnectionKiller.rollback_allc                 C   s^   t | jD ]}|d ur|jr| j|j | |j q| jD ]}| |j q| j	  d S r   )
r3   r   r4   r   r!   dbapi_connectionr2   _checkinr5   clear)r   r7   conr   r   r   checkin_all?   s   
zConnectionKiller.checkin_allc                 C   s   |    d S r   )r=   r   r   r   r   	close_allN      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 rA   prepare_for_drop_tablesr'   url)r   
connectionrA   r   r   r   rD   Q   s   z(ConnectionKiller.prepare_for_drop_tablesc                 C   s   | j | }t|D ]2}t| jD ]}|d ur*|jr*|jd ur*|j|ju r*| |j qt|dr7t	|
  q	|
  q	|  d S )Nsync_engine)r   r3   r   r4   _poolr	   r2   r:   hasattrr
   disposer;   )r   r(   Zengr7   Z	proxy_refr   r   r   _drop_testing_enginesZ   s   



z&ConnectionKiller._drop_testing_enginesc                 C      |  d d S )Nr&   )rK   r   r   r   r   
after_testj      zConnectionKiller.after_testc                 C   sj   t jsd S |jjrd S |   ddlm} t j }|	|j
j| W d    d S 1 s.w   Y  d S r@   )r   rB   	__class__Z"__leave_connections_for_teardown__r=   rC   rA   dbconnectrD   r'   rE   )r   testrA   connr   r   r   after_test_outside_fixturesm   s   "z,ConnectionKiller.after_test_outside_fixturesc                 C   s    |    | d | d d S )Nr&   r$   )r=   rK   r   r   r   r   stop_test_class_inside_fixtures   s   
z0ConnectionKiller.stop_test_class_inside_fixturesc                 C   sD   t jjrt  t jjr tt jj}t jj  	J d| d S d S )NFz/%d connection recs not cleared after test suite)r	   baseZ_strong_ref_connection_recordsr   lenr;   )r   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   rK   )r   r(   r   r   r   final_cleanup   s   
zConnectionKiller.final_cleanupc                 C   s   | j D ]}|jr
J qd S r   )r   r4   r6   r   r   r   assert_all_closed   s
   
z"ConnectionKiller.assert_all_closedN)__name__
__module____qualname__r   r   r   r   r)   r2   r8   r=   r>   rD   rK   rM   rT   rU   rY   rZ   r[   r   r   r   r   r      s$    	r   c                 O   s(   z| |i | W t   d S t   w r   )testing_reaperr[   r0   argskwr   r   r   assert_conns_closed   s   rc   c                 O   (   z| |i | W t   dS t   w )zBDecorator that rolls back all open connections after fn execution.N)r_   r8   r`   r   r   r   rollback_open_connections   s   re   c                 O   s   t   | |i | dS )z:Decorator that closes all connections before fn execution.Nr_   r=   r`   r   r   r   close_first   s   rg   c                 O   rd   )z9Decorator that closes all connections after fn execution.Nrf   r`   r   r   r   close_open_connections   s   rh   c                 c   sZ    dd l m} |jD ] }| r|| v rq
t||d }|s%ttd| j|}| V  q
d S )Nr   zsqlalchemy.dialects.%s)Zsqlalchemy.dialectsZdialects__all__getattr
__import__dialect)excludednamemodr   r   r   all_dialects   s   
rq   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 NF)dbapiconnections
is_stopped)r   rt   r   r   r   r      s   
zReconnectFixture.__init__c                 C      t | j|S r   )rj   rt   r   keyr   r   r   __getattr__   r?   zReconnectFixture.__getattr__c                 O   sN   | j j|i |}| jr| |j | }|d J d| j| |S )Nzselect 1Fz%simulated connect failure didn't work)	rt   rQ   rv   r2   r   cursorexecuteru   append)r   ra   kwargsrS   Zcursr   r   r   rQ      s   
zReconnectFixture.connectc              
   C   r*   )Nz.ReconnectFixture couldn't close connection: %sr+   r/   r   r   r   r2      s   zReconnectFixture._safeFc                 C   s,   || _ t| jD ]}| |j qg | _d S r   )rv   r3   ru   r2   r   )r   stopcr   r   r   shutdown   s   
zReconnectFixture.shutdownc                 C   s
   d| _ d S rs   )rv   r   r   r   r   restart      
zReconnectFixture.restartN)F)	r\   r]   r^   r   rz   rQ   r2   r   r   r   r   r   r   rr      s    
rr   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 rs   )rl   rt   r   rv   r   Z_disposer'   r   r   rJ     s   

z$reconnecting_engine.<locals>.dispose)r   rP   rE   rl   rt   rr   testing_enginerJ   r   Ztest_shutdownr   Ztest_restart)rE   optionsrt   rJ   r   r   r   reconnecting_engine   s   

r   Fc                 C   s  |r|rJ ddl m} n|stjr!tjjr!|dur!ddlm} nddlm} ddlm	} |s6d}d}	d}
n|
dd}|
d	d}	|
d
d}
| pMtjj} || } |du rjtjdu sc| jtjjjkrgtj}ni }ntjdur| jtjjjkrtj }|| || fi |}|
r|jdkrt|ddd }t|ddd }|rddlm} tjdurttjj|rd}|jtjj |	dkr|rd|j_nd|_t|jtjrd|j_d|j_|rt||	 |S )zBProduce an engine configured by --options with optional overrides.r   )create_async_engineF)create_engine)make_urlTr&   
use_reaperr(   sqlite_savepointNZsqliterQ   c                 S   s
   d | _ d S r   )Zisolation_level)r9   Zconnection_recordr   r   r   
do_connectA  s   
z"testing_engine.<locals>.do_connectbeginc                 S   rL   )NZBEGIN)Zexec_driver_sqlrS   r   r   r   do_beginE  s   z testing_engine.<locals>.do_begin)
StaticPoolr%   )Zsqlalchemy.ext.asyncior   r   rP   Z
_is_futureZsqlalchemy.futurer   
sqlalchemyZsqlalchemy.engine.urlr   poprE   Z
drivernameZdb_optscopyupdatero   r   Zlistens_forZsqlalchemy.poolr   
isinstancer	   Z_transfer_fromrG   Z_has_eventsZ	QueuePool_timeoutZ_max_overflowr_   r)   )rE   r   futureasyncioZtransfer_staticpoolZ_sqlite_savepointr   r   r   r(   r   Zdefault_optr'   r   r   r   r   r   r   r     sf   







r   c                    sr   ddl m} | stjj} g   fdd} fdd}fdd}|| d	 |td
r.J  _|_|_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   )r}   )sqlarb   bufferr   r   executort  rN   zmock_engine.<locals>.executorc                    s"   dd  D }|| ksJ |d S )Nc                 S   s   g | ]}t d dt|qS )z[\n\t]rC   )resubstr.0sr   r   r   
<listcomp>x  s    z3mock_engine.<locals>.assert_sql.<locals>.<listcomp>r   )Zstmtsrecvr   r   r   
assert_sqlw  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 ))rl   N)r   compiler   rn   r   r   	<genexpr>}  s    z1mock_engine.<locals>.print_sql.<locals>.<genexpr>)rl   joinmockr   )r'   r   r   	print_sql{  s   zmock_engine.<locals>.print_sqlz://r   )	r   r   r   rP   ro   rI   r   r   r   )Zdialect_namer   r   r   r   r   )r   r'   r   mock_enginea  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|i || _d S r   )r'   rF   r{   )r   r'   rS   ra   r~   r   r   r   r     s   zDBAPIProxyCursor.__init__Nc                 K   s.   |r| j j||fi |S | j j|fi |S r   )r{   r|   )r   stmt
parametersrb   r   r   r   r|     s   zDBAPIProxyCursor.executec                 K   s   | j j||fi |S r   )r{   executemany)r   r   paramsrb   r   r   r   r     s   zDBAPIProxyCursor.executemanyc                 C   s
   t | jS r   )iterr{   r   r   r   r   __iter__  r   zDBAPIProxyCursor.__iter__c                 C   rw   r   )rj   r{   rx   r   r   r   rz     r?   zDBAPIProxyCursor.__getattr__r   )	r\   r]   r^   __doc__r   r|   r   r   rz   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   |j  | _|| _|| _d S r   )r	   Z_creatorrS   r'   
cursor_cls)r   r'   r   r   r   r   r     s   
zDBAPIProxyConnection.__init__c                 O   s   | j | j| jg|R i |S r   )r   r'   rS   )r   ra   r~   r   r   r   r{     s   zDBAPIProxyConnection.cursorc                 C   s   | j   d S r   )rS   r   r   r   r   r   r     rN   zDBAPIProxyConnection.closec                 C   rw   r   )rj   rS   rx   r   r   r   rz     r?   z DBAPIProxyConnection.__getattr__N)r\   r]   r^   r   r   r{   r   rz   r   r   r   r   r     s    r   c                    s&    fdd}dd }t ||ddS )zIProduce an engine that provides proxy hooks for
    common methods.

    c                      s    t jS r   )r   rP   r   conn_clsr   r   r   	mock_conn  r?   z"proxying_engine.<locals>.mock_connc                    s    fdd}|S )Nc                    s
    | j S r   r   )r"   do_on_connectr   r   go  r   z8proxying_engine.<locals>._wrap_do_on_connect.<locals>.gor   )r   r   r   r   r   _wrap_do_on_connect  s   z,proxying_engine.<locals>._wrap_do_on_connect)Zcreatorr   )r   )r   )r   r   r   r   r   r   r   proxying_engine  s   r   r   )NN)NNNFFF)
__future__r   r   r   r-   r   rC   r   utilr   r   r   r	   r
   objectr   r_   rc   re   rg   rh   rq   rr   r   r   r   r   r   r   r   r   r   r   <module>   sJ    

	



,

P&