3
(hw/                 @   sp   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
eZdS )    N)apps)settings)serializers)router)StringIO)inputZtest_c               @   s   e Zd ZdZdd Ze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 Zd)ddZd*ddZd d! Zd"d# Zd$d% ZdS )+BaseDatabaseCreationz
    This class encapsulates all backend-specific differences that pertain to
    creation and destruction of the test database.
    c             C   s
   || _ d S )N)
connection)selfr	    r   D/tmp/pip-install-q3hcpn_q/Django/django/db/backends/base/creation.py__init__   s    zBaseDatabaseCreation.__init__c             C   s   | j jS )zH
        Used to be defined here, now moved to DatabaseWrapper.
        )r	   _nodb_connection)r
   r   r   r   r      s    z%BaseDatabaseCreation._nodb_connection   FTc             C   s   ddl m} | j }|dkr@d}|r(d}td|| j||f  | j||| | jj  |tj	| jj
 d< || jjd< |dt|d dd	| jj
d
d |r| j | j_|d| jj
d | jj  |S )z
        Creates a test database, prompting the user for confirmation if the
        database already exists. Returns the name of the test database created.
        r   )call_commandr   ZCreatingzUsing existingz %s test database for alias %s...NAMEZmigrateFT)	verbosityinteractivedatabaseZ
run_syncdbZcreatecachetable)r   )Zdjango.core.managementr   _get_test_db_nameprint_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   s0    

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   ddl m} |j}g  x@tj D ]4}|jdk	r$|j|jkr$|jt	j
kr$ j|df q$W  fdd}t }tjd| d|d |j S )z
        Serializes all data in the database into a JSON string.
        Designed only for test runner usage; will not handle large
        amounts of data.
        r   )MigrationLoaderNc              3   sj   xdt j D ]V} | jjjrtjjj| r| jj	jjj
| jjj}x|j D ]
}|V  qTW qW d S )N)r   Zsort_dependenciesZ_metaZcan_migrater	   r   Zallow_migrate_modelr   Z_default_managerusingZorder_bypknameiterator)modelZquerysetobj)app_listr
   r   r   get_objectsq   s    z@BaseDatabaseCreation.serialize_db_to_string.<locals>.get_objectsjson)indentstream)Zdjango.db.migrations.loaderr&   r	   r   Zget_app_configsZmodels_modulelabelZmigrated_appsr)   r   ZTEST_NON_SERIALIZED_APPSappendr   r   r    getvalue)r
   r&   loaderZ
app_configr.   outr   )r-   r
   r   r   ^   s    

z+BaseDatabaseCreation.serialize_db_to_stringc             C   s2   t |}x$tjd|| jjdD ]}|j  qW dS )zv
        Reloads the database with data from a string generated by
        the serialize_db_to_string method.
        r/   )r'   N)r   r   Zdeserializer	   r   save)r
   datar,   r   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 - returns 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.
        ZTESTr   )r	   r   TEST_DATABASE_PREFIX)r
   r   r   r   r      s    z&BaseDatabaseCreation._get_test_db_namec       
   #   C   sJ  | j  }| j }| jjj}| jj }y|jd|||f  W n tk
r: } z|r^|S t	j
jd|  |s~td| }	|s|	dkryJ|dkrtd| j||f  |jd||  |jd|||f  W n> tk
r } z t	j
jd|  t	jd	 W Y d
d
}~X nX ntd t	jd W Y d
d
}~X nX W d
Q R X |S )zG
        Internal implementation - creates the test db tables.
        zCREATE DATABASE %s %sz,Got an error creating the test database: %s
zXType '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 %sz.Got an error recreating the test database: %s
r:   NzTests cancelled.)sql_table_creation_suffixr   r	   ops
quote_namer   cursorexecute	Exceptionsysstderrwriter   r   r   exit)
r
   r   r   r!   suffixr"   qnrA   eZconfirmr   r   r   r      sB    


&z$BaseDatabaseCreation._create_test_dbc             C   sJ   | j jd }|dkr8d}|r d}td|| j||f  | j||| 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
   numberr   r   r!   Zsource_database_namer#   r   r   r   clone_test_db   s    z"BaseDatabaseCreation.clone_test_dbc             C   s(   | j j}|j }dj|d ||d< |S )zX
        Return a modified connection settings dict for the n-th clone of a DB.
        z{}_{}r   )r	   r   copyformat)r
   rL   Zorig_settings_dictZnew_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
   rL   r   r!   r   r   r   rK      s    z#BaseDatabaseCreation._clone_test_dbNc             C   s   | j j  |dkr | j jd }n| j|d }|dkrZd}|rBd}td|| j||f  |sj| j|| |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
Preservingz %s test database for alias %s...)
r	   r   r   rP   r   r   _destroy_test_dbr   r   r   )r
   Zold_database_namer   r!   rL   r"   r#   r   r   r   destroy_test_db   s     
z$BaseDatabaseCreation.destroy_test_dbc             C   s>   | j jj (}tjd |jd| j jj|  W dQ R X dS )zF
        Internal implementation - remove the test db tables.
        r   zDROP DATABASE %sN)r	   r   rA   timesleeprB   r?   r@   )r
   r"   r   rA   r   r   r   rR     s    
z%BaseDatabaseCreation._destroy_test_dbc             C   s   dS )zQ
        SQL to append to the end of the test table creation statements.
        r;   r   )r
   r   r   r   r>     s    z.BaseDatabaseCreation.sql_table_creation_suffixc             C   s$   | j j}|d |d |d | j fS )z
        Returns 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)r   FF)F)Nr   FN)__name__
__module____qualname____doc__r   propertyr   r$   r%   r   r9   r   r   r   rM   rP   rK   rS   rR   r>   rV   r   r   r   r   r      s"   
8		
0


r   )rD   rT   Zdjango.appsr   Zdjango.confr   Zdjango.corer   Z	django.dbr   Zdjango.utils.sixr   Zdjango.utils.six.movesr   r<   objectr   r   r   r   r   <module>   s   