summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAngie Byron <webchick@24967.no-reply.drupal.org>2008-09-26 19:10:32 +0000
committerAngie Byron <webchick@24967.no-reply.drupal.org>2008-09-26 19:10:32 +0000
commit40e2b5211621ea73cd1ff27d50c5cc2124f15342 (patch)
tree6d41ff336d8421f6b4047fb719867590216b685a
parentd02d89985a4acc8339c4a134b7a16eab8564bbf9 (diff)
downloadbrdo-40e2b5211621ea73cd1ff27d50c5cc2124f15342.tar.gz
brdo-40e2b5211621ea73cd1ff27d50c5cc2124f15342.tar.bz2
#302300 by Crell: Support adding and ignoring database targets, for better replication support.
-rw-r--r--includes/database/database.inc55
-rw-r--r--modules/simpletest/tests/database_test.test50
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.'));
+ }
}