Merge lp:~davidstrauss/drupal/195416-per-connection-prefixes into lp:~vcs-imports/drupal/old-cvs

Proposed by David Strauss
Status: Needs review
Proposed branch: lp:~davidstrauss/drupal/195416-per-connection-prefixes
Merge into: lp:~vcs-imports/drupal/old-cvs
Diff against target: 801 lines
11 files modified
.bzrignore (+3/-0)
includes/bootstrap.inc (+11/-0)
includes/common.inc (+2/-4)
includes/database/database.inc (+108/-25)
includes/database/mysql/database.inc (+2/-0)
includes/database/pgsql/database.inc (+2/-0)
includes/database/sqlite/database.inc (+2/-0)
install.php (+9/-13)
modules/simpletest/drupal_web_test_case.php (+86/-92)
modules/simpletest/simpletest.module (+4/-2)
sites/default/default.settings.php (+14/-11)
To merge this branch: bzr merge lp:~davidstrauss/drupal/195416-per-connection-prefixes
Reviewer Review Type Date Requested Status
VCS imports Pending
Review via email: mp+13264@code.launchpad.net
To post a comment you must log in.
11226. By David Strauss

Fix some duplicated code from the conflict resolution.

11227. By David Strauss

Almost working...

11228. By David Strauss

Where I am now

11229. By David Strauss

Remove junk output

11230. By chx <chx@veyron>

fixed database init

Unmerged revisions

11230. By chx <chx@veyron>

fixed database init

11229. By David Strauss

Remove junk output

11228. By David Strauss

Where I am now

11227. By David Strauss

Almost working...

11226. By David Strauss

Fix some duplicated code from the conflict resolution.

11225. By David Strauss

Current progress.

11224. By David Strauss

Ignore

11223. By David Strauss

Failed patch.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file '.bzrignore'
--- .bzrignore 1970-01-01 00:00:00 +0000
+++ .bzrignore 2009-10-13 23:58:10 +0000
@@ -0,0 +1,3 @@
1./sites/default/files
2./sites/default/private
3./sites/default/settings.php
04
=== modified file 'includes/bootstrap.inc'
--- includes/bootstrap.inc 2009-10-09 16:33:13 +0000
+++ includes/bootstrap.inc 2009-10-13 23:58:10 +0000
@@ -572,6 +572,17 @@
572}572}
573573
574/**574/**
575 * Retrieve (and optionally set) information about the current test being run.
576 */
577function drupal_test_info($value = FALSE) {
578 static $cache;
579 if ($value !== FALSE) {
580 $cache = $value;
581 }
582 return $cache;
583}
584
585/**
575 * Returns and optionally sets the filename for a system item (module,586 * Returns and optionally sets the filename for a system item (module,
576 * theme, etc.). The filename, whether provided, cached, or retrieved587 * theme, etc.). The filename, whether provided, cached, or retrieved
577 * from the database, is only returned if the file exists.588 * from the database, is only returned if the file exists.
578589
=== modified file 'includes/common.inc'
--- includes/common.inc 2009-10-13 21:16:42 +0000
+++ includes/common.inc 2009-10-13 23:58:11 +0000
@@ -782,8 +782,6 @@
782 * A string containing the response body that was received.782 * A string containing the response body that was received.
783 */783 */
784function drupal_http_request($url, array $options = array()) {784function drupal_http_request($url, array $options = array()) {
785 global $db_prefix;
786
787 $result = new stdClass();785 $result = new stdClass();
788786
789 // Parse the URL and make sure we can handle the schema.787 // Parse the URL and make sure we can handle the schema.
@@ -882,8 +880,8 @@
882 // user-agent is used to ensure that multiple testing sessions running at the880 // user-agent is used to ensure that multiple testing sessions running at the
883 // same time won't interfere with each other as they would if the database881 // same time won't interfere with each other as they would if the database
884 // prefix were stored statically in a file or database variable.882 // prefix were stored statically in a file or database variable.
885 if (is_string($db_prefix) && preg_match("/simpletest\d+/", $db_prefix, $matches)) {883 if ($test_info = drupal_test_info()) {
886 $options['headers']['User-Agent'] = drupal_generate_test_ua($matches[0]);884 $options['headers']['User-Agent'] = $test_info['test_run_id'];
887 }885 }
888886
889 $request = $options['method'] . ' ' . $path . " HTTP/1.0\r\n";887 $request = $options['method'] . ' ' . $path . " HTTP/1.0\r\n";
890888
=== modified file 'includes/database/database.inc'
--- includes/database/database.inc 2009-10-12 02:00:04 +0000
+++ includes/database/database.inc 2009-10-13 23:58:11 +0000
@@ -317,6 +317,22 @@
317 */317 */
318 protected $schema = NULL;318 protected $schema = NULL;
319319
320 /**
321 * The default prefix used by this database connection.
322 *
323 * Separated from the other prefixes for performance reasons.
324 *
325 * @var string
326 */
327 protected $defaultPrefix = '';
328
329 /**
330 * The non-default prefixes used by this database connection.
331 *
332 * @var array
333 */
334 protected $prefixes = array();
335
320 function __construct($dsn, $username, $password, $driver_options = array()) {336 function __construct($dsn, $username, $password, $driver_options = array()) {
321 // Because the other methods don't seem to work right.337 // Because the other methods don't seem to work right.
322 $driver_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;338 $driver_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
@@ -390,6 +406,24 @@
390 }406 }
391407
392 /**408 /**
409 * Preprocess the prefix used by this database connection.
410 *
411 * @param $prefix
412 * The prefix, in any of the multiple forms documented in default.settings.php.
413 */
414 protected function setPrefix($prefix) {
415 if (is_array($prefix)) {
416 $this->defaultPrefix = isset($prefix['default']) ? $prefix['default'] : '';
417 unset($prefix['default']);
418 $this->prefixes = $prefix;
419 }
420 else {
421 $this->defaultPrefix = $prefix;
422 $this->prefixes = array();
423 }
424 }
425
426 /**
393 * Append a database prefix to all tables in a query.427 * Append a database prefix to all tables in a query.
394 *428 *
395 * Queries sent to Drupal should wrap all table names in curly brackets. This429 * Queries sent to Drupal should wrap all table names in curly brackets. This
@@ -403,27 +437,12 @@
403 * The properly-prefixed string.437 * The properly-prefixed string.
404 */438 */
405 public function prefixTables($sql) {439 public function prefixTables($sql) {
406 global $db_prefix;440 // Replace specific table prefixes first.
407441 foreach ($this->prefixes as $key => $val) {
408 if (is_array($db_prefix)) {442 $sql = strtr($sql, array('{' . $key . '}' => $val . $key));
409 if (array_key_exists('default', $db_prefix)) {443 }
410 $tmp = $db_prefix;444 // Then replace remaining tables with the default prefix.
411 unset($tmp['default']);445 return strtr($sql, array('{' => $this->defaultPrefix , '}' => ''));
412 foreach ($tmp as $key => $val) {
413 $sql = strtr($sql, array('{' . $key . '}' => $val . $key));
414 }
415 return strtr($sql, array('{' => $db_prefix['default'] , '}' => ''));
416 }
417 else {
418 foreach ($db_prefix as $key => $val) {
419 $sql = strtr($sql, array('{' . $key . '}' => $val . $key));
420 }
421 return strtr($sql, array('{' => '' , '}' => ''));
422 }
423 }
424 else {
425 return strtr($sql, array('{' => $db_prefix , '}' => ''));
426 }
427 }446 }
428447
429 /**448 /**
@@ -1260,6 +1279,20 @@
1260 if (empty($value['driver'])) {1279 if (empty($value['driver'])) {
1261 $databaseInfo[$index][$target] = $databaseInfo[$index][$target][mt_rand(0, count($databaseInfo[$index][$target]) - 1)];1280 $databaseInfo[$index][$target] = $databaseInfo[$index][$target][mt_rand(0, count($databaseInfo[$index][$target]) - 1)];
1262 }1281 }
1282
1283 // Parse the prefix information.
1284 if (!isset($databaseInfo[$index][$target]['prefix'])) {
1285 // Default to an empty prefix.
1286 $databaseInfo[$index][$target]['prefix'] = array(
1287 'default' => '',
1288 );
1289 }
1290 else if (!is_array($databaseInfo[$index][$target]['prefix'])) {
1291 // Transform the flat form into an array form.
1292 $databaseInfo[$index][$target]['prefix'] = array(
1293 'default' => $databaseInfo[$index][$target]['prefix'],
1294 );
1295 }
1263 }1296 }
1264 }1297 }
12651298
@@ -1319,7 +1352,40 @@
1319 if (!empty(self::$databaseInfo[$key])) {1352 if (!empty(self::$databaseInfo[$key])) {
1320 return self::$databaseInfo[$key];1353 return self::$databaseInfo[$key];
1321 }1354 }
13221355 }
1356
1357 /**
1358 * Rename a connection and its corresponding connection information.
1359 *
1360 * @param $old_key
1361 * The old connection key.
1362 * @param $new_key
1363 * The new connection key.
1364 */
1365 final public static function renameConnection($old_key, $new_key) {
1366 if (empty(self::$databaseInfo)) {
1367 self::parseConnectionInfo();
1368 }
1369
1370 if (!empty(self::$databaseInfo[$old_key]) && empty(self::$databaseInfo[$new_key])) {
1371 self::$databaseInfo[$new_key] = self::$databaseInfo[$old_key];
1372 unset(self::$databaseInfo[$old_key]);
1373 if (isset(self::$connections[$old_key])) {
1374 self::$connections[$new_key] = self::$connections[$old_key];
1375 unset(self::$connections[$old_key]);
1376 }
1377 }
1378 }
1379
1380 /**
1381 * Remove a connection and its corresponding connection information.
1382 *
1383 * @param $key
1384 * The connection key.
1385 */
1386 final public static function removeConnection($key) {
1387 unset(self::$databaseInfo[$key]);
1388 unset(self::$connections[$key]);
1323 }1389 }
13241390
1325 /**1391 /**
@@ -1332,7 +1398,7 @@
1332 * The database target to open.1398 * The database target to open.
1333 */1399 */
1334 final protected static function openConnection($key, $target) {1400 final protected static function openConnection($key, $target) {
1335 global $db_prefix;1401 global $databases;
13361402
1337 if (empty(self::$databaseInfo)) {1403 if (empty(self::$databaseInfo)) {
1338 self::parseConnectionInfo();1404 self::parseConnectionInfo();
@@ -1359,12 +1425,29 @@
1359 if (!empty(self::$logs[$key])) {1425 if (!empty(self::$logs[$key])) {
1360 $new_connection->setLogger(self::$logs[$key]);1426 $new_connection->setLogger(self::$logs[$key]);
1361 }1427 }
1362
1363 // We need to pass around the simpletest database prefix in the request1428 // We need to pass around the simpletest database prefix in the request
1364 // and we put that in the user_agent header. The header HMAC was already1429 // and we put that in the user_agent header. The header HMAC was already
1365 // validated in bootstrap.inc.1430 // validated in bootstrap.inc.
1366 if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/^(simpletest\d+);/", $_SERVER['HTTP_USER_AGENT'], $matches)) {1431 if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/^(simpletest\d+);/", $_SERVER['HTTP_USER_AGENT'], $matches)) {
1367 $db_prefix .= $matches[1];1432 $test_prefix = $matches[1];
1433 drupal_test_info(array('test_run_id' => $test_prefix, 'in_child_site' => TRUE));
1434 foreach ($databases['default'] as $target => $value) {
1435 // Extract the current default database prefix.
1436 if (empty($value['prefix'])) {
1437 $current_prefix = '';
1438 }
1439 else if (is_array($value['prefix'])) {
1440 $current_prefix = $value['prefix']['default'];
1441 }
1442 else {
1443 $current_prefix = $value['prefix'];
1444 }
1445
1446 // Remove the current database prefix and replace it by our own.
1447 $databases['default'][$target]['prefix'] = array(
1448 'default' => $current_prefix . $test_prefix,
1449 );
1450 }
1368 }1451 }
1369 return $new_connection;1452 return $new_connection;
1370 }1453 }
13711454
=== modified file 'includes/database/mysql/database.inc'
--- includes/database/mysql/database.inc 2009-09-18 00:04:21 +0000
+++ includes/database/mysql/database.inc 2009-10-13 23:58:11 +0000
@@ -25,6 +25,8 @@
25 $connection_options['port'] = 3306;25 $connection_options['port'] = 3306;
26 }26 }
2727
28 $this->setPrefix(isset($connection_options['prefix']) ? $connection_options['prefix'] : '');
29
28 $dsn = 'mysql:host=' . $connection_options['host'] . ';port=' . $connection_options['port'] . ';dbname=' . $connection_options['database'];30 $dsn = 'mysql:host=' . $connection_options['host'] . ';port=' . $connection_options['port'] . ';dbname=' . $connection_options['database'];
29 parent::__construct($dsn, $connection_options['username'], $connection_options['password'], array(31 parent::__construct($dsn, $connection_options['username'], $connection_options['password'], array(
30 // So we don't have to mess around with cursors and unbuffered queries by default.32 // So we don't have to mess around with cursors and unbuffered queries by default.
3133
=== modified file 'includes/database/pgsql/database.inc'
--- includes/database/pgsql/database.inc 2009-09-18 00:04:21 +0000
+++ includes/database/pgsql/database.inc 2009-10-13 23:58:11 +0000
@@ -26,6 +26,8 @@
26 $connection_options['port'] = 5432;26 $connection_options['port'] = 5432;
27 }27 }
2828
29 $this->setPrefix(isset($connection_options['prefix']) ? $connection_options['prefix'] : '');
30
29 // PostgreSQL in trust mode doesn't require a password to be supplied.31 // PostgreSQL in trust mode doesn't require a password to be supplied.
30 if (empty($connection_options['password'])) {32 if (empty($connection_options['password'])) {
31 $connection_options['password'] = null;33 $connection_options['password'] = null;
3234
=== modified file 'includes/database/sqlite/database.inc'
--- includes/database/sqlite/database.inc 2009-09-18 00:04:21 +0000
+++ includes/database/sqlite/database.inc 2009-10-13 23:58:11 +0000
@@ -25,6 +25,8 @@
25 // This driver defaults to transaction support, except if explicitly passed FALSE.25 // This driver defaults to transaction support, except if explicitly passed FALSE.
26 $this->transactionSupport = !isset($connection_options['transactions']) || $connection_options['transactions'] !== FALSE;26 $this->transactionSupport = !isset($connection_options['transactions']) || $connection_options['transactions'] !== FALSE;
2727
28 $this->setPrefix(isset($connection_options['prefix']) ? $connection_options['prefix'] : '');
29
28 parent::__construct('sqlite:' . $connection_options['database'], '', '', array(30 parent::__construct('sqlite:' . $connection_options['database'], '', '', array(
29 // Force column names to lower case.31 // Force column names to lower case.
30 PDO::ATTR_CASE => PDO::CASE_LOWER,32 PDO::ATTR_CASE => PDO::CASE_LOWER,
3133
=== modified file 'install.php'
--- install.php 2009-10-13 14:15:08 +0000
+++ install.php 2009-10-13 23:58:10 +0000
@@ -788,7 +788,7 @@
788 * Verify existing settings.php788 * Verify existing settings.php
789 */789 */
790function install_verify_settings() {790function install_verify_settings() {
791 global $db_prefix, $databases;791 global $databases;
792792
793 // Verify existing settings (if any).793 // Verify existing settings (if any).
794 if (!empty($databases)) {794 if (!empty($databases)) {
@@ -814,7 +814,7 @@
814 * The form API definition for the database configuration form.814 * The form API definition for the database configuration form.
815 */815 */
816function install_settings_form($form, &$form_state, &$install_state) {816function install_settings_form($form, &$form_state, &$install_state) {
817 global $databases, $db_prefix;817 global $databases;
818 $profile = $install_state['parameters']['profile'];818 $profile = $install_state['parameters']['profile'];
819 $install_locale = $install_state['parameters']['locale'];819 $install_locale = $install_state['parameters']['locale'];
820820
@@ -909,13 +909,13 @@
909 );909 );
910910
911 // Table prefix911 // Table prefix
912 $db_prefix = ($profile == 'default') ? 'drupal_' : $profile . '_';912 $prefix = ($profile == 'default') ? 'drupal_' : $profile . '_';
913 $form['advanced_options']['db_prefix'] = array(913 $form['advanced_options']['prefix'] = array(
914 '#type' => 'textfield',914 '#type' => 'textfield',
915 '#title' => st('Table prefix'),915 '#title' => st('Table prefix'),
916 '#default_value' => '',916 '#default_value' => '',
917 '#size' => 45,917 '#size' => 45,
918 '#description' => st('If more than one application will be sharing this database, enter a table prefix such as %prefix for your @drupal site here.', array('@drupal' => drupal_install_profile_name(), '%prefix' => $db_prefix)),918 '#description' => st('If more than one application will be sharing this database, enter a table prefix such as %prefix for your @drupal site here.', array('@drupal' => drupal_install_profile_name(), '%prefix' => $prefix)),
919 );919 );
920920
921 $form['save'] = array(921 $form['save'] = array(
@@ -948,12 +948,12 @@
948 global $databases;948 global $databases;
949 $errors = array();949 $errors = array();
950 // Verify the table prefix950 // Verify the table prefix
951 if (!empty($database['db_prefix']) && is_string($database['db_prefix']) && !preg_match('/^[A-Za-z0-9_.]+$/', $database['db_prefix'])) {951 if (!empty($database['prefix']) && is_string($database['prefix']) && !preg_match('/^[A-Za-z0-9_.]+$/', $database['prefix'])) {
952 $errors['db_prefix'] = st('The database table prefix you have entered, %db_prefix, is invalid. The table prefix can only contain alphanumeric characters, periods, or underscores.', array('%db_prefix' => $database['db_prefix']));952 $errors['prefix'] = st('The database table prefix you have entered, %prefix, is invalid. The table prefix can only contain alphanumeric characters, periods, or underscores.', array('%prefix' => $database['prefix']));
953 }953 }
954954
955 if (!empty($database['port']) && !is_numeric($database['port'])) {955 if (!empty($database['port']) && !is_numeric($database['port'])) {
956 $errors['db_port'] = st('Database port must be a number.');956 $errors['port'] = st('Database port must be a number.');
957 }957 }
958958
959 // Check database type959 // Check database type
@@ -989,16 +989,12 @@
989function install_settings_form_submit($form, &$form_state) {989function install_settings_form_submit($form, &$form_state) {
990 global $install_state;990 global $install_state;
991991
992 $database = array_intersect_key($form_state['values']['_database'], array_flip(array('driver', 'database', 'username', 'password', 'host', 'port')));992 $database = array_intersect_key($form_state['values']['_database'], array_flip(array('driver', 'database', 'username', 'password', 'host', 'port', 'prefix')));
993 // Update global settings array and save993 // Update global settings array and save
994 $settings['databases'] = array(994 $settings['databases'] = array(
995 'value' => array('default' => array('default' => $database)),995 'value' => array('default' => array('default' => $database)),
996 'required' => TRUE,996 'required' => TRUE,
997 );997 );
998 $settings['db_prefix'] = array(
999 'value' => $form_state['values']['db_prefix'],
1000 'required' => TRUE,
1001 );
1002 drupal_rewrite_settings($settings);998 drupal_rewrite_settings($settings);
1003 // Indicate that the settings file has been verified, and check the database999 // Indicate that the settings file has been verified, and check the database
1004 // for the last completed task, now that we have a valid connection. This1000 // for the last completed task, now that we have a valid connection. This
10051001
=== modified file 'modules/simpletest/drupal_web_test_case.php'
--- modules/simpletest/drupal_web_test_case.php 2009-10-13 07:14:26 +0000
+++ modules/simpletest/drupal_web_test_case.php 2009-10-13 23:58:11 +0000
@@ -15,11 +15,11 @@
15 protected $testId;15 protected $testId;
1616
17 /**17 /**
18 * The original database prefix, before it was changed for testing purposes.18 * The database prefix of this test run.
19 *19 *
20 * @var string20 * @var string
21 */21 */
22 protected $originalPrefix = NULL;22 protected $databasePrefix = NULL;
2323
24 /**24 /**
25 * The original file directory, before it was changed for testing purposes.25 * The original file directory, before it was changed for testing purposes.
@@ -90,8 +90,6 @@
90 * is the caller function itself.90 * is the caller function itself.
91 */91 */
92 protected function assert($status, $message = '', $group = 'Other', array $caller = NULL) {92 protected function assert($status, $message = '', $group = 'Other', array $caller = NULL) {
93 global $db_prefix;
94
95 // Convert boolean status to string status.93 // Convert boolean status to string status.
96 if (is_bool($status)) {94 if (is_bool($status)) {
97 $status = $status ? 'pass' : 'fail';95 $status = $status ? 'pass' : 'fail';
@@ -105,10 +103,6 @@
105 $caller = $this->getAssertionCall();103 $caller = $this->getAssertionCall();
106 }104 }
107105
108 // Switch to non-testing database to store results in.
109 $current_db_prefix = $db_prefix;
110 $db_prefix = $this->originalPrefix;
111
112 // Creation assertion array that can be displayed while tests are running.106 // Creation assertion array that can be displayed while tests are running.
113 $this->assertions[] = $assertion = array(107 $this->assertions[] = $assertion = array(
114 'test_id' => $this->testId,108 'test_id' => $this->testId,
@@ -122,12 +116,11 @@
122 );116 );
123117
124 // Store assertion for display after the test has completed.118 // Store assertion for display after the test has completed.
125 db_insert('simpletest')119 Database::getConnection('default', 'simpletest_original_default')
120 ->insert('simpletest')
126 ->fields($assertion)121 ->fields($assertion)
127 ->execute();122 ->execute();
128123
129 // Return to testing prefix.
130 $db_prefix = $current_db_prefix;
131 // We do not use a ternary operator here to allow a breakpoint on124 // We do not use a ternary operator here to allow a breakpoint on
132 // test failure.125 // test failure.
133 if ($status == 'pass') {126 if ($status == 'pass') {
@@ -473,18 +466,18 @@
473 * is not restricted.466 * is not restricted.
474 *467 *
475 * @param $length468 * @param $length
476 * Length of random string to generate which will be appended to $db_prefix.469 * Length of random string to generate which will be appended to $test_info['test_run_id'].
477 * @return470 * @return
478 * Randomly generated string.471 * Randomly generated string.
479 */472 */
480 public static function randomString($length = 8) {473 public static function randomString($length = 8) {
481 global $db_prefix;
482
483 $str = '';474 $str = '';
484 for ($i = 0; $i < $length; $i++) {475 for ($i = 0; $i < $length; $i++) {
485 $str .= chr(mt_rand(32, 126));476 $str .= chr(mt_rand(32, 126));
486 }477 }
487 return str_replace('simpletest', 's', $db_prefix) . $str;478
479 $test_info = drupal_test_info();
480 return str_replace('simpletest', 's', $test_info['test_run_id']) . $str;
488 }481 }
489482
490 /**483 /**
@@ -496,20 +489,19 @@
496 * spaces and non-standard characters) this method is best.489 * spaces and non-standard characters) this method is best.
497 *490 *
498 * @param $length491 * @param $length
499 * Length of random string to generate which will be appended to $db_prefix.492 * Length of random string to generate which will be appended to $test_info['test_run_id'].
500 * @return493 * @return
501 * Randomly generated string.494 * Randomly generated string.
502 */495 */
503 public static function randomName($length = 8) {496 public static function randomName($length = 8) {
504 global $db_prefix;
505
506 $values = array_merge(range(65, 90), range(97, 122), range(48, 57));497 $values = array_merge(range(65, 90), range(97, 122), range(48, 57));
507 $max = count($values) - 1;498 $max = count($values) - 1;
508 $str = '';499 $str = '';
509 for ($i = 0; $i < $length; $i++) {500 for ($i = 0; $i < $length; $i++) {
510 $str .= chr($values[mt_rand(0, $max)]);501 $str .= chr($values[mt_rand(0, $max)]);
511 }502 }
512 return str_replace('simpletest', 's', $db_prefix) . $str;503 $test_info = drupal_test_info();
504 return str_replace('simpletest', 's', $test_info['test_run_id']) . $str;
513 }505 }
514506
515}507}
@@ -533,15 +525,14 @@
533 }525 }
534526
535 function setUp() {527 function setUp() {
536 global $db_prefix, $conf;528 global $conf;
537529
538 // Store necessary current values before switching to prefixed database.530 // Store necessary current values before switching to prefixed database.
539 $this->originalPrefix = $db_prefix;
540 $this->originalFileDirectory = file_directory_path();531 $this->originalFileDirectory = file_directory_path();
541532
542 // Generate temporary prefixed database to ensure that tests have a clean starting point.533 // Generate temporary prefixed database to ensure that tests have a clean starting point.
543 $db_prefix = Database::getConnection()->prefixTables('{simpletest' . mt_rand(1000, 1000000) . '}');534 $this->databasePrefix = Database::getConnection()->prefixTables('{simpletest' . mt_rand(1000, 1000000) . '}');
544 $conf['file_public_path'] = $this->originalFileDirectory . '/' . $db_prefix;535 $conf['file_public_path'] = $this->originalFileDirectory . '/' . $this->databasePrefix;
545536
546 // If locale is enabled then t() will try to access the database and537 // If locale is enabled then t() will try to access the database and
547 // subsequently will fail as the database is not accessible.538 // subsequently will fail as the database is not accessible.
@@ -554,11 +545,10 @@
554 }545 }
555546
556 function tearDown() {547 function tearDown() {
557 global $db_prefix, $conf;548 global $conf;
558 if (preg_match('/simpletest\d+/', $db_prefix)) {549
550 if (preg_match('/simpletest\d+/', $this->databasePrefix)) {
559 $conf['file_public_path'] = $this->originalFileDirectory;551 $conf['file_public_path'] = $this->originalFileDirectory;
560 // Return the database prefix to the original.
561 $db_prefix = $this->originalPrefix;
562 // Restore modules if necessary.552 // Restore modules if necessary.
563 if (isset($this->originalModuleList)) {553 if (isset($this->originalModuleList)) {
564 module_list(TRUE, FALSE, FALSE, $this->originalModuleList);554 module_list(TRUE, FALSE, FALSE, $this->originalModuleList);
@@ -1025,27 +1015,34 @@
1025 * List of modules to enable for the duration of the test.1015 * List of modules to enable for the duration of the test.
1026 */1016 */
1027 protected function setUp() {1017 protected function setUp() {
1028 global $db_prefix, $user, $language;1018 global $user, $language;
1019
1020 // Generate a temporary prefixed database to ensure that tests have a clean starting point.
1021 $this->databasePrefix = 'simpletest' . mt_rand(1000, 1000000);
1022
1023 // Clone the current connection and replace the current prefix.
1024 $connection_info = Database::getConnectionInfo('default');
1025 Database::renameConnection('default', 'simpletest_original_default');
1026 foreach ($connection_info as $target => $value) {
1027 $connection_info[$target]['prefix'] = array(
1028 'default' => $value['prefix']['default'] . $this->databasePrefix,
1029 );
1030 }
1031 Database::addConnectionInfo('default', 'default', $connection_info['default']);
10291032
1030 // Store necessary current values before switching to prefixed database.1033 // Store necessary current values before switching to prefixed database.
1031 $this->originalLanguage = $language;1034 $this->originalLanguage = $language;
1032 $this->originalLanguageDefault = variable_get('language_default');1035 $this->originalLanguageDefault = variable_get('language_default');
1033 $this->originalPrefix = $db_prefix;
1034 $this->originalFileDirectory = file_directory_path();1036 $this->originalFileDirectory = file_directory_path();
1035 $this->originalProfile = drupal_get_profile();1037 $this->originalProfile = drupal_get_profile();
1036 $clean_url_original = variable_get('clean_url', 0);1038 $clean_url_original = variable_get('clean_url', 0);
10371039
1038 // Generate temporary prefixed database to ensure that tests have a clean starting point.1040 // Set the simpletest id for use in other parts of Drupal.
1039 $db_prefix_new = Database::getConnection()->prefixTables('{simpletest' . mt_rand(1000, 1000000) . '}');1041 drupal_test_info(array('test_run_id' => $this->databasePrefix, 'in_child_site' => FALSE));
1040 db_update('simpletest_test_id')
1041 ->fields(array('last_prefix' => $db_prefix_new))
1042 ->condition('test_id', $this->testId)
1043 ->execute();
1044 $db_prefix = $db_prefix_new;
10451042
1046 // Create test directory ahead of installation so fatal errors and debug1043 // Create test directory ahead of installation so fatal errors and debug
1047 // information can be logged during installation process.1044 // information can be logged during installation process.
1048 $directory = $this->originalFileDirectory . '/simpletest/' . substr($db_prefix, 10);1045 $directory = $this->originalFileDirectory . '/simpletest/' . substr($this->databasePrefix, 10);
1049 file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);1046 file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
10501047
1051 // Log fatal errors.1048 // Log fatal errors.
@@ -1109,7 +1106,7 @@
1109 variable_set('mail_sending_system', array('default-system' => 'TestingMailSystem'));1106 variable_set('mail_sending_system', array('default-system' => 'TestingMailSystem'));
11101107
1111 // Use temporary files directory with the same prefix as the database.1108 // Use temporary files directory with the same prefix as the database.
1112 $public_files_directory = $this->originalFileDirectory . '/' . $db_prefix;1109 $public_files_directory = $this->originalFileDirectory . '/' . $this->databasePrefix;
1113 $private_files_directory = $public_files_directory . '/private';1110 $private_files_directory = $public_files_directory . '/private';
11141111
1115 // Set path variables1112 // Set path variables
@@ -1130,8 +1127,10 @@
1130 * setup a clean environment for the current test run.1127 * setup a clean environment for the current test run.
1131 */1128 */
1132 protected function preloadRegistry() {1129 protected function preloadRegistry() {
1133 db_query('INSERT INTO {registry} SELECT * FROM ' . $this->originalPrefix . 'registry');1130 $original_connection = Database::getConnection('default', 'simpletest_original_default');
1134 db_query('INSERT INTO {registry_file} SELECT * FROM ' . $this->originalPrefix . 'registry_file');1131 $this->pass('INSERT INTO {registry} SELECT * FROM ' . $original_connection->prefixTables('{registry}'));
1132 db_query('INSERT INTO {registry} SELECT * FROM ' . $original_connection->prefixTables('{registry}'));
1133 db_query('INSERT INTO {registry_file} SELECT * FROM ' . $original_connection->prefixTables('{registry_file}'));
1135 }1134 }
11361135
1137 /**1136 /**
@@ -1157,14 +1156,9 @@
1157 * and reset the database prefix.1156 * and reset the database prefix.
1158 */1157 */
1159 protected function tearDown() {1158 protected function tearDown() {
1160 global $db_prefix, $user, $language;1159 global $user, $language;
11611160
1162 // In case a fatal error occured that was not in the test process read the1161 simpletest_log_read($this->testId, $this->databasePrefix, get_class($this), TRUE);
1163 // log to pick up any fatal errors.
1164 $db_prefix_temp = $db_prefix;
1165 $db_prefix = $this->originalPrefix;
1166 simpletest_log_read($this->testId, $db_prefix, get_class($this), TRUE);
1167 $db_prefix = $db_prefix_temp;
11681162
1169 $emailCount = count(variable_get('drupal_test_email_collector', array()));1163 $emailCount = count(variable_get('drupal_test_email_collector', array()));
1170 if ($emailCount) {1164 if ($emailCount) {
@@ -1172,48 +1166,47 @@
1172 $this->pass($message, t('E-mail'));1166 $this->pass($message, t('E-mail'));
1173 }1167 }
11741168
1175 if (preg_match('/simpletest\d+/', $db_prefix)) {1169 // Delete temporary files directory.
1176 // Delete temporary files directory.1170 file_unmanaged_delete_recursive(file_directory_path());
1177 file_unmanaged_delete_recursive(file_directory_path());1171
11781172 // Remove all prefixed tables (all the tables in the schema).
1179 // Remove all prefixed tables (all the tables in the schema).1173 $schema = drupal_get_schema(NULL, TRUE);
1180 $schema = drupal_get_schema(NULL, TRUE);1174 $ret = array();
1181 $ret = array();1175 foreach ($schema as $name => $table) {
1182 foreach ($schema as $name => $table) {1176 db_drop_table($name);
1183 db_drop_table($name);1177 }
1184 }1178
11851179 // Get back to the original connection.
1186 // Return the database prefix to the original.1180 Database::removeConnection('default');
1187 $db_prefix = $this->originalPrefix;1181 Database::renameConnection('simpletest_original_default', 'default');
11881182
1189 // Return the user to the original one.1183 // Return the user to the original one.
1190 $user = $this->originalUser;1184 $user = $this->originalUser;
1191 drupal_save_session(TRUE);1185 drupal_save_session(TRUE);
11921186
1193 // Ensure that internal logged in variable and cURL options are reset.1187 // Ensure that internal logged in variable and cURL options are reset.
1194 $this->loggedInUser = FALSE;1188 $this->isLoggedIn = FALSE;
1195 $this->additionalCurlOptions = array();1189 $this->additionalCurlOptions = array();
11961190
1197 // Reload module list and implementations to ensure that test module hooks1191 // Reload module list and implementations to ensure that test module hooks
1198 // aren't called after tests.1192 // aren't called after tests.
1199 module_list(TRUE);1193 module_list(TRUE);
1200 module_implements('', FALSE, TRUE);1194 module_implements('', FALSE, TRUE);
12011195
1202 // Reset the Field API.1196 // Reset the Field API.
1203 field_cache_clear();1197 field_cache_clear();
12041198
1205 // Rebuild caches.1199 // Rebuild caches.
1206 $this->refreshVariables();1200 $this->refreshVariables();
12071201
1208 // Reset language.1202 // Reset language.
1209 $language = $this->originalLanguage;1203 $language = $this->originalLanguage;
1210 if ($this->originalLanguageDefault) {1204 if ($this->originalLanguageDefault) {
1211 $GLOBALS['conf']['language_default'] = $this->originalLanguageDefault;1205 $GLOBALS['conf']['language_default'] = $this->originalLanguageDefault;
1212 }1206 }
12131207
1214 // Close the CURL handler.1208 // Close the CURL handler.
1215 $this->curlClose();1209 $this->curlClose();
1216 }
1217 }1210 }
12181211
1219 /**1212 /**
@@ -1225,7 +1218,7 @@
1225 * See the description of $curl_options for other options.1218 * See the description of $curl_options for other options.
1226 */1219 */
1227 protected function curlInitialize() {1220 protected function curlInitialize() {
1228 global $base_url, $db_prefix;1221 global $base_url;
12291222
1230 if (!isset($this->curlHandle)) {1223 if (!isset($this->curlHandle)) {
1231 $this->curlHandle = curl_init();1224 $this->curlHandle = curl_init();
@@ -1238,6 +1231,7 @@
1238 CURLOPT_SSL_VERIFYPEER => FALSE, // Required to make the tests run on https.1231 CURLOPT_SSL_VERIFYPEER => FALSE, // Required to make the tests run on https.
1239 CURLOPT_SSL_VERIFYHOST => FALSE, // Required to make the tests run on https.1232 CURLOPT_SSL_VERIFYHOST => FALSE, // Required to make the tests run on https.
1240 CURLOPT_HEADERFUNCTION => array(&$this, 'curlHeaderCallback'),1233 CURLOPT_HEADERFUNCTION => array(&$this, 'curlHeaderCallback'),
1234 CURLOPT_USERAGENT => $this->databasePrefix,
1241 );1235 );
1242 if (isset($this->httpauth_credentials)) {1236 if (isset($this->httpauth_credentials)) {
1243 $curl_options[CURLOPT_USERPWD] = $this->httpauth_credentials;1237 $curl_options[CURLOPT_USERPWD] = $this->httpauth_credentials;
@@ -1249,7 +1243,7 @@
1249 }1243 }
1250 // We set the user agent header on each request so as to use the current1244 // We set the user agent header on each request so as to use the current
1251 // time and a new uniqid.1245 // time and a new uniqid.
1252 if (preg_match('/simpletest\d+/', $db_prefix, $matches)) {1246 if (preg_match('/simpletest\d+/', $this->databasePrefix, $matches)) {
1253 curl_setopt($this->curlHandle, CURLOPT_USERAGENT, drupal_generate_test_ua($matches[0]));1247 curl_setopt($this->curlHandle, CURLOPT_USERAGENT, drupal_generate_test_ua($matches[0]));
1254 }1248 }
1255 }1249 }
@@ -1692,7 +1686,7 @@
1692 protected function xpath($xpath) {1686 protected function xpath($xpath) {
1693 if ($this->parse()) {1687 if ($this->parse()) {
1694 return $this->elements->xpath($xpath);1688 return $this->elements->xpath($xpath);
1695 }1689 }
1696 return FALSE;1690 return FALSE;
1697 }1691 }
16981692
16991693
=== modified file 'modules/simpletest/simpletest.module'
--- modules/simpletest/simpletest.module 2009-10-09 00:59:53 +0000
+++ modules/simpletest/simpletest.module 2009-10-13 23:58:11 +0000
@@ -414,16 +414,18 @@
414function simpletest_clean_database() {414function simpletest_clean_database() {
415 $tables = db_find_tables(Database::getConnection()->prefixTables('{simpletest}') . '%');415 $tables = db_find_tables(Database::getConnection()->prefixTables('{simpletest}') . '%');
416 $schema = drupal_get_schema_unprocessed('simpletest');416 $schema = drupal_get_schema_unprocessed('simpletest');
417 $removed = 0;
417 foreach (array_diff_key($tables, $schema) as $table) {418 foreach (array_diff_key($tables, $schema) as $table) {
418 // Strip the prefix and skip tables without digits following "simpletest",419 // Strip the prefix and skip tables without digits following "simpletest",
419 // e.g. {simpletest_test_id}.420 // e.g. {simpletest_test_id}.
420 if (preg_match('/simpletest\d+.*/', $table, $matches)) {421 if (preg_match('/simpletest\d+.*/', $table, $matches)) {
421 db_drop_table($matches[0]);422 db_drop_table($matches[0]);
423 ++$removed;
422 }424 }
423 }425 }
424426
425 if (count($ret) > 0) {427 if (count($removed) > 0) {
426 drupal_set_message(format_plural(count($ret), 'Removed 1 leftover table.', 'Removed @count leftover tables.'));428 drupal_set_message(format_plural(count($removed), 'Removed 1 leftover table.', 'Removed @count leftover tables.'));
427 }429 }
428 else {430 else {
429 drupal_set_message(t('No leftover tables to remove.'));431 drupal_set_message(t('No leftover tables to remove.'));
430432
=== modified file 'sites/default/default.settings.php'
--- sites/default/default.settings.php 2009-10-09 07:48:06 +0000
+++ sites/default/default.settings.php 2009-10-13 23:58:11 +0000
@@ -61,6 +61,7 @@
61 * 'password' => 'password',61 * 'password' => 'password',
62 * 'host' => 'localhost',62 * 'host' => 'localhost',
63 * 'port' => 3306,63 * 'port' => 3306,
64 * 'prefix' => 'myprefix_',
64 * );65 * );
65 *66 *
66 * The "driver" property indicates what Drupal database driver the67 * The "driver" property indicates what Drupal database driver the
@@ -105,30 +106,31 @@
105 * 'username' => 'username',106 * 'username' => 'username',
106 * 'password' => 'password',107 * 'password' => 'password',
107 * 'host' => 'localhost',108 * 'host' => 'localhost',
109 * 'prefix' => 'main_',
108 * );110 * );
109 *111 *
110 * You can optionally set prefixes for some or all database table names112 * You can optionally set prefixes for some or all database table names
111 * by using the $db_prefix setting. If a prefix is specified, the table113 * by using the 'prefix' setting. If a prefix is specified, the table
112 * name will be prepended with its value. Be sure to use valid database114 * name will be prepended with its value. Be sure to use valid database
113 * characters only, usually alphanumeric and underscore. If no prefixes115 * characters only, usually alphanumeric and underscore. If no prefixes
114 * are desired, leave it as an empty string ''.116 * are desired, leave it as an empty string ''.
115 *117 *
116 * To have all database names prefixed, set $db_prefix as a string:118 * To have all database names prefixed, set 'prefix' as a string:
117 *119 *
118 * $db_prefix = 'main_';120 * 'prefix' => 'main_',
119 *121 *
120 * To provide prefixes for specific tables, set $db_prefix as an array.122 * To provide prefixes for specific tables, set 'prefix' as an array.
121 * The array's keys are the table names and the values are the prefixes.123 * The array's keys are the table names and the values are the prefixes.
122 * The 'default' element holds the prefix for any tables not specified124 * The 'default' element is mandatory and holds the prefix for any tables
123 * elsewhere in the array. Example:125 * not specified elsewhere in the array. Example:
124 *126 *
125 * $db_prefix = array(127 * 'prefix' = array(
126 * 'default' => 'main_',128 * 'default' => 'main_',
127 * 'users' => 'shared_',129 * 'users' => 'shared_',
128 * 'sessions' => 'shared_',130 * 'sessions' => 'shared_',
129 * 'role' => 'shared_',131 * 'role' => 'shared_',
130 * 'authmap' => 'shared_',132 * 'authmap' => 'shared_',
131 * );133 * ),
132 *134 *
133 * Database configuration format:135 * Database configuration format:
134 * $databases['default']['default'] = array(136 * $databases['default']['default'] = array(
@@ -137,6 +139,7 @@
137 * 'username' => 'username',139 * 'username' => 'username',
138 * 'password' => 'password',140 * 'password' => 'password',
139 * 'host' => 'localhost',141 * 'host' => 'localhost',
142 * 'prefix' => '',
140 * );143 * );
141 * $databases['default']['default'] = array(144 * $databases['default']['default'] = array(
142 * 'driver' => 'pgsql',145 * 'driver' => 'pgsql',
@@ -144,6 +147,7 @@
144 * 'username' => 'username',147 * 'username' => 'username',
145 * 'password' => 'password',148 * 'password' => 'password',
146 * 'host' => 'localhost',149 * 'host' => 'localhost',
150 * 'prefix' => '',
147 * );151 * );
148 * $databases['default']['default'] = array(152 * $databases['default']['default'] = array(
149 * 'driver' => 'sqlite',153 * 'driver' => 'sqlite',
@@ -151,7 +155,6 @@
151 * );155 * );
152 */156 */
153$databases = array();157$databases = array();
154$db_prefix = '';
155158
156/**159/**
157 * Access control for update.php script160 * Access control for update.php script

Subscribers

People subscribed via source and target branches