From bcf9ca78e0ed7559a6025e9bf094d62e72043603 Mon Sep 17 00:00:00 2001 From: doctrine Date: Mon, 5 Jun 2006 09:57:53 +0000 Subject: [PATCH] Serialization model rewrite --- Doctrine/Collection.php | 47 +++++++++++++++++++++++- Doctrine/Record.php | 65 +++++++++++++++++++--------------- Doctrine/Session.php | 7 ++-- tests/QueryTestCase.class.php | 4 +-- tests/RecordTestCase.class.php | 10 +++--- 5 files changed, 93 insertions(+), 40 deletions(-) diff --git a/Doctrine/Collection.php b/Doctrine/Collection.php index 838d35a5f..67213640f 100644 --- a/Doctrine/Collection.php +++ b/Doctrine/Collection.php @@ -8,7 +8,7 @@ require_once("Access.php"); * @url www.phpdoctrine.com * @license LGPL */ -class Doctrine_Collection extends Doctrine_Access implements Countable, IteratorAggregate { +class Doctrine_Collection extends Doctrine_Access implements Countable, IteratorAggregate, Serializable { /** * @var array $data an array containing the data access objects of this collection */ @@ -69,6 +69,51 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator public function getTable() { return $this->table; } + /** + * this method is automatically called when this Doctrine_Collection is serialized + * + * @return array + */ + public function serialize() { + $vars = get_object_vars($this); + + unset($vars['reference']); + unset($vars['reference_field']); + unset($vars['relation']); + unset($vars['expandable']); + unset($vars['expanded']); + unset($vars['generator']); + + $vars['table'] = $vars['table']->getComponentName(); + + return serialize($vars); + } + /** + * unseralize + * this method is automatically called everytime a Doctrine_Collection object is unserialized + * + * @return void + */ + public function unserialize($serialized) { + $manager = Doctrine_Manager::getInstance(); + $session = $manager->getCurrentSession(); + + $array = unserialize($serialized); + + foreach($array as $name => $values) { + $this->$name = $values; + } + + $this->table = $session->getTable($this->table->getComponenName()); + + $this->expanded = array(); + $this->expandable = true; + + $name = $table->getAttribute(Doctrine::ATTR_COLL_KEY); + if($name !== null) { + $this->generator = new Doctrine_IndexGenerator($name); + } + } /** * whether or not an offset batch has been expanded * @return boolean diff --git a/Doctrine/Record.php b/Doctrine/Record.php index 42e1de99c..bdbc932e5 100644 --- a/Doctrine/Record.php +++ b/Doctrine/Record.php @@ -3,7 +3,7 @@ require_once("Access.php"); /** * Doctrine_Record */ -abstract class Doctrine_Record extends Doctrine_Access implements Countable, IteratorAggregate { +abstract class Doctrine_Record extends Doctrine_Access implements Countable, IteratorAggregate, Serializable { /** * STATE CONSTANTS */ @@ -247,10 +247,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite $name = $this->table->getIdentifier(); if($exists) { - if(isset($this->data[$name])) + if(isset($this->data[$name]) && $this->data[$name] !== self::$null) $this->id = $this->data[$name]; } - + unset($this->data[$name]); break; @@ -272,21 +272,24 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite * * @return array */ - public function __sleep() { + public function serialize() { $this->table->getAttribute(Doctrine::ATTR_LISTENER)->onSleep($this); + $vars = get_object_vars($this); + + unset($vars['references']); + unset($vars['collections']); + unset($vars['originals']); + unset($vars['table']); - // unset all vars that won't need to be serialized - - unset($this->associations); - unset($this->collections); - unset($this->references); - unset($this->originals); - unset($this->oid); + if( ! is_array($this->id)) { + $name = $this->table->getIdentifier(); + $this->data = array_merge($this->data, array($name => $this->id)); + } foreach($this->data as $k => $v) { if($v instanceof Doctrine_Record) - $this->data[$k] = array(); + unset($this->data[$k]); elseif($v === self::$null) { unset($this->data[$k]); } else { @@ -298,11 +301,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite endswitch; } } - - $this->table = $this->table->getComponentName(); - - return array_keys(get_object_vars($this)); + return serialize($vars); } /** * unseralize @@ -310,17 +310,21 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite * * @return void */ - public function __wakeup() { - $name = $this->table; - + public function unserialize($serialized) { $manager = Doctrine_Manager::getInstance(); - $sess = $manager->getCurrentSession(); + $session = $manager->getCurrentSession(); $this->oid = self::$index; - self::$index++; - $this->table = $sess->getTable($name); + $this->table = $session->getTable(get_class($this)); + + + $array = unserialize($serialized); + + foreach($array as $name => $values) { + $this->$name = $values; + } $this->table->getRepository()->add($this); @@ -336,6 +340,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite $this->table->getAttribute(Doctrine::ATTR_LISTENER)->onWakeUp($this); } + + /** * addCollection * @param Doctrine_Collection $collection @@ -494,9 +500,9 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite return $this->data[$name]; } - if($name == $this->table->getIdentifier()) { + if($name === $this->table->getIdentifier()) return $this->id; - } + if( ! isset($this->references[$name])) $this->loadReference($name); @@ -579,7 +585,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite $fk = $this->table->getForeignKey($name); // one-to-many or one-to-one relation - if($fk instanceof Doctrine_ForeignKey || + if($fk instanceof Doctrine_ForeignKey || $fk instanceof Doctrine_LocalKey) { switch($fk->getType()): case Doctrine_Relation::MANY_COMPOSITE: @@ -702,7 +708,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite $type = $this->table->getTypeOf($v); if($type == 'array' || - $type == 'object') { + $type == 'object') { $a[$v] = serialize($this->data[$v]); continue; @@ -905,9 +911,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite $this->state = Doctrine_Record::STATE_CLEAN; $this->modified = array(); } else { - $this->id = $id; - $this->state = Doctrine_Record::STATE_CLEAN; - $this->modified = array(); + $name = $this->table->getIdentifier(); + $this->id = $id; + $this->state = Doctrine_Record::STATE_CLEAN; + $this->modified = array(); } } /** diff --git a/Doctrine/Session.php b/Doctrine/Session.php index 8b02049ba..2eb78e5e0 100644 --- a/Doctrine/Session.php +++ b/Doctrine/Session.php @@ -77,12 +77,11 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab * @param PDO $pdo -- database handle */ public function __construct(Doctrine_Manager $manager,PDO $pdo) { - $this->dbh = $pdo; - - $this->setParent($manager); - + $this->dbh = $pdo; $this->state = Doctrine_Session::STATE_OPEN; + $this->setParent($manager); + $this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER); $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); diff --git a/tests/QueryTestCase.class.php b/tests/QueryTestCase.class.php index 59419823c..304d60c99 100644 --- a/tests/QueryTestCase.class.php +++ b/tests/QueryTestCase.class.php @@ -14,7 +14,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { $this->dbh->query("DROP TABLE IF EXISTS test_entries"); parent::prepareTables(); } - public function testOneToOneRelationFetching2() { + public function testOneToOneSharedRelations() { $status = new Log_Status(); $status->name = 'success'; @@ -45,7 +45,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { $this->assertEqual($entries[0]->Log_Status->name, 'success'); // the second Log_Status is fetched from identityMap - + $this->assertTrue($entries[1]->Log_Status instanceof Log_Status); $this->assertEqual($entries[1]->Log_Status->name, 'success'); diff --git a/tests/RecordTestCase.class.php b/tests/RecordTestCase.class.php index 0b338f2d2..588e6f9a4 100644 --- a/tests/RecordTestCase.class.php +++ b/tests/RecordTestCase.class.php @@ -3,10 +3,12 @@ require_once("UnitTestCase.class.php"); class Doctrine_RecordTestCase extends Doctrine_UnitTestCase { public function testSerialize() { - //$user = $this->session->getTable("User")->find(4); - //$str = serialize($user); - //$user2 = unserialize($str); - //$this->assertEqual($user2->getID(),$user->getID()); + $user = $this->session->getTable("User")->find(4); + $str = serialize($user); + $user2 = unserialize($str); + + $this->assertTrue($user2 instanceof User); + $this->assertEqual($user2->getID(),$user->getID()); } public function testCallback() {