summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/database/database.inc34
-rw-r--r--includes/database/query.inc33
-rw-r--r--modules/simpletest/tests/database_test.test27
3 files changed, 94 insertions, 0 deletions
diff --git a/includes/database/database.inc b/includes/database/database.inc
index 94517f002..8d6abb844 100644
--- a/includes/database/database.inc
+++ b/includes/database/database.inc
@@ -194,6 +194,17 @@ abstract class DatabaseConnection extends PDO {
protected $target = NULL;
/**
+ * The key representing this connection.
+ *
+ * The key is a unique string which identifies a database connection. A
+ * connection can be a single server or a cluster of master and slaves (use
+ * target to pick between master and slave).
+ *
+ * @var string
+ */
+ protected $key = NULL;
+
+ /**
* The current database logging object for this connection.
*
* @var DatabaseLog
@@ -470,6 +481,28 @@ abstract class DatabaseConnection extends PDO {
}
/**
+ * Tells this connection object what its key is.
+ *
+ * @param $target
+ * The key this connection is for.
+ */
+ public function setKey($key) {
+ if (!isset($this->key)) {
+ $this->key = $key;
+ }
+ }
+
+ /**
+ * Returns the key this connection is associated with.
+ *
+ * @return
+ * The key of this connection.
+ */
+ public function getKey() {
+ return $this->key;
+ }
+
+ /**
* Associates a logging object with this connection.
*
* @param $logger
@@ -1539,6 +1572,7 @@ abstract class Database {
require_once DRUPAL_ROOT . '/includes/database/' . $driver . '/database.inc';
$new_connection = new $driver_class(self::$databaseInfo[$key][$target]);
$new_connection->setTarget($target);
+ $new_connection->setKey($key);
// If we have any active logging objects for this connection key, we need
// to associate them with the connection we just opened.
diff --git a/includes/database/query.inc b/includes/database/query.inc
index d7e688eb5..7c590c220 100644
--- a/includes/database/query.inc
+++ b/includes/database/query.inc
@@ -242,6 +242,20 @@ abstract class Query implements QueryPlaceholderInterface {
protected $connection;
/**
+ * The target of the connection object.
+ *
+ * @var string
+ */
+ protected $connectionTarget;
+
+ /**
+ * The key of the connection object.
+ *
+ * @var string
+ */
+ protected $connectionKey;
+
+ /**
* The query options to pass on to the connection object.
*
* @var array
@@ -270,10 +284,29 @@ abstract class Query implements QueryPlaceholderInterface {
*/
public function __construct(DatabaseConnection $connection, $options) {
$this->connection = $connection;
+ $this->connectionKey = $this->connection->getKey();
+ $this->connectionTarget = $this->connection->getTarget();
+
$this->queryOptions = $options;
}
/**
+ * Implements the magic __sleep function to disconnect from the database.
+ */
+ public function __sleep() {
+ $keys = get_object_vars($this);
+ unset($keys['connection']);
+ return array_keys($keys);
+ }
+
+ /**
+ * Implements the magic __wakeup function to reconnect to the database.
+ */
+ public function __wakeup() {
+ $this->connection = Database::getConnection($this->connectionTarget, $this->connectionKey);
+ }
+
+ /**
* Runs the query against the database.
*/
abstract protected function execute();
diff --git a/modules/simpletest/tests/database_test.test b/modules/simpletest/tests/database_test.test
index f34afafab..b80f55231 100644
--- a/modules/simpletest/tests/database_test.test
+++ b/modules/simpletest/tests/database_test.test
@@ -2751,6 +2751,33 @@ class DatabaseLoggingTestCase extends DatabaseTestCase {
}
/**
+ * Query serialization tests.
+ */
+class DatabaseSerializeQueryTestCase extends DatabaseTestCase {
+ public static function getInfo() {
+ return array(
+ 'name' => 'Serialize query',
+ 'description' => 'Test serializing and unserializing a query.',
+ 'group' => 'Database',
+ );
+ }
+
+ /**
+ * Confirm that a query can be serialized and unserialized.
+ */
+ function testSerializeQuery() {
+ $query = db_select('test');
+ $query->addField('test', 'age');
+ $query->condition('name', 'Ringo');
+ // If this doesn't work, it will throw an exception, so no need for an
+ // assertion.
+ $query = unserialize(serialize($query));
+ $results = $query->execute()->fetchCol();
+ $this->assertEqual($results[0], 28, t('Query properly executed after unserialization.'));
+ }
+}
+
+/**
* Range query tests.
*/
class DatabaseRangeQueryTestCase extends DrupalWebTestCase {