Merge lp:~davidstrauss/drupal/195416-per-connection-prefixes into lp:~vcs-imports/drupal/old-cvs
- 195416-per-connection-prefixes
- Merge into 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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
VCS imports | Pending | ||
Review via email: mp+13264@code.launchpad.net |
Commit message
Description of the change
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
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 |