U
    8ÄT_B1  ã                   @   sn   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ZG d	d
„ d
ƒZdS )é    N)ÚStringIO)Úapps)Úsettings)Úserializers)Úrouter)ÚatomicZtest_c                   @   s¬   e Zd ZdZd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„ Zd+dd„Zd,dd„Zd-dd„Zdd„ Zd.dd „Zd/d"d#„Zd$d%„ Zd&d'„ Zd(d)„ Zd!S )0ÚBaseDatabaseCreationzs
    Encapsulate backend-specific differences pertaining to creation and
    destruction of the test database.
    c                 C   s
   || _ d S ©N)Ú
connection)Úselfr
   © r   úD/tmp/pip-unpacked-wheel-dv63caxw/django/db/backends/base/creation.pyÚ__init__   s    zBaseDatabaseCreation.__init__c                 C   s
   | j  ¡ S r	   )r
   Ú_nodb_cursor©r   r   r   r   r      s    z!BaseDatabaseCreation._nodb_cursorc                 C   s   t j |tj ¡ d S r	   )ÚsysÚstderrÚwriteÚosÚlinesep)r   Úmsgr   r   r   Úlog   s    zBaseDatabaseCreation.logé   FTc                 C   sÖ   ddl m} |  ¡ }|dkrBd}|r(d}|  d||  ||¡f ¡ |  |||¡ | j ¡  |tj	| jj
 d< || jjd< | jjd d	 r¨|d
t|d dƒd| jj
dd� |r¸|  ¡ | j_|d| jj
d� | j ¡  |S )z£
        Create a test database, prompting the user for confirmation if the
        database already exists. Return the name of the test database created.
        r   )Úcall_commandr   ZCreatingzUsing existingú %s test database for alias %s...ÚNAMEÚTESTZMIGRATEZmigrateFT)Ú	verbosityÚinteractiveÚdatabaseZ
run_syncdbZcreatecachetable)r   )Zdjango.core.managementr   Ú_get_test_db_namer   Ú_get_database_display_strÚ_create_test_dbr
   Úcloser   Ú	DATABASESÚaliasÚsettings_dictÚmaxÚserialize_db_to_stringZ_test_serialized_contentsZensure_connection)r   r   ÚautoclobberÚ	serializeÚkeepdbr   Útest_database_nameÚactionr   r   r   Úcreate_test_db   s6    
þ

û
z#BaseDatabaseCreation.create_test_dbc                 C   s   |d | j jd< dS )z€
        Set this database up to be used in testing as a mirror of a primary
        database whose settings are given.
        r   N)r
   r&   )r   Zprimary_settings_dictr   r   r   Úset_as_test_mirrorW   s    z'BaseDatabaseCreation.set_as_test_mirrorc                    s.   ‡ fdd„}t ƒ }tjd|ƒ d|d� | ¡ S )z¤
        Serialize all data in the database into a JSON string.
        Designed only for test runner usage; will not handle large
        amounts of data.
        c                  3   s    ddl m}  | ˆ jƒ}t ¡ D ]|}|jd k	r|j|jkr|jt	j
kr| ¡ D ]L}|j ˆ j¡rLt ˆ jj|¡rL|j ˆ jj¡ |jjj¡}| ¡ E d H  qLqd S )Nr   )ÚMigrationLoader)Zdjango.db.migrations.loaderr0   r
   r   Zget_app_configsZmodels_moduleÚlabelZmigrated_appsÚnamer   ZTEST_NON_SERIALIZED_APPSZ
get_modelsÚ_metaZcan_migrater   Zallow_migrate_modelr%   Z_default_managerÚusingZorder_byÚpkÚiterator)r0   ÚloaderZ
app_configÚmodelZquerysetr   r   r   Úget_objectse   s(    
ÿ
þ
ýÿþÿþz@BaseDatabaseCreation.serialize_db_to_string.<locals>.get_objectsÚjsonN)ÚindentÚstream)r   r   r*   Úgetvalue)r   r9   Úoutr   r   r   r(   ^   s    z+BaseDatabaseCreation.serialize_db_to_stringc              
   C   s„   t |ƒ}tƒ }t| jjd��^ | j ¡ �: tjd|| jjd�D ]}| ¡  | 	|j
jjj¡ q>W 5 Q R X | jj|d� W 5 Q R X dS )zw
        Reload the database with data from a string generated by
        the serialize_db_to_string() method.
        )r4   r:   )Útable_namesN)r   Úsetr   r
   r%   Zconstraint_checks_disabledr   ZdeserializeÚsaveÚaddÚobjectÚ	__class__r3   Zdb_tableZcheck_constraints)r   Údatar?   Úobjr   r   r   Údeserialize_db_from_string|   s    z/BaseDatabaseCreation.deserialize_db_from_stringc                 C   s    d| j j|dkrd| ndf S )zR
        Return display string for a database for use in various actions.
        z'%s'%sé   z ('%s')Ú )r
   r%   )r   r   Zdatabase_namer   r   r   r!   �   s    þz.BaseDatabaseCreation._get_database_display_strc                 C   s0   | j jd d r | j jd d S t| j jd  S )zû
        Internal implementation - return the name of the test DB that will be
        created. Only useful when called from create_test_db() and
        _create_test_db() and when no external munging is done with the 'NAME'
        settings.
        r   r   )r
   r&   ÚTEST_DATABASE_PREFIXr   r   r   r   r    ˜   s    z&BaseDatabaseCreation._get_test_db_namec                 C   s   |  d| ¡ d S )Nz%CREATE DATABASE %(dbname)s %(suffix)s)Úexecute)r   ÚcursorÚ
parametersr+   r   r   r   Ú_execute_create_test_db£   s    z,BaseDatabaseCreation._execute_create_test_dbc           	      C   sP  |   ¡ }| jj |¡|  ¡ dœ}|  ¡ ��}z|  |||¡ W �n  tk
�r@ } zà|rp| W Y ¢ÒW  5 Q R £ S |  d| ¡ |sŽt	d| ƒ}|sœ|dk�rz@|dkr¾|  d|  
||¡f ¡ | d| ¡ |  |||¡ W n< tk
�r } z|  d| ¡ t d	¡ W 5 d
}~X Y nX n|  d¡ t d¡ W 5 d
}~X Y nX W 5 Q R X |S )zF
        Internal implementation - create the test db tables.
        )ZdbnameÚsuffixz+Got an error creating the test database: %szXType 'yes' if you would like to try deleting the test database '%s', or 'no' to cancel: Úyesr   z,Destroying old test database for alias %s...zDROP DATABASE %(dbname)sz-Got an error recreating the test database: %srH   NzTests cancelled.)r    r
   ÚopsÚ
quote_nameÚsql_table_creation_suffixr   rN   Ú	Exceptionr   Úinputr!   rK   r   Úexit)	r   r   r)   r+   r,   Ztest_db_paramsrL   ÚeZconfirmr   r   r   r"   ¦   s>    þÿÿ
ÿ
&z$BaseDatabaseCreation._create_test_dbc                 C   sL   | j jd }|dkr:d}|r d}|  d||  ||¡f ¡ |  |||¡ dS )z(
        Clone a test database.
        r   r   zCloning test databasezUsing existing clonez%s for alias %s...N)r
   r&   r   r!   Ú_clone_test_db)r   rO   r   r)   r+   Zsource_database_namer-   r   r   r   Úclone_test_dbÏ   s    
þz"BaseDatabaseCreation.clone_test_dbc                 C   s    | j j}|dd |d |¡i–S )zX
        Return a modified connection settings dict for the n-th clone of a DB.
        r   z{}_{})r
   r&   Úformat)r   rO   Zorig_settings_dictr   r   r   Úget_test_db_clone_settingsâ   s    z/BaseDatabaseCreation.get_test_db_clone_settingsc                 C   s   t dƒ‚dS )zI
        Internal implementation - duplicate the test db tables.
        znThe database backend doesn't support cloning databases. Disable the option to run tests in parallel processes.N)ÚNotImplementedError)r   rO   r   r+   r   r   r   rX   ì   s    ÿz#BaseDatabaseCreation._clone_test_dbNc                 C   s–   | j  ¡  |dkr | j jd }n|  |¡d }|dkr\d}|rBd}|  d||  ||¡f ¡ |sl|  ||¡ |dk	r’|tj| j j	 d< || j jd< dS )zv
        Destroy a test database, prompting the user for confirmation if the
        database already exists.
        Nr   r   Z
DestroyingZ
Preservingr   )
r
   r#   r&   r[   r   r!   Ú_destroy_test_dbr   r$   r%   )r   Zold_database_namer   r+   rO   r,   r-   r   r   r   Údestroy_test_dbô   s"    

þz$BaseDatabaseCreation.destroy_test_dbc              	   C   s0   |   ¡ �}| d| jj |¡ ¡ W 5 Q R X dS )zF
        Internal implementation - remove the test db tables.
        zDROP DATABASE %sN)r   rK   r
   rQ   rR   )r   r,   r   rL   r   r   r   r]     s    
ÿz%BaseDatabaseCreation._destroy_test_dbc                 C   s   dS )zQ
        SQL to append to the end of the test table creation statements.
        rI   r   r   r   r   r   rS     s    z.BaseDatabaseCreation.sql_table_creation_suffixc                 C   s$   | j j}|d |d |d |  ¡ fS )zÇ
        Return a tuple with elements of self.connection.settings_dict (a
        DATABASES setting value) that uniquely identify a database
        accordingly to the RDBMS particularities.
        ZHOSTZPORTZENGINE)r
   r&   r    )r   r&   r   r   r   Útest_db_signature$  s    üz&BaseDatabaseCreation.test_db_signature)r   FTF)F)F)r   FF)F)Nr   FN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r.   r/   r(   rG   r!   r    rN   r"   rY   r[   rX   r^   r]   rS   r_   r   r   r   r   r      s&   
9	

)



r   )r   r   Úior   Zdjango.appsr   Zdjango.confr   Zdjango.corer   Z	django.dbr   Zdjango.db.transactionr   rJ   r   r   r   r   r   Ú<module>   s   