From 8e3f6eee0ab652e0089e8604ce6e39ae308fdaa6 Mon Sep 17 00:00:00 2001 From: romanb Date: Sun, 8 Nov 2009 11:07:49 +0000 Subject: [PATCH] [2.0][DDC-121] Fixed. Also fixed memcache tests and some small refactorings. --- lib/Doctrine/DBAL/Connection.php | 17 +------- lib/Doctrine/DBAL/Driver/Connection.php | 2 +- lib/Doctrine/DBAL/DriverManager.php | 3 +- lib/Doctrine/ORM/Id/SequenceGenerator.php | 2 +- .../Hydration/SingleScalarHydrator.php | 4 +- lib/Doctrine/ORM/PersistentCollection.php | 17 +++++++- .../Persisters/StandardEntityPersister.php | 5 ++- .../Tests/Common/Cache/MemcacheCacheTest.php | 11 ++++- tests/Doctrine/Tests/Mocks/ConnectionMock.php | 2 +- .../Tests/Mocks/DriverConnectionMock.php | 2 +- .../Functional/AdvancedAssociationTest.php | 2 +- .../ORM/Functional/BasicFunctionalTest.php | 42 +++++++++++++++++++ .../Tests/ORM/Functional/IdentityMapTest.php | 1 + ...ManyToManyBidirectionalAssociationTest.php | 4 +- 14 files changed, 84 insertions(+), 30 deletions(-) diff --git a/lib/Doctrine/DBAL/Connection.php b/lib/Doctrine/DBAL/Connection.php index d4dab2ff9..fb6a31a2e 100644 --- a/lib/Doctrine/DBAL/Connection.php +++ b/lib/Doctrine/DBAL/Connection.php @@ -328,7 +328,7 @@ class Connection } /** - * Convenience method for PDO::query("...") followed by $stmt->fetchAll(PDO::FETCH_COLUMN, ...). + * Convenience method for PDO::query("...") followed by $stmt->fetchColumn(...). * * @param string $statement sql query to be executed * @param array $params prepared statement params @@ -337,7 +337,7 @@ class Connection */ public function fetchColumn($statement, array $params = array(), $colnum = 0) { - return $this->execute($statement, $params)->fetchAll(Connection::FETCH_COLUMN, $colnum); + return $this->execute($statement, $params)->fetchColumn($colnum); } /** @@ -536,19 +536,6 @@ class Connection return $this->execute($sql, $params)->fetchAll(Connection::FETCH_ASSOC); } - /** - * Convenience method for PDO::query("...") followed by $stmt->fetchColumn(). - * - * @param string $statement The SQL query. - * @param array $params The query parameters. - * @param int $colnum 0-indexed column number to retrieve - * @return mixed - */ - public function fetchOne($statement, array $params = array(), $colnum = 0) - { - return $this->execute($statement, $params)->fetchColumn($colnum); - } - /** * Prepares an SQL statement. * diff --git a/lib/Doctrine/DBAL/Driver/Connection.php b/lib/Doctrine/DBAL/Driver/Connection.php index 1a9d431d1..bbda199eb 100644 --- a/lib/Doctrine/DBAL/Driver/Connection.php +++ b/lib/Doctrine/DBAL/Driver/Connection.php @@ -35,7 +35,7 @@ interface Connection function query(); function quote($input); function exec($statement); - function lastInsertId(); + function lastInsertId($name = null); function beginTransaction(); function commit(); function rollBack(); diff --git a/lib/Doctrine/DBAL/DriverManager.php b/lib/Doctrine/DBAL/DriverManager.php index 124a87d11..21a75c10d 100644 --- a/lib/Doctrine/DBAL/DriverManager.php +++ b/lib/Doctrine/DBAL/DriverManager.php @@ -43,7 +43,8 @@ final class DriverManager 'pdo_sqlite' => 'Doctrine\DBAL\Driver\PDOSqlite\Driver', 'pdo_pgsql' => 'Doctrine\DBAL\Driver\PDOPgSql\Driver', 'pdo_oci' => 'Doctrine\DBAL\Driver\PDOOracle\Driver', - 'pdo_mssql' => 'Doctrine\DBAL\Driver\PDOMsSql\Driver' + 'pdo_mssql' => 'Doctrine\DBAL\Driver\PDOMsSql\Driver', + 'oci8' => 'Doctrine\DBAL\Driver\OCI8\Driver' ); /** Private constructor. This class cannot be instantiated. */ diff --git a/lib/Doctrine/ORM/Id/SequenceGenerator.php b/lib/Doctrine/ORM/Id/SequenceGenerator.php index 45e932d52..08927c8bc 100644 --- a/lib/Doctrine/ORM/Id/SequenceGenerator.php +++ b/lib/Doctrine/ORM/Id/SequenceGenerator.php @@ -62,7 +62,7 @@ class SequenceGenerator extends AbstractIdGenerator implements \Serializable // Allocate new values $conn = $em->getConnection(); $sql = $conn->getDatabasePlatform()->getSequenceNextValSql($this->_sequenceName); - $this->_nextValue = $conn->fetchOne($sql); + $this->_nextValue = $conn->fetchColumn($sql); $this->_maxValue = $this->_nextValue + $this->_allocationSize; } return $this->_nextValue++; diff --git a/lib/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php index 39c401b7a..8f76d2ec8 100644 --- a/lib/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php +++ b/lib/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php @@ -36,10 +36,10 @@ class SingleScalarHydrator extends AbstractHydrator $cache = array(); $result = $this->_stmt->fetchAll(Connection::FETCH_ASSOC); //TODO: Let this exception be raised by Query as QueryException - if (count($result) > 1 || count($result[0]) > 1) { + if (count($result) > 1 || count($result[key($result)]) > 1) { throw HydrationException::nonUniqueResult(); } - $result = $this->_gatherScalarRowData($result[0], $cache); + $result = $this->_gatherScalarRowData($result[key($result)], $cache); return array_shift($result); } diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/lib/Doctrine/ORM/PersistentCollection.php index 4a615cd0e..85d6d13da 100644 --- a/lib/Doctrine/ORM/PersistentCollection.php +++ b/lib/Doctrine/ORM/PersistentCollection.php @@ -190,7 +190,7 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect } else { // ManyToMany $this->_typeClass->reflFields[$this->_backRefFieldName] - ->getValue($element)->add($this->_owner); + ->getValue($element)->unwrap()->add($this->_owner); } } } @@ -229,8 +229,18 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect private function _initialize() { if ( ! $this->_initialized) { + if ($this->_isDirty) { + // Has NEW objects added through add(). Remember them. + $newObjects = $this->_coll->toArray(); + } $this->_coll->clear(); $this->_association->load($this->_owner, $this, $this->_em); + // Reattach NEW objects added through add(), if any. + if (isset($newObjects)) { + foreach ($newObjects as $obj) { + $this->_coll->add($obj); + } + } $this->_initialized = true; } } @@ -242,6 +252,7 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect public function takeSnapshot() { $this->_snapshot = $this->_coll->toArray(); + $this->_isDirty = false; } /** @@ -267,7 +278,8 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect } /** - * INTERNAL getInsertDiff + * INTERNAL: + * getInsertDiff * * @return array */ @@ -465,6 +477,7 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect */ public function set($key, $value) { + $this->_initialize(); $this->_coll->set($key, $value); $this->_changed(); } diff --git a/lib/Doctrine/ORM/Persisters/StandardEntityPersister.php b/lib/Doctrine/ORM/Persisters/StandardEntityPersister.php index e04776364..7bfe69e27 100644 --- a/lib/Doctrine/ORM/Persisters/StandardEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/StandardEntityPersister.php @@ -193,7 +193,7 @@ class StandardEntityPersister $sql = "SELECT " . $versionFieldColumnName . " FROM " . $class->getQuotedTableName($this->_platform) . " WHERE " . implode(' = ? AND ', $identifier) . " = ?"; $value = $this->_conn->fetchColumn($sql, (array) $id); - $this->_class->setFieldValue($entity, $versionField, $value[0]); + $this->_class->setFieldValue($entity, $versionField, $value); } /** @@ -550,7 +550,8 @@ class StandardEntityPersister $stmt = $this->_conn->prepare($this->_getSelectManyToManyEntityCollectionSql($assoc, $criteria)); $stmt->execute(array_values($criteria)); while ($result = $stmt->fetch(Connection::FETCH_ASSOC)) { - $coll->add($this->_createEntity($result)); + //$coll->add($this->_createEntity($result)); + $coll->hydrateAdd($this->_createEntity($result)); } $stmt->closeCursor(); } diff --git a/tests/Doctrine/Tests/Common/Cache/MemcacheCacheTest.php b/tests/Doctrine/Tests/Common/Cache/MemcacheCacheTest.php index 996b0baaa..52f44c844 100644 --- a/tests/Doctrine/Tests/Common/Cache/MemcacheCacheTest.php +++ b/tests/Doctrine/Tests/Common/Cache/MemcacheCacheTest.php @@ -8,9 +8,17 @@ require_once __DIR__ . '/../../TestInit.php'; class MemcacheCacheTest extends \Doctrine\Tests\DoctrineTestCase { + private $_memcache; + public function setUp() { - if ( ! extension_loaded('memcache')) { + if (extension_loaded('memcache')) { + $memcache = new \Memcache; + $ok = @$memcache->connect('localhost', 11211); + if (!$ok) { + $this->markTestSkipped('The ' . __CLASS__ .' requires the use of memcache'); + } + } else { $this->markTestSkipped('The ' . __CLASS__ .' requires the use of memcache'); } } @@ -18,6 +26,7 @@ class MemcacheCacheTest extends \Doctrine\Tests\DoctrineTestCase public function testMemcacheCacheDriver() { $cache = new MemcacheCache(); + $cache->setMemcache($this->_memcache); // Test save $cache->save('test_key', 'testing this out'); diff --git a/tests/Doctrine/Tests/Mocks/ConnectionMock.php b/tests/Doctrine/Tests/Mocks/ConnectionMock.php index 87e3d7b7d..41f5ebab0 100644 --- a/tests/Doctrine/Tests/Mocks/ConnectionMock.php +++ b/tests/Doctrine/Tests/Mocks/ConnectionMock.php @@ -43,7 +43,7 @@ class ConnectionMock extends \Doctrine\DBAL\Connection /** * @override */ - public function fetchOne($statement, array $params = array(), $colnum = 0) + public function fetchColumn($statement, array $params = array(), $colnum = 0) { return $this->_fetchOneResult; } diff --git a/tests/Doctrine/Tests/Mocks/DriverConnectionMock.php b/tests/Doctrine/Tests/Mocks/DriverConnectionMock.php index be6df9935..ad9050b2a 100644 --- a/tests/Doctrine/Tests/Mocks/DriverConnectionMock.php +++ b/tests/Doctrine/Tests/Mocks/DriverConnectionMock.php @@ -8,7 +8,7 @@ class DriverConnectionMock implements \Doctrine\DBAL\Driver\Connection public function query() {} public function quote($input) {} public function exec($statement) {} - public function lastInsertId() {} + public function lastInsertId($name = null) {} public function beginTransaction() {} public function commit() {} public function rollBack() {} diff --git a/tests/Doctrine/Tests/ORM/Functional/AdvancedAssociationTest.php b/tests/Doctrine/Tests/ORM/Functional/AdvancedAssociationTest.php index a4bede0d0..a7c9cdc07 100644 --- a/tests/Doctrine/Tests/ORM/Functional/AdvancedAssociationTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/AdvancedAssociationTest.php @@ -94,9 +94,9 @@ class AdvancedAssociationTest extends \Doctrine\Tests\OrmFunctionalTestCase $definitions = $res[0]->getDefinitions(); $this->assertEquals(1, count($res)); + $this->assertTrue($definitions[0] instanceof Definition); $this->assertEquals(2, $definitions->count()); - } public function testManyToMany() diff --git a/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php b/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php index 348f48d99..88c60f903 100644 --- a/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php @@ -380,6 +380,48 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase $gblanco->addPhonenumber($newPhone); $this->assertFalse($gblanco->getPhonenumbers()->isInitialized()); + $this->_em->persist($gblanco); + + $this->_em->flush(); + $this->_em->clear(); + + $query = $this->_em->createQuery("select u, p from Doctrine\Tests\Models\CMS\CmsUser u join u.phonenumbers p where u.username='gblanco'"); + $gblanco2 = $query->getSingleResult(); + $this->assertEquals(4, $gblanco2->getPhonenumbers()->count()); + } + + public function testInitializeCollectionWithNewObjectsRetainsNewObjects() + { + $user = new CmsUser; + $user->name = 'Guilherme'; + $user->username = 'gblanco'; + $user->status = 'developer'; + + for ($i=0; $i<3; ++$i) { + $phone = new CmsPhonenumber; + $phone->phonenumber = 100 + $i; + $user->addPhonenumber($phone); + } + + $this->_em->persist($user); + $this->_em->flush(); + $this->_em->clear(); + + $this->assertEquals(3, $user->getPhonenumbers()->count()); + + $query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username='gblanco'"); + + $gblanco = $query->getSingleResult(); + + $this->assertFalse($gblanco->getPhonenumbers()->isInitialized()); + + $newPhone = new CmsPhonenumber; + $newPhone->phonenumber = 555; + $gblanco->addPhonenumber($newPhone); + + $this->assertFalse($gblanco->getPhonenumbers()->isInitialized()); + $this->assertEquals(4, $gblanco->getPhonenumbers()->count()); + $this->assertTrue($gblanco->getPhonenumbers()->isInitialized()); $this->_em->flush(); $this->_em->clear(); diff --git a/tests/Doctrine/Tests/ORM/Functional/IdentityMapTest.php b/tests/Doctrine/Tests/ORM/Functional/IdentityMapTest.php index 7fe549fdd..ba0c55242 100644 --- a/tests/Doctrine/Tests/ORM/Functional/IdentityMapTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/IdentityMapTest.php @@ -178,6 +178,7 @@ class IdentityMapTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->_em->flush(); $this->assertEquals(3, count($user->getPhonenumbers())); + $this->assertFalse($user->getPhonenumbers()->isDirty()); //external update to CmsAddress $this->_em->getConnection()->executeUpdate('insert into cms_phonenumbers (phonenumber, user_id) VALUES (?,?)', array(999, $user->getId())); diff --git a/tests/Doctrine/Tests/ORM/Functional/ManyToManyBidirectionalAssociationTest.php b/tests/Doctrine/Tests/ORM/Functional/ManyToManyBidirectionalAssociationTest.php index 07d01112a..2b5054b9c 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ManyToManyBidirectionalAssociationTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ManyToManyBidirectionalAssociationTest.php @@ -110,7 +110,6 @@ class ManyToManyBidirectionalAssociationTest extends AbstractManyToManyAssociati $this->assertLoadingOfOwningSide($products); } - private function _createLoadingFixture() { $this->firstProduct->addCategory($this->firstCategory); @@ -140,6 +139,7 @@ class ManyToManyBidirectionalAssociationTest extends AbstractManyToManyAssociati $this->assertEquals(2, count($firstProductCategories)); $this->assertEquals(2, count($secondProductCategories)); + $this->assertTrue($firstProductCategories[0] === $secondProductCategories[0]); $this->assertTrue($firstProductCategories[1] === $secondProductCategories[1]); @@ -148,7 +148,7 @@ class ManyToManyBidirectionalAssociationTest extends AbstractManyToManyAssociati $this->assertEquals(2, count($firstCategoryProducts)); $this->assertEquals(2, count($secondCategoryProducts)); - + $this->assertTrue($firstCategoryProducts[0] instanceof ECommerceProduct); $this->assertTrue($firstCategoryProducts[1] instanceof ECommerceProduct); $this->assertTrue($secondCategoryProducts[0] instanceof ECommerceProduct);