From 54655d3a52a7fbeeb59e628acdfa073ad9da525f Mon Sep 17 00:00:00 2001 From: Angie Byron Date: Wed, 15 Dec 2010 06:52:54 +0000 Subject: #977460 by dmitrig01, bfroehle, Josh The Geek: Fixed Cannot serialize or unserialize PDO instances error --- includes/database/database.inc | 34 +++++++++++++++++++++++++++++ includes/database/query.inc | 33 ++++++++++++++++++++++++++++ modules/simpletest/tests/database_test.test | 27 +++++++++++++++++++++++ 3 files changed, 94 insertions(+) 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 @@ -193,6 +193,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. * @@ -469,6 +480,28 @@ abstract class DatabaseConnection extends PDO { return $this->target; } + /** + * 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. * @@ -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 @@ -241,6 +241,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. * @@ -270,9 +284,28 @@ 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. */ 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 @@ -2750,6 +2750,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. */ -- cgit v1.2.3