diff options
-rw-r--r-- | includes/database/database.inc | 55 | ||||
-rw-r--r-- | modules/simpletest/tests/database_test.test | 50 |
2 files changed, 105 insertions, 0 deletions
diff --git a/includes/database/database.inc b/includes/database/database.inc index 49402d02b..4c3bf1fb5 100644 --- a/includes/database/database.inc +++ b/includes/database/database.inc @@ -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); } @@ -773,6 +784,32 @@ abstract class Database { } /** + * Add database connection info for a given key/target. + * + * This method allows the addition of new connection credentials at runtime. + * Under normal circumstances the preferred way to specify database credentials + * is via settings.php. However, this method allows them to be added at + * arbitrary times, such as during unit tests, when connecting to admin-defined + * third party databases, etc. + * + * 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. + * Note that the structure of this array will depend on the database driver + * it is connecting to. + */ + 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. * * @param $connection @@ -842,6 +879,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; + } + } /** diff --git a/modules/simpletest/tests/database_test.test b/modules/simpletest/tests/database_test.test index c7b4f69d6..124d18ef1 100644 --- a/modules/simpletest/tests/database_test.test +++ b/modules/simpletest/tests/database_test.test @@ -104,6 +104,56 @@ class DatabaseTestCase extends DrupalWebTestCase { ':priority' => 3, )); } +} + +/** + * Test connection management. + */ +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('Each target refers to a different 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.')); + } } |