o aL@s\ddlZddlmZddlmZddlmZddlmZddl m Z dZ Gdd d eZ dS) N)settings) DatabaseError)BaseDatabaseCreation)get_random_string)cached_propertytest_c@seZdZeddZdDddZddZd d Zd d ZdEd dZ dFddZ dFddZ ddZ ddZ dFddZddZddZdGddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zd0d1Zd2d3Zd4d5Zd6d7Zd8d9Zd:d;Zdd?Z!d@dAZ"dBdCZ#dS)HDatabaseCreationcCs^tj|jj}|dp|d}|dp|d}i|||d}t|j}|||jjdS)a> This is analogous to other backends' `_nodb_connection` property, which allows access to an "administrative" connection which can be used to manage the test databases. For Oracle, the only connection that can be used for that purpose is the main (non-test) connection. SAVED_USERUSERSAVED_PASSWORDPASSWORD)r r )alias)r DATABASES connectionr gettype)self settings_dictuserpasswordDatabaseWrapperrD/usr/lib/python3/dist-packages/django/db/backends/oracle/creation.py_maindb_connections   z#DatabaseCreation._maindb_connectionFcCsF|}|j}|rz |||||Wnty}zdt|vr3|d|t d|s=t d|d}|sC|dkr|dkrP|d|j j z | |||WnJty}z!d t|vrp|||||n |d |t dWYd}~n"d}~wty}z|d |t dWYd}~nd}~wwz |||||Wn(ty}z|d |t dWYd}~nd}~ww|d t dWYd}~nd}~ww|r|dkr|d z |||||Wnty}z{dt|vr|d|t d|s!t d|d}|s)|dkrnz%|dkr4|d|||||dkrE|d |||||Wn)tym}z|d|t dWYd}~nd}~ww|d t dWYd}~nd}~wwWdn 1swY|j|||j jdS)N ORA-01543z+Got an error creating the test database: %sz^It appears the test database, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: ryesr.Destroying old test database for alias '%s'...z ORA-29857z1Got an error destroying the old test database: %sz-Got an error recreating the test database: %szTests cancelled.zCreating test user... ORA-01920z'Got an error creating the test user: %szZIt appears the test user, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: Destroying old test user...z)Got an error recreating the test user: %sNAME)_get_test_db_paramsrcursor_test_database_create_execute_test_db_creation Exceptionstrlogsysexitinputrr _execute_test_db_destructionr)_handle_objects_preventing_db_destruction_test_user_create_create_test_user_destroy_test_userclose_switch_to_test_userr)r verbosity autoclobberkeepdb parametersr#econfirmrrr_create_test_dbs        "         B  z DatabaseCreation._create_test_dbcCstj|jj}|jjd|d<|jjd<|jjd|d<|jjd<|d}|jjd}|d|d<|d<|d<|jjd<|d|d<|jjd<dS) a Switch to the user that's used for creating the test database. Oracle doesn't have the concept of separate databases under the same user, so a separate user is used; see _create_test_db(). The main user is also needed for cleanup when testing is completed, so save its credentials in the SAVED_USER/SAVED_PASSWORD key in the settings dict. r r r r TESTrrN)rrrr r)rr6 real_settingsreal_test_settings test_settingsrrrr2fs    z%DatabaseCreation._switch_to_test_usercCs$|d|jjd<|d|jjd<dS)z Set this database up to be used in testing as a mirror of a primary database whose settings are given. r r Nrr)rprimary_settings_dictrrrset_as_test_mirrorzsz#DatabaseCreation.set_as_test_mirrorc CsD|d|r|std|d}|s|dkrz|dkr#|d||||WntyI}z|d|tdWYd}~nd}~wwz|dkrX|d |jj| |||WdSty}z|d |tdWYd}~dSd}~ww|d tddS|d |d|d tddS) Na There are objects in the old test database which prevent its destruction. If they belong to the test user, deleting the user will allow the test database to be recreated. Otherwise, you will need to find and remove each of these objects, or use a different tablespace. zType 'yes' to delete user %s: rrrr z)Got an error destroying the test user: %srrz-Got an error destroying the test database: %sz5Tests cancelled -- test database cannot be recreated.z[Django is configured to use pre-existing test user '%s', and will not attempt to delete it.) r(r.r+r0r&r)r*rr r,)rr#r6r3r4r8r7rrrr-s@    z:DatabaseCreation._handle_objects_preventing_db_destructioncCs|jjd|jjd<|jjd|jjd<|j|}|j0}|r7|dkr0|d||||| rK|dkrD|d| |||Wdn1sUwY|jdS) z Destroy a test database, prompting the user for confirmation if the database already exists. Return the name of the test database created. r r r r rzDestroying test user...z"Destroying test database tables...N) rrr1r"rr#r.r(r0r$r,)rtest_database_namer3r6r#rrr_destroy_test_dbs      z!DatabaseCreation._destroy_test_dbcCsV|dkr |d|d|rddg}nddg}|rdnd}||||||dS) Nrz_create_test_db(): dbname = %srz CREATE TABLESPACE %(tblspace)s DATAFILE SIZE %(size)s AUTOEXTEND ON NEXT %(extsize)s MAXSIZE %(maxsize)s z CREATE TEMPORARY TABLESPACE %(tblspace_temp)s TEMPFILE SIZE %(size_tmp)s AUTOEXTEND ON NEXT %(extsize_tmp)s MAXSIZE %(maxsize_tmp)s z CREATE TABLESPACE %(tblspace)s DATAFILE '%(datafile)s' SIZE %(size)s REUSE AUTOEXTEND ON NEXT %(extsize)s MAXSIZE %(maxsize)s z CREATE TEMPORARY TABLESPACE %(tblspace_temp)s TEMPFILE '%(datafile_tmp)s' SIZE %(size_tmp)s REUSE AUTOEXTEND ON NEXT %(extsize_tmp)s MAXSIZE %(maxsize_tmp)s r)r(#_test_database_oracle_managed_files_execute_allow_fail_statements)rr#r6r3r5 statementsacceptable_ora_errrrrr%s z*DatabaseCreation._execute_test_db_creationc Cs|dkr |d|dddg}|rdnd}||||||}|s4|ddur4d}|||g||d D]} d } | |d <||| g||d }|sU|dkrU|d | q6dS)Nrz"_create_test_user(): username = %srzCREATE USER %(user)s IDENTIFIED BY "%(password)s" DEFAULT TABLESPACE %(tblspace)s TEMPORARY TABLESPACE %(tblspace_temp)s QUOTA UNLIMITED ON %(tblspace)s zGRANT CREATE SESSION, CREATE TABLE, CREATE SEQUENCE, CREATE PROCEDURE, CREATE TRIGGER TO %(user)srr z0ALTER USER %(user)s IDENTIFIED BY "%(password)s")VIEWzMATERIALIZED VIEWz(GRANT CREATE %(object_type)s TO %(user)s object_typez ORA-01031zBFailed to grant CREATE %s permission to test user. This may be ok.)r(rD_test_settings_get_execute_statements) rr#r6r3r5rErFsuccess set_passwordrHextrarrrr/s$  z"DatabaseCreation._create_test_usercCs6|dkr |d|dddg}|||||dS)Nrz)_execute_test_db_destruction(): dbname=%srzQDROP TABLESPACE %(tblspace)s INCLUDING CONTENTS AND DATAFILES CASCADE CONSTRAINTSzVDROP TABLESPACE %(tblspace_temp)s INCLUDING CONTENTS AND DATAFILES CASCADE CONSTRAINTSr(rJrr#r6r3rErrrr,s z-DatabaseCreation._execute_test_db_destructioncCs>|dkr|d|d|ddg}|||||dS)Nrz_destroy_test_user(): user=%srz&Be patient. This can take some time...zDROP USER %(user)s CASCADErNrOrrrr0s  z#DatabaseCreation._destroy_test_userc Csh|D]/}||}|dkrt|z||Wqty1}z|r%|dkr,|d|d}~wwdS)Nrz Failed (%s))printexecuter&r() rr#rEr6r3allow_quiet_failtemplatestmterrrrrrJs z$DatabaseCreation._execute_statementsc Cspz|duo t|dk}|j|||||dWdSty7}zt|}|dus+||vr,WYd}~dSd}~ww)z Execute statements which are allowed to fail silently if the Oracle error code given by `acceptable_ora_err` is raised. Return True if the statements execute without an exception, or False otherwise. Nr)rRTF)lenrJrr') rr#rEr6r3rFrRrU descriptionrrrrDsz/DatabaseCreation._execute_allow_fail_statementscCsT|||||||||| | | | d S)N) dbnamerrtblspace tblspace_tempdatafile datafile_tmpmaxsize maxsize_tmpsizesize_tmpextsize extsize_tmp) _test_database_name_test_database_user_test_database_passwd_test_database_tblspace_test_database_tblspace_tmp _test_database_tblspace_datafile$_test_database_tblspace_tmp_datafile_test_database_tblspace_maxsize#_test_database_tblspace_tmp_maxsize_test_database_tblspace_size _test_database_tblspace_tmp_size_test_database_tblspace_extsize#_test_database_tblspace_tmp_extsizerrrrr",sz$DatabaseCreation._get_test_db_paramsNcCs4|jj}|d||}|dur|rt||}|S)z Return a value from the test settings dict, or a given default, or a prefixed entry from the main settings dict. r:NrrrTEST_DATABASE_PREFIX)rkeydefaultprefixedrvalrrrrI=s   z#DatabaseCreation._test_settings_getcC|jdddS)Nr!rurIrprrrrcHz$DatabaseCreation._test_database_namecC|jdddS)N CREATE_DBTrtryrprrrr$Krzz&DatabaseCreation._test_database_createcCr{)N CREATE_USERTr}ryrprrrr.Nrzz"DatabaseCreation._test_user_createcCrw)Nr rxryrprrrrdQrzz$DatabaseCreation._test_database_usercCs&|d}|dur|rtd}|S)Nr )rIr.r)rrrrrreTs z&DatabaseCreation._test_database_passwdcCr{)NTBLSPACEr rxryrprrrrf[rzz(DatabaseCreation._test_database_tblspacecCs$|jj}|ddt|ddS)Nr: TBLSPACE_TMPr _temprqrrrrrrg^s z,DatabaseCreation._test_database_tblspace_tmpcCd|}|jd|dS)N%s.dbfDATAFILEr})rfrIrrYrrrrhc z1DatabaseCreation._test_database_tblspace_datafilecCr)Nr DATAFILE_TMPr})rgrIrrrrrigrz5DatabaseCreation._test_database_tblspace_tmp_datafilecCr{)NDATAFILE_MAXSIZE500Mr}ryrprrrrjkrzz0DatabaseCreation._test_database_tblspace_maxsizecCr{)NDATAFILE_TMP_MAXSIZErr}ryrprrrrknrzz4DatabaseCreation._test_database_tblspace_tmp_maxsizecCr{)N DATAFILE_SIZE50Mr}ryrprrrrlqrzz-DatabaseCreation._test_database_tblspace_sizecCr{)NDATAFILE_TMP_SIZErr}ryrprrrrmtrzz1DatabaseCreation._test_database_tblspace_tmp_sizecCr{)NDATAFILE_EXTSIZE25Mr}ryrprrrrnwrzz0DatabaseCreation._test_database_tblspace_extsizecCr{)NDATAFILE_TMP_EXTSIZErr}ryrprrrrozrzz4DatabaseCreation._test_database_tblspace_tmp_extsizecCr{)NORACLE_MANAGED_FILESFr}ryrprrrrC}rzz4DatabaseCreation._test_database_oracle_managed_filescCs |jjdS)z Return the 'production' DB name to get the test DB creation machinery to work. This isn't a great deal in this case because DB names as handled by Django don't have real counterparts in Oracle. r!r>rprrr_get_test_db_names z"DatabaseCreation._get_test_db_namecCs*|jj}|d|d|d|d|fS)NHOSTPORTENGINEr!)rrrdrrrrtest_db_signaturesz"DatabaseCreation.test_db_signature)rFF)r)F)NN)$__name__ __module__ __qualname__rrr9r2r@r-rBr%r/r,r0rJrDr"rIrcr$r.rdrerfrgrhrirjrkrlrmrnrorCrrrrrrr sD  H %  !!     r) r) django.confr django.dbr django.db.backends.base.creationrdjango.utils.cryptordjango.utils.functionalrrrrrrrrs