Index: includes/database/database.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database/database.inc,v retrieving revision 1.2 diff -u -p -r1.2 database.inc --- includes/database/database.inc 31 Aug 2008 09:12:35 -0000 1.2 +++ includes/database/database.inc 31 Aug 2008 15:10:29 -0000 @@ -666,6 +666,13 @@ abstract class Database { static protected $databaseInfo = NULL; /** + * A list of key/target credentials to simply ignore. + * + * @var array + */ + static protected $ignoreTargets = array(); + + /** * The key of the currently active database connection. * * @var string @@ -695,6 +702,10 @@ abstract class Database { * The corresponding connection object. */ final public static function getConnection($key = 'default', $target = 'default') { + if (!empty(self::$ignoreTargets[$key][$target])) { + $target = 'default'; + } + if (!isset(self::$connections[$key][$target])) { self::openConnection($key, $target); } @@ -771,6 +782,24 @@ abstract class Database { self::$databaseInfo = $databaseInfo; } + + /** + * Add database connection info for a given key/target. + * + * If the given key/target pair already exists, this method will be ignored. + * + * @param $key + * The database key. + * @param $target + * The database target name. + * @param $info + * The database connection information, as it would be defined in settings.php. + */ + public static function addConnectionInfo($key, $target, $info) { + if (empty(self::$databaseInfo[$key][$target])) { + self::$databaseInfo[$key][$target] = $info; + } + } /** * Gets information on the specified database connection. @@ -843,6 +872,24 @@ abstract class Database { throw $e; } } + + /** + * Instruct the system to temporarily ignore a given key/target. + * + * At times we need to temporarily disable slave queries. To do so, + * call this method with the database key and the target to disable. + * That database key will then always fall back to 'default' for that + * key, even if it's defined. + * + * @param $key + * The database connection key. + * @param $target + * The target of the specified key to ignore. + */ + public static function ignoreTarget($key, $target) { + self::$ignoreTargets[$key][$target] = TRUE; + } + } /** Index: modules/simpletest/tests/database_test.test =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/tests/database_test.test,v retrieving revision 1.1 diff -u -p -r1.1 database_test.test --- modules/simpletest/tests/database_test.test 31 Aug 2008 11:43:41 -0000 1.1 +++ modules/simpletest/tests/database_test.test 31 Aug 2008 15:10:29 -0000 @@ -104,7 +104,59 @@ class DatabaseTestCase extends DrupalWeb ':priority' => 3, )); } +} + +/** + * Test fetch actions, part 1. + * + * We get timeout errors if we try to run too many tests at once. + */ +class DatabaseConnectionTestCase extends DatabaseTestCase { + + function getInfo() { + return array( + 'name' => t('Connection tests'), + 'description' => t('Tests of the core database system.'), + 'group' => t('Database'), + ); + } + + /** + * Test that connections return appropriate connection objects. + */ + function testConnectionRouting() { + + // Clone the master credentials to a slave connection. + // Note this will result in two independent connection objects that happen + // to point to the same place. + $connection_info = Database::getConnectionInfo(); + Database::addConnectionInfo('default', 'slave', $connection_info['default']['default']); + + $db1 = Database::getConnection('default', 'default'); + $db2 = Database::getConnection('default', 'slave'); + + $this->assertFalse($db1 === $db2, t('Both targets refer to the same connection.')); + } + + /** + * Test that connections return appropriate connection objects. + */ + function testConnectionRoutingOverride() { + // Clone the master credentials to a slave connection. + // Note this will result in two independent connection objects that happen + // to point to the same place. + $connection_info = Database::getConnectionInfo('default'); + Database::addConnectionInfo('default', 'slave', $connection_info['default']); + + Database::ignoreTarget('default', 'slave'); + + $db1 = Database::getConnection('default', 'default'); + $db2 = Database::getConnection('default', 'slave'); + + $this->assertTrue($db1 === $db2, t('Both targets refer to the same connection.')); + } + } /**