B
    þ¦†\Ï3  ã               @   sl  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 dd
lmZ e e¡ZdZG dd„ deƒZdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zejdd„ ƒZejdd„ ƒZejdd„ ƒZejdd„ ƒZejdd „ ƒZejd!d"„ ƒZ e !d#¡d$d%„ ƒZ"e  !d&¡d'd(„ ƒZ#e !d&¡d)d*„ ƒZ$e !d+¡d,d-„ ƒZ%e !d.¡d/d0„ ƒZ&e !d.¡d1d2„ ƒZ'e !d&¡d3d4„ ƒZ(e !d+¡d5d6„ ƒZ)e !d&¡d7d8„ ƒZ*e !d.¡d9d:„ ƒZ+e !d;¡d<d=„ ƒZ,e !d;¡d>d?„ ƒZ-d@dA„ Z.e !d;¡dBdC„ ƒZ/e !d;¡dDdE„ ƒZ0dFdG„ Z1dHdI„ Z2e  !d;¡dJdK„ ƒZ3e !d#¡dLdM„ ƒZ4e !d#¡dNdO„ ƒZ5dPdQ„ Z6dRdS„ Z7dS )Té    Né   )Úconfig)Úenginesé   )Úcreate_engine)Úexc)Útext)Úurl)Úcompatc               @   s0   e Zd Zdd„ Zedd„ ƒZdd„ Zdd„ Zd	S )
Úregisterc             C   s
   i | _ d S )N)Úfns)Úself© r   ú;lib/python3.7/site-packages/sqlalchemy/testing/provision.pyÚ__init__   s    zregister.__init__c             C   s   t ƒ  d¡|ƒS )NÚ*)r   Úfor_db)ÚclsÚfnr   r   r   Úinit   s    zregister.initc                s   ‡ ‡fdd„}|S )Nc                s   | ˆj ˆ < ˆS )N)r   )r   )Údbnamer   r   r   Údecorate   s    
z!register.for_db.<locals>.decorater   )r   r   r   r   )r   r   r   r      s    zregister.for_dbc             G   sp   t |tjƒrt |¡}nt |tjƒr*|}n|jj}| ¡ }|| j	krX| j	| |f|žŽ S | j	d |f|žŽ S d S )Nr   )
Ú
isinstancer
   Zstring_typesÚsa_urlÚmake_urlZURLÚdbr	   Úget_backend_namer   )r   ÚcfgÚargr	   Úbackendr   r   r   Ú__call__#   s    
zregister.__call__N)Ú__name__Ú
__module__Ú__qualname__r   Úclassmethodr   r   r    r   r   r   r   r      s   r   c             C   s4   x.t ƒ D ]$}t d| |jj¡ t||j| ƒ qW d S )NzCREATE database %s, URI %r)Ú_configs_for_db_operationÚlogÚinfor   r	   Ú
_create_db)Úfollower_identr   r   r   r   Úcreate_follower_db1   s    r*   c             C   s"   xt j ¡ D ]}t|| ƒ qW d S )N)r   ÚConfigÚall_configsÚ_configure_follower)r)   r   r   r   r   Úconfigure_follower7   s    r.   c             C   sd   |rt | |ƒ} i }t| |ƒ t | |¡}t| ||ƒ | ¡  ¡  tj 	||||¡}|r`t
||ƒ |S )N)Ú_follower_url_from_mainÚ_update_db_optsr   Ztesting_engineÚ_post_configure_engineÚconnectÚcloser   r+   r   r-   )Údb_urlÚoptionsZfile_configr)   Údb_optsÚengr   r   r   r   Úsetup_config<   s    


r8   c             C   s4   x.t ƒ D ]$}t d| |jj¡ t||j| ƒ qW d S )NzDROP database %s, URI %r)r%   r&   r'   r   r	   Ú_drop_db)r)   r   r   r   r   Údrop_follower_dbK   s    r:   c              c   s”   t ƒ } xtj ¡ D ]}|j ¡  qW xLtj ¡ D ]>}|jj}| ¡ }||j|j	|j
f}|| kr0|V  |  |¡ q0W xtj ¡ D ]}|j ¡  q~W d S )N)Úsetr   r+   r,   r   Zdisposer	   r   ÚusernameÚhostÚdatabaseÚadd)Zhostsr   r	   r   Z	host_confr   r   r   r%   Q   s    r%   c             C   s   t d|j ƒ‚d S )Nz"no DB creation routine for cfg: %s)ÚNotImplementedErrorr	   )r   r7   Úidentr   r   r   r(   d   s    r(   c             C   s   t d|j ƒ‚d S )Nzno DB drop routine for cfg: %s)r@   r	   )r   r7   rA   r   r   r   r9   i   s    r9   c             C   s   d S )Nr   )r4   r6   r   r   r   r0   n   s    r0   c             C   s   d S )Nr   )r   rA   r   r   r   r-   s   s    r-   c             C   s   d S )Nr   )r	   Úenginer)   r   r   r   r1   x   s    r1   c             C   s   t  | ¡} || _| S )N)r   r   r>   )r	   rA   r   r   r   r/   }   s    
r/   Úmssqlc             C   s   d|d< d S )NFZlegacy_schema_aliasingr   )r4   r6   r   r   r   Ú_mssql_update_db_opts„   s    rD   Zsqlitec             C   s0   t  | ¡} | jr| jdkr| S t  d| ¡S d S )Nz:memory:zsqlite:///%s.db)r   r   r>   )r	   rA   r   r   r   Ú_sqlite_follower_url_from_main‰   s    
rE   c                s(   ddl m} | |d¡‡ fdd„ƒ}d S )Nr   )Úeventr2   c                s"   ˆ s|   d¡ n|   dˆ  ¡ d S )Nz/ATTACH DATABASE "test_schema.db" AS test_schemaz2ATTACH DATABASE "%s_test_schema.db" AS test_schema)Úexecute)Zdbapi_connectionZconnection_record)r)   r   r   r2   –   s    z._sqlite_post_configure_engine.<locals>.connect)Z
sqlalchemyrF   Zlistens_for)r	   rB   r)   rF   r2   r   )r)   r   Ú_sqlite_post_configure_engine’   s    rH   Z
postgresqlc             C   sê   | j j}| ¡ jddÈ}yt| ||ƒ W n tk
r>   Y nX |sN| d¡}d}xˆy| d||f ¡ W nj tj	k
rÈ } z>|d7 }|dkr‚ dt
|ƒkr¸t d	||j|¡ t d
¡ W d d }~X Y qT   ‚ Y qTX P qTW W d Q R X d S )NÚ
AUTOCOMMIT)Úisolation_levelzselect current_database()r   zCREATE DATABASE %s TEMPLATE %sr   é   zaccessed by other userszFWaiting to create %s, URI %r, template DB %s is in use sleeping for .5g      à?)r5   Zpostgresql_templatedbr2   Úexecution_optionsÚ_pg_drop_dbÚ	ExceptionZscalarrG   r   ZOperationalErrorÚstrr&   r'   r	   ÚtimeZsleep)r   r7   rA   Ztemplate_dbÚconnZattemptÚerrr   r   r   Ú_pg_create_db¥   s6    
rS   Zmysqlc          	   C   sh   |  ¡ V}yt| ||ƒ W n tk
r.   Y nX | d| ¡ | d| ¡ | d| ¡ W d Q R X d S )Nz(CREATE DATABASE %s CHARACTER SET utf8mb4z4CREATE DATABASE %s_test_schema CHARACTER SET utf8mb4z6CREATE DATABASE %s_test_schema_2 CHARACTER SET utf8mb4)r2   Ú_mysql_drop_dbrN   rG   )r   r7   rA   rQ   r   r   r   Ú_mysql_create_dbÊ   s    

rU   c             C   s   d| | _ d| | _d S )Nz%s_test_schemaz%s_test_schema_2)Útest_schemaÚtest_schema_2)r   rA   r   r   r   Ú_mysql_configure_followerÛ   s    
rX   c             C   s   d S )Nr   )r   r7   rA   r   r   r   Ú_sqlite_create_dbá   s    rY   c          	   C   s@   |  ¡ jdd&}|jtdƒ|d | d| ¡ W d Q R X d S )NrI   )rJ   z€select pg_terminate_backend(pid) from pg_stat_activity where usename=current_user and pid != pg_backend_pid() and datname=:dname)ZdnamezDROP DATABASE %s)r2   rL   rG   r   )r   r7   rA   rQ   r   r   r   rM   æ   s    rM   c             C   s&   |rt  d| ¡ nt  d| ¡ d S )Nz%s_test_schema.dbz%s.db)ÚosÚremove)r   r7   rA   r   r   r   Ú_sqlite_drop_dbô   s    r\   c          	   C   sB   |  ¡ 0}| d| ¡ | d| ¡ | d| ¡ W d Q R X d S )NzDROP DATABASE %s_test_schemazDROP DATABASE %s_test_schema_2zDROP DATABASE %s)r2   rG   )r   r7   rA   rQ   r   r   r   rT   ü   s    
rT   Úoraclec          	   C   s|   |  ¡ j}| d| ¡ | d| ¡ | d| ¡ | d|f ¡ | d| ¡ | d| ¡ | d| ¡ W d Q R X d S )Nzcreate user %s identified by xez#create user %s_ts1 identified by xez#create user %s_ts2 identified by xezgrant dba to %sz grant unlimited tablespace to %sz$grant unlimited tablespace to %s_ts1z$grant unlimited tablespace to %s_ts2)r2   rG   )r   r7   rA   rQ   r   r   r   Ú_oracle_create_db  s    
r^   c             C   s   d| | _ d| | _d S )Nz%s_ts1z%s_ts2)rV   rW   )r   rA   r   r   r   Ú_oracle_configure_follower  s    
r_   c          
   C   sT   y|   d| ¡ t d|¡ dS  tjk
rN } zt d|¡ dS d }~X Y nX d S )Nzdrop user %s cascadezReaped db: %sTzcouldn't drop db: %sF)rG   r&   r'   r   ÚDatabaseErrorÚwarning)rQ   r   rR   r   r   r   Ú_ora_drop_ignore  s    rb   c          	   C   s>   |  ¡ ,}t||ƒ t|d| ƒ t|d| ƒ W d Q R X d S )Nz%s_ts1z%s_ts2)r2   rb   )r   r7   rA   rQ   r   r   r   Ú_oracle_drop_db#  s    

rc   c             C   s   d S )Nr   )r4   r6   r   r   r   Ú_oracle_update_db_opts0  s    rd   c          	   C   sâ   t  d¡ t t¡}t t¡}t| ƒ^}xV|D ]N}| ¡ }| d¡\}}t 	|¡}| 
¡ |jf}||  |¡ ||  |¡ q.W W d Q R X xR|D ]J}|d }	t|| ƒd }
|| }|	dkrÈt|
|ƒ q|	dkrt|
|ƒ qW d S )NzReaping databases...ú r   r]   rC   )r&   r'   ÚcollectionsÚdefaultdictr;   ÚopenÚstripÚsplitr   r   r   r=   r?   ÚlistÚ_reap_oracle_dbsÚ_reap_mssql_dbs)Zidents_fileZurlsÚidentsZfile_ÚlineZdb_namer4   Zurl_objZurl_keyr   r	   rA   r   r   r   Úreap_dbs5  s&    






rp   c          	   C   s  t  d| ¡ t| ƒ}| ¡ â}t  dd |¡¡ | d¡}dd„ |D ƒ}tƒ }xj|D ]b}| d¡sT| d¡rpqTqT||krT| |¡ d	| |krœ| d	| ¡ d
| |krT| d
| ¡ qTW d }}	x(t	|dƒD ]\}	}
t
||
ƒrÎ|d7 }qÎW t  d||	¡ W d Q R X d S )Nzdb reaper connecting to %rzidentifiers in file: %sz, z‰select u.username from all_users u where username like 'TEST_%' and not exists (select username from v$session where username=u.username)c             S   s   h | ]\}|  ¡ ’qS r   )Úlower)Ú.0r<   r   r   r   ú	<setcomp>Z  s    z#_reap_oracle_dbs.<locals>.<setcomp>Z_ts1Z_ts2z%s_ts1z%s_ts2r   r   z-Dropped %d out of %d stale databases detected)r&   r'   r   r2   ÚjoinrG   r;   Úendswithr?   Ú	enumeraterb   )r	   rn   r7   rQ   Úto_reapÚ	all_namesÚto_dropÚnameÚdroppedÚtotalr<   r   r   r   rl   N  s.    



rl   c             C   s   t  | ¡} || _d| _| S )NZxe)r   r   r<   Zpassword)r	   rA   r   r   r   Ú_oracle_follower_url_from_maino  s    
r}   c          	   C   sl   |  ¡ jddR}| d| ¡ | d| ¡ | d| ¡ | d| ¡ | d¡ | d¡ W d Q R X d S )	NrI   )rJ   zcreate database %sz1ALTER DATABASE %s SET ALLOW_SNAPSHOT_ISOLATION ONz0ALTER DATABASE %s SET READ_COMMITTED_SNAPSHOT ONzuse %szcreate schema test_schemazcreate schema test_schema_2)r2   rL   rG   )r   r7   rA   rQ   r   r   r   Ú_mssql_create_dbw  s    


r~   c          	   C   s*   |  ¡ jdd}t||ƒ W d Q R X d S )NrI   )rJ   )r2   rL   Ú_mssql_drop_ignore)r   r7   rA   rQ   r   r   r   Ú_mssql_drop_db†  s    r€   c          
   C   sT   y|   d| ¡ t d|¡ dS  tjk
rN } zt d|¡ dS d }~X Y nX d S )Nzdrop database %szReaped db: %sTzcouldn't drop db: %sF)rG   r&   r'   r   r`   ra   )rQ   rA   rR   r   r   r   r   Œ  s    	r   c          	   C   sÄ   t  d| ¡ t| ƒ}| ¡ jdd–}t  dd |¡¡ | d¡}dd„ |D ƒ}tƒ }x|D ]}||kr\| |¡ q\W d	 }}	x(t	|d
ƒD ]\}	}
t
||
ƒrŠ|d
7 }qŠW t  d||	¡ W d Q R X d S )Nzdb reaper connecting to %rrI   )rJ   zidentifiers in file: %sz, z›select d.name from sys.databases as d where name like 'TEST_%' and not exists (select session_id from sys.dm_exec_sessions where database_id=d.database_id)c             S   s   h | ]\}|  ¡ ’qS r   )rq   )rr   r   r   r   r   rs   «  s    z"_reap_mssql_dbs.<locals>.<setcomp>r   r   z-Dropped %d out of %d stale databases detected)r&   r'   r   r2   rL   rt   rG   r;   r?   rv   r   )r	   rn   r7   rQ   rw   rx   ry   rz   r{   r|   r   r   r   r   rm   ž  s"    

rm   )8rf   ZloggingrZ   rP   Ú r   r   r   r   r   rB   r	   r   Úutilr
   Z	getLoggerr!   r&   ZFOLLOWER_IDENTÚobjectr   r*   r.   r8   r:   r%   r   r(   r9   r0   r-   r1   r/   r   rD   rE   rH   rS   rU   rX   rY   rM   r\   rT   r^   r_   rb   rc   rd   rp   rl   r}   r~   r€   r   rm   r   r   r   r   Ú<module>   s\   
	%
!