Fixed #21775 -- Allowed customization of datafile for Oracle tablespace

This commit is contained in:
Josh Smeaton 2014-08-26 15:54:37 +10:00 committed by Tim Graham
parent 54fd84e432
commit 0eb5cde9da
3 changed files with 120 additions and 45 deletions

View File

@ -58,20 +58,7 @@ class DatabaseCreation(BaseDatabaseCreation):
super(DatabaseCreation, self).__init__(connection) super(DatabaseCreation, self).__init__(connection)
def _create_test_db(self, verbosity=1, autoclobber=False, keepdb=False): def _create_test_db(self, verbosity=1, autoclobber=False, keepdb=False):
TEST_NAME = self._test_database_name() parameters = self._get_test_db_params()
TEST_USER = self._test_database_user()
TEST_PASSWD = self._test_database_passwd()
TEST_TBLSPACE = self._test_database_tblspace()
TEST_TBLSPACE_TMP = self._test_database_tblspace_tmp()
parameters = {
'dbname': TEST_NAME,
'user': TEST_USER,
'password': TEST_PASSWD,
'tblspace': TEST_TBLSPACE,
'tblspace_temp': TEST_TBLSPACE_TMP,
}
cursor = self.connection.cursor() cursor = self.connection.cursor()
if self._test_database_create(): if self._test_database_create():
try: try:
@ -85,8 +72,7 @@ class DatabaseCreation(BaseDatabaseCreation):
if not autoclobber: if not autoclobber:
confirm = input( confirm = input(
"It appears the test database, %s, already exists. " "It appears the test database, %s, already exists. "
"Type 'yes' to delete it, or 'no' to cancel: " % TEST_NAME "Type 'yes' to delete it, or 'no' to cancel: " % parameters['user'])
)
if autoclobber or confirm == 'yes': if autoclobber or confirm == 'yes':
try: try:
if verbosity >= 1: if verbosity >= 1:
@ -110,8 +96,7 @@ class DatabaseCreation(BaseDatabaseCreation):
if not autoclobber: if not autoclobber:
confirm = input( confirm = input(
"It appears the test user, %s, already exists. Type " "It appears the test user, %s, already exists. Type "
"'yes' to delete it, or 'no' to cancel: " % TEST_USER "'yes' to delete it, or 'no' to cancel: " % parameters['user'])
)
if autoclobber or confirm == 'yes': if autoclobber or confirm == 'yes':
try: try:
if verbosity >= 1: if verbosity >= 1:
@ -137,8 +122,8 @@ class DatabaseCreation(BaseDatabaseCreation):
real_test_settings = real_settings['TEST'] real_test_settings = real_settings['TEST']
test_settings = self.connection.settings_dict['TEST'] test_settings = self.connection.settings_dict['TEST']
real_test_settings['USER'] = real_settings['USER'] = test_settings['USER'] = \ real_test_settings['USER'] = real_settings['USER'] = test_settings['USER'] = \
self.connection.settings_dict['USER'] = TEST_USER self.connection.settings_dict['USER'] = parameters['user']
real_settings['PASSWORD'] = self.connection.settings_dict['PASSWORD'] = TEST_PASSWD real_settings['PASSWORD'] = self.connection.settings_dict['PASSWORD'] = parameters['password']
return self.connection.settings_dict['NAME'] return self.connection.settings_dict['NAME']
@ -147,23 +132,9 @@ class DatabaseCreation(BaseDatabaseCreation):
Destroy a test database, prompting the user for confirmation if the Destroy a test database, prompting the user for confirmation if the
database already exists. Returns the name of the test database created. database already exists. Returns the name of the test database created.
""" """
TEST_NAME = self._test_database_name()
TEST_USER = self._test_database_user()
TEST_PASSWD = self._test_database_passwd()
TEST_TBLSPACE = self._test_database_tblspace()
TEST_TBLSPACE_TMP = self._test_database_tblspace_tmp()
self.connection.settings_dict['USER'] = self.connection.settings_dict['SAVED_USER'] self.connection.settings_dict['USER'] = self.connection.settings_dict['SAVED_USER']
self.connection.settings_dict['PASSWORD'] = self.connection.settings_dict['SAVED_PASSWORD'] self.connection.settings_dict['PASSWORD'] = self.connection.settings_dict['SAVED_PASSWORD']
parameters = self._get_test_db_params()
parameters = {
'dbname': TEST_NAME,
'user': TEST_USER,
'password': TEST_PASSWD,
'tblspace': TEST_TBLSPACE,
'tblspace_temp': TEST_TBLSPACE_TMP,
}
cursor = self.connection.cursor() cursor = self.connection.cursor()
time.sleep(1) # To avoid "database is being accessed by other users" errors. time.sleep(1) # To avoid "database is being accessed by other users" errors.
if self._test_user_create(): if self._test_user_create():
@ -178,15 +149,15 @@ class DatabaseCreation(BaseDatabaseCreation):
def _execute_test_db_creation(self, cursor, parameters, verbosity): def _execute_test_db_creation(self, cursor, parameters, verbosity):
if verbosity >= 2: if verbosity >= 2:
print("_create_test_db(): dbname = %s" % parameters['dbname']) print("_create_test_db(): dbname = %s" % parameters['user'])
statements = [ statements = [
"""CREATE TABLESPACE %(tblspace)s """CREATE TABLESPACE %(tblspace)s
DATAFILE '%(tblspace)s.dbf' SIZE 20M DATAFILE '%(datafile)s' SIZE 20M
REUSE AUTOEXTEND ON NEXT 10M MAXSIZE 200M REUSE AUTOEXTEND ON NEXT 10M MAXSIZE %(maxsize)s
""", """,
"""CREATE TEMPORARY TABLESPACE %(tblspace_temp)s """CREATE TEMPORARY TABLESPACE %(tblspace_temp)s
TEMPFILE '%(tblspace_temp)s.dbf' SIZE 20M TEMPFILE '%(datafile_tmp)s' SIZE 20M
REUSE AUTOEXTEND ON NEXT 10M MAXSIZE 100M REUSE AUTOEXTEND ON NEXT 10M MAXSIZE %(maxsize_tmp)s
""", """,
] ]
self._execute_statements(cursor, statements, parameters, verbosity) self._execute_statements(cursor, statements, parameters, verbosity)
@ -207,7 +178,7 @@ class DatabaseCreation(BaseDatabaseCreation):
def _execute_test_db_destruction(self, cursor, parameters, verbosity): def _execute_test_db_destruction(self, cursor, parameters, verbosity):
if verbosity >= 2: if verbosity >= 2:
print("_execute_test_db_destruction(): dbname=%s" % parameters['dbname']) print("_execute_test_db_destruction(): dbname=%s" % parameters['user'])
statements = [ statements = [
'DROP TABLESPACE %(tblspace)s INCLUDING CONTENTS AND DATAFILES CASCADE CONSTRAINTS', 'DROP TABLESPACE %(tblspace)s INCLUDING CONTENTS AND DATAFILES CASCADE CONSTRAINTS',
'DROP TABLESPACE %(tblspace_temp)s INCLUDING CONTENTS AND DATAFILES CASCADE CONSTRAINTS', 'DROP TABLESPACE %(tblspace_temp)s INCLUDING CONTENTS AND DATAFILES CASCADE CONSTRAINTS',
@ -234,6 +205,19 @@ class DatabaseCreation(BaseDatabaseCreation):
sys.stderr.write("Failed (%s)\n" % (err)) sys.stderr.write("Failed (%s)\n" % (err))
raise raise
def _get_test_db_params(self):
return {
'dbname': self._test_database_name(),
'user': self._test_database_user(),
'password': self._test_database_passwd(),
'tblspace': self._test_database_tblspace(),
'tblspace_temp': self._test_database_tblspace_tmp(),
'datafile': self._test_database_tblspace_datafile(),
'datafile_tmp': self._test_database_tblspace_tmp_datafile(),
'maxsize': self._test_database_tblspace_size(),
'maxsize_tmp': self._test_database_tblspace_tmp_size(),
}
def _test_settings_get(self, key, default=None, prefixed=None): def _test_settings_get(self, key, default=None, prefixed=None):
""" """
Return a value from the test settings dict, Return a value from the test settings dict,
@ -262,12 +246,26 @@ class DatabaseCreation(BaseDatabaseCreation):
return self._test_settings_get('PASSWORD', default=PASSWORD) return self._test_settings_get('PASSWORD', default=PASSWORD)
def _test_database_tblspace(self): def _test_database_tblspace(self):
return self._test_settings_get('TBLSPACE', prefixed='NAME') return self._test_settings_get('TBLSPACE', prefixed='USER')
def _test_database_tblspace_tmp(self): def _test_database_tblspace_tmp(self):
settings_dict = self.connection.settings_dict settings_dict = self.connection.settings_dict
return settings_dict['TEST'].get('TBLSPACE_TMP', return settings_dict['TEST'].get('TBLSPACE_TMP',
TEST_DATABASE_PREFIX + settings_dict['NAME'] + '_temp') TEST_DATABASE_PREFIX + settings_dict['USER'] + '_temp')
def _test_database_tblspace_datafile(self):
tblspace = '%s.dbf' % self._test_database_tblspace()
return self._test_settings_get('DATAFILE', default=tblspace)
def _test_database_tblspace_tmp_datafile(self):
tblspace = '%s.dbf' % self._test_database_tblspace_tmp()
return self._test_settings_get('DATAFILE_TMP', default=tblspace)
def _test_database_tblspace_size(self):
return self._test_settings_get('DATAFILE_MAXSIZE', default='500M')
def _test_database_tblspace_tmp_size(self):
return self._test_settings_get('DATAFILE_TMP_MAXSIZE', default='500M')
def _get_test_db_name(self): def _get_test_db_name(self):
""" """

View File

@ -741,7 +741,11 @@ Default: ``None``
This is an Oracle-specific setting. This is an Oracle-specific setting.
The name of the tablespace that will be used when running tests. If not The name of the tablespace that will be used when running tests. If not
provided, Django will use ``'test_' + NAME``. provided, Django will use ``'test_' + USER``.
.. versionchanged:: 1.8
Previously Django used ``'test_' + NAME`` if not provided.
.. setting:: TEST_TBLSPACE_TMP .. setting:: TEST_TBLSPACE_TMP
@ -753,7 +757,73 @@ Default: ``None``
This is an Oracle-specific setting. This is an Oracle-specific setting.
The name of the temporary tablespace that will be used when running tests. If The name of the temporary tablespace that will be used when running tests. If
not provided, Django will use ``'test_' + NAME + '_temp'``. not provided, Django will use ``'test_' + USER + '_temp'``.
.. versionchanged:: 1.8
Previously Django used ``'test_' + NAME + '_temp'`` if not provided.
.. setting:: DATAFILE
DATAFILE
^^^^^^^^
.. versionadded:: 1.8
Default: ``None``
This is an Oracle-specific setting.
The name of the datafile to use for the TBLSPACE. If not provided, Django will
use ``TBLSPACE + '.dbf'``.
.. setting:: DATAFILE_TMP
DATAFILE_TMP
^^^^^^^^^^^^
.. versionadded:: 1.8
Default: ``None``
This is an Oracle-specific setting.
The name of the datafile to use for the TBLSPACE_TMP. If not provided, Django
will use ``TBLSPACE_TMP + '.dbf'``.
.. setting:: DATAFILE_MAXSIZE
DATAFILE_MAXSIZE
^^^^^^^^^^^^^^^^
.. versionadded:: 1.8
Default: ``'500M'``
.. versionchanged:: 1.8
The previous value was 200M and was not user customizable.
This is an Oracle-specific setting.
The maximum size that the DATAFILE is allowed to grow to.
.. setting:: DATAFILE_TMP_MAXSIZE
DATAFILE_TMP_MAXSIZE
^^^^^^^^^^^^^^^^^^^^
.. versionadded:: 1.8
Default: ``'500M'``
.. versionchanged:: 1.8
The previous value was 200M and was not user customizable.
This is an Oracle-specific setting.
The maximum size that the DATAFILE_TMP is allowed to grow to.
.. setting:: OLD_TEST_CHARSET .. setting:: OLD_TEST_CHARSET

View File

@ -341,6 +341,10 @@ Tests
* Added the :attr:`~django.test.Response.resolver_match` attribute to test * Added the :attr:`~django.test.Response.resolver_match` attribute to test
client responses. client responses.
* Added several settings that allow customization of test tablespace parameters
for Oracle: :setting:`DATAFILE`, :setting:`DATAFILE_TMP`,
:setting:`DATAFILE_MAXSIZE` and :setting:`DATAFILE_TMP_MAXSIZE`.
Validators Validators
^^^^^^^^^^ ^^^^^^^^^^
@ -569,6 +573,9 @@ Miscellaneous
* Seconds have been removed from any locales that had them in ``TIME_FORMAT``, * Seconds have been removed from any locales that had them in ``TIME_FORMAT``,
``DATETIME_FORMAT``, or ``SHORT_DATETIME_FORMAT``. ``DATETIME_FORMAT``, or ``SHORT_DATETIME_FORMAT``.
* The default maxsize of the Oracle test tablespace has increased from 200M
to 500M.
.. _deprecated-features-1.8: .. _deprecated-features-1.8:
Features deprecated in 1.8 Features deprecated in 1.8