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

Proposed by David Strauss on 2009-10-13
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 2009-10-13 Pending
Review via email: mp+13264@code.launchpad.net
To post a comment you must log in.
11226. By David Strauss on 2009-10-13

Fix some duplicated code from the conflict resolution.

11227. By David Strauss on 2009-10-13

Almost working...

11228. By David Strauss on 2009-10-13

Where I am now

11229. By David Strauss on 2009-10-13

Remove junk output

11230. By chx <chx@veyron> on 2009-10-13

fixed database init

Unmerged revisions

11230. By chx <chx@veyron> on 2009-10-13

fixed database init

11229. By David Strauss on 2009-10-13

Remove junk output

11228. By David Strauss on 2009-10-13

Where I am now

11227. By David Strauss on 2009-10-13

Almost working...

11226. By David Strauss on 2009-10-13

Fix some duplicated code from the conflict resolution.

11225. By David Strauss on 2009-10-13

Current progress.

11224. By David Strauss on 2009-10-12

Ignore

11223. By David Strauss on 2009-10-12

Failed patch.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file '.bzrignore'
2--- .bzrignore 1970-01-01 00:00:00 +0000
3+++ .bzrignore 2009-10-13 23:58:10 +0000
4@@ -0,0 +1,3 @@
5+./sites/default/files
6+./sites/default/private
7+./sites/default/settings.php
8
9=== modified file 'includes/bootstrap.inc'
10--- includes/bootstrap.inc 2009-10-09 16:33:13 +0000
11+++ includes/bootstrap.inc 2009-10-13 23:58:10 +0000
12@@ -572,6 +572,17 @@
13 }
14
15 /**
16+ * Retrieve (and optionally set) information about the current test being run.
17+ */
18+function drupal_test_info($value = FALSE) {
19+ static $cache;
20+ if ($value !== FALSE) {
21+ $cache = $value;
22+ }
23+ return $cache;
24+}
25+
26+/**
27 * Returns and optionally sets the filename for a system item (module,
28 * theme, etc.). The filename, whether provided, cached, or retrieved
29 * from the database, is only returned if the file exists.
30
31=== modified file 'includes/common.inc'
32--- includes/common.inc 2009-10-13 21:16:42 +0000
33+++ includes/common.inc 2009-10-13 23:58:11 +0000
34@@ -782,8 +782,6 @@
35 * A string containing the response body that was received.
36 */
37 function drupal_http_request($url, array $options = array()) {
38- global $db_prefix;
39-
40 $result = new stdClass();
41
42 // Parse the URL and make sure we can handle the schema.
43@@ -882,8 +880,8 @@
44 // user-agent is used to ensure that multiple testing sessions running at the
45 // same time won't interfere with each other as they would if the database
46 // prefix were stored statically in a file or database variable.
47- if (is_string($db_prefix) && preg_match("/simpletest\d+/", $db_prefix, $matches)) {
48- $options['headers']['User-Agent'] = drupal_generate_test_ua($matches[0]);
49+ if ($test_info = drupal_test_info()) {
50+ $options['headers']['User-Agent'] = $test_info['test_run_id'];
51 }
52
53 $request = $options['method'] . ' ' . $path . " HTTP/1.0\r\n";
54
55=== modified file 'includes/database/database.inc'
56--- includes/database/database.inc 2009-10-12 02:00:04 +0000
57+++ includes/database/database.inc 2009-10-13 23:58:11 +0000
58@@ -317,6 +317,22 @@
59 */
60 protected $schema = NULL;
61
62+ /**
63+ * The default prefix used by this database connection.
64+ *
65+ * Separated from the other prefixes for performance reasons.
66+ *
67+ * @var string
68+ */
69+ protected $defaultPrefix = '';
70+
71+ /**
72+ * The non-default prefixes used by this database connection.
73+ *
74+ * @var array
75+ */
76+ protected $prefixes = array();
77+
78 function __construct($dsn, $username, $password, $driver_options = array()) {
79 // Because the other methods don't seem to work right.
80 $driver_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
81@@ -390,6 +406,24 @@
82 }
83
84 /**
85+ * Preprocess the prefix used by this database connection.
86+ *
87+ * @param $prefix
88+ * The prefix, in any of the multiple forms documented in default.settings.php.
89+ */
90+ protected function setPrefix($prefix) {
91+ if (is_array($prefix)) {
92+ $this->defaultPrefix = isset($prefix['default']) ? $prefix['default'] : '';
93+ unset($prefix['default']);
94+ $this->prefixes = $prefix;
95+ }
96+ else {
97+ $this->defaultPrefix = $prefix;
98+ $this->prefixes = array();
99+ }
100+ }
101+
102+ /**
103 * Append a database prefix to all tables in a query.
104 *
105 * Queries sent to Drupal should wrap all table names in curly brackets. This
106@@ -403,27 +437,12 @@
107 * The properly-prefixed string.
108 */
109 public function prefixTables($sql) {
110- global $db_prefix;
111-
112- if (is_array($db_prefix)) {
113- if (array_key_exists('default', $db_prefix)) {
114- $tmp = $db_prefix;
115- unset($tmp['default']);
116- foreach ($tmp as $key => $val) {
117- $sql = strtr($sql, array('{' . $key . '}' => $val . $key));
118- }
119- return strtr($sql, array('{' => $db_prefix['default'] , '}' => ''));
120- }
121- else {
122- foreach ($db_prefix as $key => $val) {
123- $sql = strtr($sql, array('{' . $key . '}' => $val . $key));
124- }
125- return strtr($sql, array('{' => '' , '}' => ''));
126- }
127- }
128- else {
129- return strtr($sql, array('{' => $db_prefix , '}' => ''));
130- }
131+ // Replace specific table prefixes first.
132+ foreach ($this->prefixes as $key => $val) {
133+ $sql = strtr($sql, array('{' . $key . '}' => $val . $key));
134+ }
135+ // Then replace remaining tables with the default prefix.
136+ return strtr($sql, array('{' => $this->defaultPrefix , '}' => ''));
137 }
138
139 /**
140@@ -1260,6 +1279,20 @@
141 if (empty($value['driver'])) {
142 $databaseInfo[$index][$target] = $databaseInfo[$index][$target][mt_rand(0, count($databaseInfo[$index][$target]) - 1)];
143 }
144+
145+ // Parse the prefix information.
146+ if (!isset($databaseInfo[$index][$target]['prefix'])) {
147+ // Default to an empty prefix.
148+ $databaseInfo[$index][$target]['prefix'] = array(
149+ 'default' => '',
150+ );
151+ }
152+ else if (!is_array($databaseInfo[$index][$target]['prefix'])) {
153+ // Transform the flat form into an array form.
154+ $databaseInfo[$index][$target]['prefix'] = array(
155+ 'default' => $databaseInfo[$index][$target]['prefix'],
156+ );
157+ }
158 }
159 }
160
161@@ -1319,7 +1352,40 @@
162 if (!empty(self::$databaseInfo[$key])) {
163 return self::$databaseInfo[$key];
164 }
165-
166+ }
167+
168+ /**
169+ * Rename a connection and its corresponding connection information.
170+ *
171+ * @param $old_key
172+ * The old connection key.
173+ * @param $new_key
174+ * The new connection key.
175+ */
176+ final public static function renameConnection($old_key, $new_key) {
177+ if (empty(self::$databaseInfo)) {
178+ self::parseConnectionInfo();
179+ }
180+
181+ if (!empty(self::$databaseInfo[$old_key]) && empty(self::$databaseInfo[$new_key])) {
182+ self::$databaseInfo[$new_key] = self::$databaseInfo[$old_key];
183+ unset(self::$databaseInfo[$old_key]);
184+ if (isset(self::$connections[$old_key])) {
185+ self::$connections[$new_key] = self::$connections[$old_key];
186+ unset(self::$connections[$old_key]);
187+ }
188+ }
189+ }
190+
191+ /**
192+ * Remove a connection and its corresponding connection information.
193+ *
194+ * @param $key
195+ * The connection key.
196+ */
197+ final public static function removeConnection($key) {
198+ unset(self::$databaseInfo[$key]);
199+ unset(self::$connections[$key]);
200 }
201
202 /**
203@@ -1332,7 +1398,7 @@
204 * The database target to open.
205 */
206 final protected static function openConnection($key, $target) {
207- global $db_prefix;
208+ global $databases;
209
210 if (empty(self::$databaseInfo)) {
211 self::parseConnectionInfo();
212@@ -1359,12 +1425,29 @@
213 if (!empty(self::$logs[$key])) {
214 $new_connection->setLogger(self::$logs[$key]);
215 }
216-
217 // We need to pass around the simpletest database prefix in the request
218 // and we put that in the user_agent header. The header HMAC was already
219 // validated in bootstrap.inc.
220 if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/^(simpletest\d+);/", $_SERVER['HTTP_USER_AGENT'], $matches)) {
221- $db_prefix .= $matches[1];
222+ $test_prefix = $matches[1];
223+ drupal_test_info(array('test_run_id' => $test_prefix, 'in_child_site' => TRUE));
224+ foreach ($databases['default'] as $target => $value) {
225+ // Extract the current default database prefix.
226+ if (empty($value['prefix'])) {
227+ $current_prefix = '';
228+ }
229+ else if (is_array($value['prefix'])) {
230+ $current_prefix = $value['prefix']['default'];
231+ }
232+ else {
233+ $current_prefix = $value['prefix'];
234+ }
235+
236+ // Remove the current database prefix and replace it by our own.
237+ $databases['default'][$target]['prefix'] = array(
238+ 'default' => $current_prefix . $test_prefix,
239+ );
240+ }
241 }
242 return $new_connection;
243 }
244
245=== modified file 'includes/database/mysql/database.inc'
246--- includes/database/mysql/database.inc 2009-09-18 00:04:21 +0000
247+++ includes/database/mysql/database.inc 2009-10-13 23:58:11 +0000
248@@ -25,6 +25,8 @@
249 $connection_options['port'] = 3306;
250 }
251
252+ $this->setPrefix(isset($connection_options['prefix']) ? $connection_options['prefix'] : '');
253+
254 $dsn = 'mysql:host=' . $connection_options['host'] . ';port=' . $connection_options['port'] . ';dbname=' . $connection_options['database'];
255 parent::__construct($dsn, $connection_options['username'], $connection_options['password'], array(
256 // So we don't have to mess around with cursors and unbuffered queries by default.
257
258=== modified file 'includes/database/pgsql/database.inc'
259--- includes/database/pgsql/database.inc 2009-09-18 00:04:21 +0000
260+++ includes/database/pgsql/database.inc 2009-10-13 23:58:11 +0000
261@@ -26,6 +26,8 @@
262 $connection_options['port'] = 5432;
263 }
264
265+ $this->setPrefix(isset($connection_options['prefix']) ? $connection_options['prefix'] : '');
266+
267 // PostgreSQL in trust mode doesn't require a password to be supplied.
268 if (empty($connection_options['password'])) {
269 $connection_options['password'] = null;
270
271=== modified file 'includes/database/sqlite/database.inc'
272--- includes/database/sqlite/database.inc 2009-09-18 00:04:21 +0000
273+++ includes/database/sqlite/database.inc 2009-10-13 23:58:11 +0000
274@@ -25,6 +25,8 @@
275 // This driver defaults to transaction support, except if explicitly passed FALSE.
276 $this->transactionSupport = !isset($connection_options['transactions']) || $connection_options['transactions'] !== FALSE;
277
278+ $this->setPrefix(isset($connection_options['prefix']) ? $connection_options['prefix'] : '');
279+
280 parent::__construct('sqlite:' . $connection_options['database'], '', '', array(
281 // Force column names to lower case.
282 PDO::ATTR_CASE => PDO::CASE_LOWER,
283
284=== modified file 'install.php'
285--- install.php 2009-10-13 14:15:08 +0000
286+++ install.php 2009-10-13 23:58:10 +0000
287@@ -788,7 +788,7 @@
288 * Verify existing settings.php
289 */
290 function install_verify_settings() {
291- global $db_prefix, $databases;
292+ global $databases;
293
294 // Verify existing settings (if any).
295 if (!empty($databases)) {
296@@ -814,7 +814,7 @@
297 * The form API definition for the database configuration form.
298 */
299 function install_settings_form($form, &$form_state, &$install_state) {
300- global $databases, $db_prefix;
301+ global $databases;
302 $profile = $install_state['parameters']['profile'];
303 $install_locale = $install_state['parameters']['locale'];
304
305@@ -909,13 +909,13 @@
306 );
307
308 // Table prefix
309- $db_prefix = ($profile == 'default') ? 'drupal_' : $profile . '_';
310- $form['advanced_options']['db_prefix'] = array(
311+ $prefix = ($profile == 'default') ? 'drupal_' : $profile . '_';
312+ $form['advanced_options']['prefix'] = array(
313 '#type' => 'textfield',
314 '#title' => st('Table prefix'),
315 '#default_value' => '',
316 '#size' => 45,
317- '#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)),
318+ '#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)),
319 );
320
321 $form['save'] = array(
322@@ -948,12 +948,12 @@
323 global $databases;
324 $errors = array();
325 // Verify the table prefix
326- if (!empty($database['db_prefix']) && is_string($database['db_prefix']) && !preg_match('/^[A-Za-z0-9_.]+$/', $database['db_prefix'])) {
327- $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']));
328+ if (!empty($database['prefix']) && is_string($database['prefix']) && !preg_match('/^[A-Za-z0-9_.]+$/', $database['prefix'])) {
329+ $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']));
330 }
331
332 if (!empty($database['port']) && !is_numeric($database['port'])) {
333- $errors['db_port'] = st('Database port must be a number.');
334+ $errors['port'] = st('Database port must be a number.');
335 }
336
337 // Check database type
338@@ -989,16 +989,12 @@
339 function install_settings_form_submit($form, &$form_state) {
340 global $install_state;
341
342- $database = array_intersect_key($form_state['values']['_database'], array_flip(array('driver', 'database', 'username', 'password', 'host', 'port')));
343+ $database = array_intersect_key($form_state['values']['_database'], array_flip(array('driver', 'database', 'username', 'password', 'host', 'port', 'prefix')));
344 // Update global settings array and save
345 $settings['databases'] = array(
346 'value' => array('default' => array('default' => $database)),
347 'required' => TRUE,
348 );
349- $settings['db_prefix'] = array(
350- 'value' => $form_state['values']['db_prefix'],
351- 'required' => TRUE,
352- );
353 drupal_rewrite_settings($settings);
354 // Indicate that the settings file has been verified, and check the database
355 // for the last completed task, now that we have a valid connection. This
356
357=== modified file 'modules/simpletest/drupal_web_test_case.php'
358--- modules/simpletest/drupal_web_test_case.php 2009-10-13 07:14:26 +0000
359+++ modules/simpletest/drupal_web_test_case.php 2009-10-13 23:58:11 +0000
360@@ -15,11 +15,11 @@
361 protected $testId;
362
363 /**
364- * The original database prefix, before it was changed for testing purposes.
365+ * The database prefix of this test run.
366 *
367 * @var string
368 */
369- protected $originalPrefix = NULL;
370+ protected $databasePrefix = NULL;
371
372 /**
373 * The original file directory, before it was changed for testing purposes.
374@@ -90,8 +90,6 @@
375 * is the caller function itself.
376 */
377 protected function assert($status, $message = '', $group = 'Other', array $caller = NULL) {
378- global $db_prefix;
379-
380 // Convert boolean status to string status.
381 if (is_bool($status)) {
382 $status = $status ? 'pass' : 'fail';
383@@ -105,10 +103,6 @@
384 $caller = $this->getAssertionCall();
385 }
386
387- // Switch to non-testing database to store results in.
388- $current_db_prefix = $db_prefix;
389- $db_prefix = $this->originalPrefix;
390-
391 // Creation assertion array that can be displayed while tests are running.
392 $this->assertions[] = $assertion = array(
393 'test_id' => $this->testId,
394@@ -122,12 +116,11 @@
395 );
396
397 // Store assertion for display after the test has completed.
398- db_insert('simpletest')
399+ Database::getConnection('default', 'simpletest_original_default')
400+ ->insert('simpletest')
401 ->fields($assertion)
402 ->execute();
403
404- // Return to testing prefix.
405- $db_prefix = $current_db_prefix;
406 // We do not use a ternary operator here to allow a breakpoint on
407 // test failure.
408 if ($status == 'pass') {
409@@ -473,18 +466,18 @@
410 * is not restricted.
411 *
412 * @param $length
413- * Length of random string to generate which will be appended to $db_prefix.
414+ * Length of random string to generate which will be appended to $test_info['test_run_id'].
415 * @return
416 * Randomly generated string.
417 */
418 public static function randomString($length = 8) {
419- global $db_prefix;
420-
421 $str = '';
422 for ($i = 0; $i < $length; $i++) {
423 $str .= chr(mt_rand(32, 126));
424 }
425- return str_replace('simpletest', 's', $db_prefix) . $str;
426+
427+ $test_info = drupal_test_info();
428+ return str_replace('simpletest', 's', $test_info['test_run_id']) . $str;
429 }
430
431 /**
432@@ -496,20 +489,19 @@
433 * spaces and non-standard characters) this method is best.
434 *
435 * @param $length
436- * Length of random string to generate which will be appended to $db_prefix.
437+ * Length of random string to generate which will be appended to $test_info['test_run_id'].
438 * @return
439 * Randomly generated string.
440 */
441 public static function randomName($length = 8) {
442- global $db_prefix;
443-
444 $values = array_merge(range(65, 90), range(97, 122), range(48, 57));
445 $max = count($values) - 1;
446 $str = '';
447 for ($i = 0; $i < $length; $i++) {
448 $str .= chr($values[mt_rand(0, $max)]);
449 }
450- return str_replace('simpletest', 's', $db_prefix) . $str;
451+ $test_info = drupal_test_info();
452+ return str_replace('simpletest', 's', $test_info['test_run_id']) . $str;
453 }
454
455 }
456@@ -533,15 +525,14 @@
457 }
458
459 function setUp() {
460- global $db_prefix, $conf;
461+ global $conf;
462
463 // Store necessary current values before switching to prefixed database.
464- $this->originalPrefix = $db_prefix;
465 $this->originalFileDirectory = file_directory_path();
466
467 // Generate temporary prefixed database to ensure that tests have a clean starting point.
468- $db_prefix = Database::getConnection()->prefixTables('{simpletest' . mt_rand(1000, 1000000) . '}');
469- $conf['file_public_path'] = $this->originalFileDirectory . '/' . $db_prefix;
470+ $this->databasePrefix = Database::getConnection()->prefixTables('{simpletest' . mt_rand(1000, 1000000) . '}');
471+ $conf['file_public_path'] = $this->originalFileDirectory . '/' . $this->databasePrefix;
472
473 // If locale is enabled then t() will try to access the database and
474 // subsequently will fail as the database is not accessible.
475@@ -554,11 +545,10 @@
476 }
477
478 function tearDown() {
479- global $db_prefix, $conf;
480- if (preg_match('/simpletest\d+/', $db_prefix)) {
481+ global $conf;
482+
483+ if (preg_match('/simpletest\d+/', $this->databasePrefix)) {
484 $conf['file_public_path'] = $this->originalFileDirectory;
485- // Return the database prefix to the original.
486- $db_prefix = $this->originalPrefix;
487 // Restore modules if necessary.
488 if (isset($this->originalModuleList)) {
489 module_list(TRUE, FALSE, FALSE, $this->originalModuleList);
490@@ -1025,27 +1015,34 @@
491 * List of modules to enable for the duration of the test.
492 */
493 protected function setUp() {
494- global $db_prefix, $user, $language;
495+ global $user, $language;
496+
497+ // Generate a temporary prefixed database to ensure that tests have a clean starting point.
498+ $this->databasePrefix = 'simpletest' . mt_rand(1000, 1000000);
499+
500+ // Clone the current connection and replace the current prefix.
501+ $connection_info = Database::getConnectionInfo('default');
502+ Database::renameConnection('default', 'simpletest_original_default');
503+ foreach ($connection_info as $target => $value) {
504+ $connection_info[$target]['prefix'] = array(
505+ 'default' => $value['prefix']['default'] . $this->databasePrefix,
506+ );
507+ }
508+ Database::addConnectionInfo('default', 'default', $connection_info['default']);
509
510 // Store necessary current values before switching to prefixed database.
511 $this->originalLanguage = $language;
512 $this->originalLanguageDefault = variable_get('language_default');
513- $this->originalPrefix = $db_prefix;
514 $this->originalFileDirectory = file_directory_path();
515 $this->originalProfile = drupal_get_profile();
516 $clean_url_original = variable_get('clean_url', 0);
517
518- // Generate temporary prefixed database to ensure that tests have a clean starting point.
519- $db_prefix_new = Database::getConnection()->prefixTables('{simpletest' . mt_rand(1000, 1000000) . '}');
520- db_update('simpletest_test_id')
521- ->fields(array('last_prefix' => $db_prefix_new))
522- ->condition('test_id', $this->testId)
523- ->execute();
524- $db_prefix = $db_prefix_new;
525+ // Set the simpletest id for use in other parts of Drupal.
526+ drupal_test_info(array('test_run_id' => $this->databasePrefix, 'in_child_site' => FALSE));
527
528 // Create test directory ahead of installation so fatal errors and debug
529 // information can be logged during installation process.
530- $directory = $this->originalFileDirectory . '/simpletest/' . substr($db_prefix, 10);
531+ $directory = $this->originalFileDirectory . '/simpletest/' . substr($this->databasePrefix, 10);
532 file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
533
534 // Log fatal errors.
535@@ -1109,7 +1106,7 @@
536 variable_set('mail_sending_system', array('default-system' => 'TestingMailSystem'));
537
538 // Use temporary files directory with the same prefix as the database.
539- $public_files_directory = $this->originalFileDirectory . '/' . $db_prefix;
540+ $public_files_directory = $this->originalFileDirectory . '/' . $this->databasePrefix;
541 $private_files_directory = $public_files_directory . '/private';
542
543 // Set path variables
544@@ -1130,8 +1127,10 @@
545 * setup a clean environment for the current test run.
546 */
547 protected function preloadRegistry() {
548- db_query('INSERT INTO {registry} SELECT * FROM ' . $this->originalPrefix . 'registry');
549- db_query('INSERT INTO {registry_file} SELECT * FROM ' . $this->originalPrefix . 'registry_file');
550+ $original_connection = Database::getConnection('default', 'simpletest_original_default');
551+ $this->pass('INSERT INTO {registry} SELECT * FROM ' . $original_connection->prefixTables('{registry}'));
552+ db_query('INSERT INTO {registry} SELECT * FROM ' . $original_connection->prefixTables('{registry}'));
553+ db_query('INSERT INTO {registry_file} SELECT * FROM ' . $original_connection->prefixTables('{registry_file}'));
554 }
555
556 /**
557@@ -1157,14 +1156,9 @@
558 * and reset the database prefix.
559 */
560 protected function tearDown() {
561- global $db_prefix, $user, $language;
562+ global $user, $language;
563
564- // In case a fatal error occured that was not in the test process read the
565- // log to pick up any fatal errors.
566- $db_prefix_temp = $db_prefix;
567- $db_prefix = $this->originalPrefix;
568- simpletest_log_read($this->testId, $db_prefix, get_class($this), TRUE);
569- $db_prefix = $db_prefix_temp;
570+ simpletest_log_read($this->testId, $this->databasePrefix, get_class($this), TRUE);
571
572 $emailCount = count(variable_get('drupal_test_email_collector', array()));
573 if ($emailCount) {
574@@ -1172,48 +1166,47 @@
575 $this->pass($message, t('E-mail'));
576 }
577
578- if (preg_match('/simpletest\d+/', $db_prefix)) {
579- // Delete temporary files directory.
580- file_unmanaged_delete_recursive(file_directory_path());
581-
582- // Remove all prefixed tables (all the tables in the schema).
583- $schema = drupal_get_schema(NULL, TRUE);
584- $ret = array();
585- foreach ($schema as $name => $table) {
586- db_drop_table($name);
587- }
588-
589- // Return the database prefix to the original.
590- $db_prefix = $this->originalPrefix;
591-
592- // Return the user to the original one.
593- $user = $this->originalUser;
594- drupal_save_session(TRUE);
595-
596- // Ensure that internal logged in variable and cURL options are reset.
597- $this->loggedInUser = FALSE;
598- $this->additionalCurlOptions = array();
599-
600- // Reload module list and implementations to ensure that test module hooks
601- // aren't called after tests.
602- module_list(TRUE);
603- module_implements('', FALSE, TRUE);
604-
605- // Reset the Field API.
606- field_cache_clear();
607-
608- // Rebuild caches.
609- $this->refreshVariables();
610-
611- // Reset language.
612- $language = $this->originalLanguage;
613- if ($this->originalLanguageDefault) {
614- $GLOBALS['conf']['language_default'] = $this->originalLanguageDefault;
615- }
616-
617- // Close the CURL handler.
618- $this->curlClose();
619- }
620+ // Delete temporary files directory.
621+ file_unmanaged_delete_recursive(file_directory_path());
622+
623+ // Remove all prefixed tables (all the tables in the schema).
624+ $schema = drupal_get_schema(NULL, TRUE);
625+ $ret = array();
626+ foreach ($schema as $name => $table) {
627+ db_drop_table($name);
628+ }
629+
630+ // Get back to the original connection.
631+ Database::removeConnection('default');
632+ Database::renameConnection('simpletest_original_default', 'default');
633+
634+ // Return the user to the original one.
635+ $user = $this->originalUser;
636+ drupal_save_session(TRUE);
637+
638+ // Ensure that internal logged in variable and cURL options are reset.
639+ $this->isLoggedIn = FALSE;
640+ $this->additionalCurlOptions = array();
641+
642+ // Reload module list and implementations to ensure that test module hooks
643+ // aren't called after tests.
644+ module_list(TRUE);
645+ module_implements('', FALSE, TRUE);
646+
647+ // Reset the Field API.
648+ field_cache_clear();
649+
650+ // Rebuild caches.
651+ $this->refreshVariables();
652+
653+ // Reset language.
654+ $language = $this->originalLanguage;
655+ if ($this->originalLanguageDefault) {
656+ $GLOBALS['conf']['language_default'] = $this->originalLanguageDefault;
657+ }
658+
659+ // Close the CURL handler.
660+ $this->curlClose();
661 }
662
663 /**
664@@ -1225,7 +1218,7 @@
665 * See the description of $curl_options for other options.
666 */
667 protected function curlInitialize() {
668- global $base_url, $db_prefix;
669+ global $base_url;
670
671 if (!isset($this->curlHandle)) {
672 $this->curlHandle = curl_init();
673@@ -1238,6 +1231,7 @@
674 CURLOPT_SSL_VERIFYPEER => FALSE, // Required to make the tests run on https.
675 CURLOPT_SSL_VERIFYHOST => FALSE, // Required to make the tests run on https.
676 CURLOPT_HEADERFUNCTION => array(&$this, 'curlHeaderCallback'),
677+ CURLOPT_USERAGENT => $this->databasePrefix,
678 );
679 if (isset($this->httpauth_credentials)) {
680 $curl_options[CURLOPT_USERPWD] = $this->httpauth_credentials;
681@@ -1249,7 +1243,7 @@
682 }
683 // We set the user agent header on each request so as to use the current
684 // time and a new uniqid.
685- if (preg_match('/simpletest\d+/', $db_prefix, $matches)) {
686+ if (preg_match('/simpletest\d+/', $this->databasePrefix, $matches)) {
687 curl_setopt($this->curlHandle, CURLOPT_USERAGENT, drupal_generate_test_ua($matches[0]));
688 }
689 }
690@@ -1692,7 +1686,7 @@
691 protected function xpath($xpath) {
692 if ($this->parse()) {
693 return $this->elements->xpath($xpath);
694- }
695+ }
696 return FALSE;
697 }
698
699
700=== modified file 'modules/simpletest/simpletest.module'
701--- modules/simpletest/simpletest.module 2009-10-09 00:59:53 +0000
702+++ modules/simpletest/simpletest.module 2009-10-13 23:58:11 +0000
703@@ -414,16 +414,18 @@
704 function simpletest_clean_database() {
705 $tables = db_find_tables(Database::getConnection()->prefixTables('{simpletest}') . '%');
706 $schema = drupal_get_schema_unprocessed('simpletest');
707+ $removed = 0;
708 foreach (array_diff_key($tables, $schema) as $table) {
709 // Strip the prefix and skip tables without digits following "simpletest",
710 // e.g. {simpletest_test_id}.
711 if (preg_match('/simpletest\d+.*/', $table, $matches)) {
712 db_drop_table($matches[0]);
713+ ++$removed;
714 }
715 }
716
717- if (count($ret) > 0) {
718- drupal_set_message(format_plural(count($ret), 'Removed 1 leftover table.', 'Removed @count leftover tables.'));
719+ if (count($removed) > 0) {
720+ drupal_set_message(format_plural(count($removed), 'Removed 1 leftover table.', 'Removed @count leftover tables.'));
721 }
722 else {
723 drupal_set_message(t('No leftover tables to remove.'));
724
725=== modified file 'sites/default/default.settings.php'
726--- sites/default/default.settings.php 2009-10-09 07:48:06 +0000
727+++ sites/default/default.settings.php 2009-10-13 23:58:11 +0000
728@@ -61,6 +61,7 @@
729 * 'password' => 'password',
730 * 'host' => 'localhost',
731 * 'port' => 3306,
732+ * 'prefix' => 'myprefix_',
733 * );
734 *
735 * The "driver" property indicates what Drupal database driver the
736@@ -105,30 +106,31 @@
737 * 'username' => 'username',
738 * 'password' => 'password',
739 * 'host' => 'localhost',
740+ * 'prefix' => 'main_',
741 * );
742 *
743 * You can optionally set prefixes for some or all database table names
744- * by using the $db_prefix setting. If a prefix is specified, the table
745+ * by using the 'prefix' setting. If a prefix is specified, the table
746 * name will be prepended with its value. Be sure to use valid database
747 * characters only, usually alphanumeric and underscore. If no prefixes
748 * are desired, leave it as an empty string ''.
749 *
750- * To have all database names prefixed, set $db_prefix as a string:
751- *
752- * $db_prefix = 'main_';
753- *
754- * To provide prefixes for specific tables, set $db_prefix as an array.
755+ * To have all database names prefixed, set 'prefix' as a string:
756+ *
757+ * 'prefix' => 'main_',
758+ *
759+ * To provide prefixes for specific tables, set 'prefix' as an array.
760 * The array's keys are the table names and the values are the prefixes.
761- * The 'default' element holds the prefix for any tables not specified
762- * elsewhere in the array. Example:
763+ * The 'default' element is mandatory and holds the prefix for any tables
764+ * not specified elsewhere in the array. Example:
765 *
766- * $db_prefix = array(
767+ * 'prefix' = array(
768 * 'default' => 'main_',
769 * 'users' => 'shared_',
770 * 'sessions' => 'shared_',
771 * 'role' => 'shared_',
772 * 'authmap' => 'shared_',
773- * );
774+ * ),
775 *
776 * Database configuration format:
777 * $databases['default']['default'] = array(
778@@ -137,6 +139,7 @@
779 * 'username' => 'username',
780 * 'password' => 'password',
781 * 'host' => 'localhost',
782+ * 'prefix' => '',
783 * );
784 * $databases['default']['default'] = array(
785 * 'driver' => 'pgsql',
786@@ -144,6 +147,7 @@
787 * 'username' => 'username',
788 * 'password' => 'password',
789 * 'host' => 'localhost',
790+ * 'prefix' => '',
791 * );
792 * $databases['default']['default'] = array(
793 * 'driver' => 'sqlite',
794@@ -151,7 +155,6 @@
795 * );
796 */
797 $databases = array();
798-$db_prefix = '';
799
800 /**
801 * Access control for update.php script

Subscribers

People subscribed via source and target branches