3
v^.                 @   sb   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ZG dd	 d	ZdS )
    N)StringIO)apps)settings)serializers)routerZtest_c               @   s   e Zd ZdZdd Ze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/usr/lib/python3.6/site-packages/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_connectionc             C   s   t jj|tj  d S )N)sysstderrwriteoslinesep)r	   msgr
   r
   r   log   s    zBaseDatabaseCreation.log   FTc             C   s   ddl m} | j }|dkrBd}|r(d}| j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
        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 existingz %s test database for alias %s...NAMEZmigrateFT)	verbosityinteractivedatabaseZ
run_syncdbZcreatecachetable)r   )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_contents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_mirrorY   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
        Serialize 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   s`   xZt j D ]L} | jjjrtjjj| r| jj	jjj
| jjj}|j E d H  qW d S )N)r   sort_dependencies_metacan_migrater   r   allow_migrate_modelr!   _default_managerusingorder_bypknameiterator)modelqueryset)app_listr	   r
   r   get_objectss   s
    z@BaseDatabaseCreation.serialize_db_to_string.<locals>.get_objectsjson)indentstream)Zdjango.db.migrations.loaderr-   r   r   get_app_configsmodels_modulelabelZmigrated_appsr6   r   TEST_NON_SERIALIZED_APPSappendr   r   r'   getvalue)r	   r-   loader
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 )zw
        Reload the database with data from a string generated by
        the serialize_db_to_string() method.
        r<   )r3   N)r   r   deserializer   r!   save)r	   data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   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.
        TESTr   )r   r"   TEST_DATABASE_PREFIX)r	   r
   r
   r   r      s    z&BaseDatabaseCreation._get_test_db_namec             C   s   |j 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   s<  | j  }| jjj|| j d}| jj }y| j||| W n tk
r, } z|r\|S | j	d|  |szt
d| }|s|dkry@|dkr| j	d| j||f  |jd|  | j||| W n< tk
r } z| j	d|  tjd	 W Y d
d
}~X nX n| j	d tjd W Y d
d
}~X nX W d
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: %srM   NzTests cancelled.)r   r   ops
quote_namesql_table_creation_suffixr   rS   rU   	Exceptionr   inputr   rR   r   exit)	r	   r   r&   r(   r)   Ztest_db_paramsrS   econfirmr
   r
   r   r      s6    
&z$BaseDatabaseCreation._create_test_dbc             C   sL   | j jd }|dkr:d}|r d}| j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	   rV   r   r&   r(   source_database_namer*   r
   r
   r   clone_test_db   s    z"BaseDatabaseCreation.clone_test_dbc             C   s    | j j}|ddj|d |iS )zX
        Return a modified connection settings dict for the n-th clone of a DB.
        r   z{}_{})r   r"   format)r	   rV   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	   rV   r   r(   r
   r
   r   r`      s    z#BaseDatabaseCreation._clone_test_dbNc             C   s   | j j  |dkr | j jd }n| j|d }|dkr\d}|rBd}| jd|| j||f  |sl| 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"   re   r   r   _destroy_test_dbr   r    r!   )r	   Zold_database_namer   r(   rV   r)   r*   r
   r
   r   destroy_test_db   s     
z$BaseDatabaseCreation.destroy_test_dbc             C   s4   | j jj }|jd| j jj|  W dQ R X dS )zF
        Internal implementation - remove the test db tables.
        zDROP DATABASE %sN)r   r   rS   rR   rX   rY   )r	   r)   r   rS   r
   r
   r   rg   
  s    z%BaseDatabaseCreation._destroy_test_dbc             C   s   dS )zQ
        SQL to append to the end of the test table creation statements.
        rN   r
   )r	   r
   r
   r   rZ     s    z.BaseDatabaseCreation.sql_table_creation_suffixc             C   s$   | j j}|d |d |d | j 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.
        HOSTPORT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   propertyr   r   r+   r,   r$   rL   r   r   rU   r   rb   re   r`   rh   rg   rZ   rl   r
   r
   r
   r   r      s&   
8		

)



r   )r   r   ior   django.appsr   django.confr   Zdjango.corer   	django.dbr   rQ   r   r
   r
   r
   r   <module>   s   