From f60f2a567ae1ec4ae7e199b6e90aa1c37217f4f3 Mon Sep 17 00:00:00 2001 From: "Jasper N. Brouwer" Date: Sun, 9 Nov 2014 15:59:05 +0100 Subject: [PATCH] Fixed associations using a value-conversion type for identifiers --- .../Collection/ManyToManyPersister.php | 18 +- .../Entity/BasicEntityPersister.php | 145 ++++++++++++--- tests/Doctrine/Tests/DbalTypes/Rot13Type.php | 81 +++++++++ .../ValueConversionType/AuxiliaryEntity.php | 16 ++ .../InversedManyToManyCompositeIdEntity.php | 34 ++++ ...dManyToManyCompositeIdForeignKeyEntity.php | 35 ++++ .../InversedManyToManyEntity.php | 28 +++ .../InversedOneToManyCompositeIdEntity.php | 39 ++++ ...edOneToManyCompositeIdForeignKeyEntity.php | 40 +++++ .../InversedOneToManyEntity.php | 33 ++++ .../InversedOneToOneCompositeIdEntity.php | 32 ++++ ...sedOneToOneCompositeIdForeignKeyEntity.php | 33 ++++ .../InversedOneToOneEntity.php | 26 +++ .../OwningManyToManyCompositeIdEntity.php | 36 ++++ ...gManyToManyCompositeIdForeignKeyEntity.php | 36 ++++ .../OwningManyToManyEntity.php | 33 ++++ .../OwningManyToOneCompositeIdEntity.php | 25 +++ ...ngManyToOneCompositeIdForeignKeyEntity.php | 25 +++ .../OwningManyToOneEntity.php | 22 +++ .../OwningOneToOneCompositeIdEntity.php | 25 +++ ...ingOneToOneCompositeIdForeignKeyEntity.php | 30 ++++ .../OwningOneToOneEntity.php | 22 +++ .../ORM/Functional/SchemaValidatorTest.php | 11 ++ .../ManyToManyCompositeIdForeignKeyTest.php | 168 ++++++++++++++++++ .../ManyToManyCompositeIdTest.php | 162 +++++++++++++++++ .../ValueConversionType/ManyToManyTest.php | 158 ++++++++++++++++ .../OneToManyCompositeIdForeignKeyTest.php | 140 +++++++++++++++ .../OneToManyCompositeIdTest.php | 134 ++++++++++++++ .../ValueConversionType/OneToManyTest.php | 130 ++++++++++++++ .../OneToOneCompositeIdForeignKeyTest.php | 140 +++++++++++++++ .../OneToOneCompositeIdTest.php | 134 ++++++++++++++ .../ValueConversionType/OneToOneTest.php | 130 ++++++++++++++ .../Doctrine/Tests/OrmFunctionalTestCase.php | 90 ++++++++++ 33 files changed, 2179 insertions(+), 32 deletions(-) create mode 100644 tests/Doctrine/Tests/DbalTypes/Rot13Type.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/AuxiliaryEntity.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/InversedManyToManyCompositeIdEntity.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/InversedManyToManyCompositeIdForeignKeyEntity.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/InversedManyToManyEntity.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyCompositeIdEntity.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyCompositeIdForeignKeyEntity.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyEntity.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToOneCompositeIdEntity.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToOneCompositeIdForeignKeyEntity.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToOneEntity.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToManyCompositeIdEntity.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToManyCompositeIdForeignKeyEntity.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToManyEntity.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToOneCompositeIdEntity.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToOneCompositeIdForeignKeyEntity.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToOneEntity.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/OwningOneToOneCompositeIdEntity.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/OwningOneToOneCompositeIdForeignKeyEntity.php create mode 100644 tests/Doctrine/Tests/Models/ValueConversionType/OwningOneToOneEntity.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/ValueConversionType/ManyToManyCompositeIdForeignKeyTest.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/ValueConversionType/ManyToManyCompositeIdTest.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/ValueConversionType/ManyToManyTest.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyCompositeIdForeignKeyTest.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyCompositeIdTest.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyTest.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToOneCompositeIdForeignKeyTest.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToOneCompositeIdTest.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToOneTest.php diff --git a/lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php b/lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php index 40b1be958..3a09079c7 100644 --- a/lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php +++ b/lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php @@ -374,22 +374,20 @@ class ManyToManyPersister extends AbstractCollectionPersister $mapping = $collection->getMapping(); $identifier = $this->uow->getEntityIdentifier($collection->getOwner()); - // Optimization for single column identifier - if (count($mapping['relationToSourceKeyColumns']) === 1) { - return array(reset($identifier)); - } - - // Composite identifier $sourceClass = $this->em->getClassMetadata($mapping['sourceEntity']); $params = array(); + $types = array(); foreach ($mapping['relationToSourceKeyColumns'] as $columnName => $refColumnName) { - $params[] = isset($sourceClass->fieldNames[$refColumnName]) - ? $identifier[$sourceClass->fieldNames[$refColumnName]] - : $identifier[$sourceClass->getFieldForColumn($columnName)]; + $field = isset($sourceClass->fieldNames[$refColumnName]) + ? $sourceClass->fieldNames[$refColumnName] + : $sourceClass->getFieldForColumn($columnName); + + $params[] = $identifier[$field]; + $types[] = $this->getType($field, $sourceClass); } - return $params; + return array($params, $types); } /** diff --git a/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php index 537961420..1be3ecd5b 100644 --- a/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php @@ -710,6 +710,7 @@ class BasicEntityPersister implements EntityPersister { $sql = $this->getSelectSQL($criteria, $assoc, $lockMode, $limit, null, $orderBy); list($params, $types) = $this->expandParameters($criteria); + $stmt = $this->conn->executeQuery($sql, $params, $types); if ($entity !== null) { @@ -965,11 +966,12 @@ class BasicEntityPersister implements EntityPersister */ private function getManyToManyStatement(array $assoc, $sourceEntity, $offset = null, $limit = null) { - $sourceClass = $this->em->getClassMetadata($assoc['sourceEntity']); - $class = $sourceClass; - $association = $assoc; - $criteria = array(); + $criteria = array(); + $parameters = array(); + $sourceClass = $this->em->getClassMetadata($assoc['sourceEntity']); + $class = $sourceClass; + $association = $assoc; if ( ! $assoc['isOwningSide']) { $class = $this->em->getClassMetadata($assoc['targetEntity']); @@ -984,8 +986,8 @@ class BasicEntityPersister implements EntityPersister foreach ($joinColumns as $joinColumn) { - $sourceKeyColumn = $joinColumn['referencedColumnName']; - $quotedKeyColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform); + $sourceKeyColumn = $joinColumn['referencedColumnName']; + $quotedKeyColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform); switch (true) { case $sourceClass->containsForeignIdentifier: @@ -1012,10 +1014,11 @@ class BasicEntityPersister implements EntityPersister } $criteria[$quotedJoinTable . '.' . $quotedKeyColumn] = $value; + $parameters[] = array('value' => $value, 'field' => $field, 'class' => $sourceClass); } $sql = $this->getSelectSQL($criteria, $assoc, null, $limit, $offset); - list($params, $types) = $this->expandParameters($criteria); + list($params, $types) = $this->expandToManyParameters($parameters); return $this->conn->executeQuery($sql, $params, $types); } @@ -1303,17 +1306,13 @@ class BasicEntityPersister implements EntityPersister $targetClass = $this->em->getClassMetadata($assoc['targetEntity']); foreach ($assoc['joinColumns'] as $joinColumn) { - $type = null; + $type = $this->getColumnType($joinColumn['referencedColumnName'], null, $targetClass); $isIdentifier = isset($assoc['id']) && $assoc['id'] === true; $quotedColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $this->class, $this->platform); $resultColumnName = $this->getSQLColumnAlias($joinColumn['name']); $columnList[] = $this->getSQLTableAlias($class->name, ($alias == 'r' ? '' : $alias) ) . '.' . $quotedColumn . ' AS ' . $resultColumnName; - if (isset($targetClass->fieldNames[$joinColumn['referencedColumnName']])) { - $type = $targetClass->fieldMappings[$targetClass->fieldNames[$joinColumn['referencedColumnName']]]['type']; - } - $this->rsm->addMetaResult($alias, $resultColumnName, $quotedColumn, $isIdentifier, $type); } @@ -1713,7 +1712,9 @@ class BasicEntityPersister implements EntityPersister */ private function getOneToManyStatement(array $assoc, $sourceEntity, $offset = null, $limit = null) { - $criteria = array(); + $criteria = array(); + $parameters = array(); + $owningAssoc = $this->class->associationMappings[$assoc['mappedBy']]; $sourceClass = $this->em->getClassMetadata($assoc['sourceEntity']); @@ -1730,15 +1731,20 @@ class BasicEntityPersister implements EntityPersister } $criteria[$tableAlias . "." . $targetKeyColumn] = $value; + $parameters[] = array('value' => $value, 'field' => $field, 'class' => $sourceClass); continue; } - $criteria[$tableAlias . "." . $targetKeyColumn] = $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity); + $field = $sourceClass->fieldNames[$sourceKeyColumn]; + $value = $sourceClass->reflFields[$field]->getValue($sourceEntity); + + $criteria[$tableAlias . "." . $targetKeyColumn] = $value; + $parameters[] = array('value' => $value, 'field' => $field, 'class' => $sourceClass); } $sql = $this->getSelectSQL($criteria, $assoc, null, $limit, $offset); - list($params, $types) = $this->expandParameters($criteria); + list($params, $types) = $this->expandToManyParameters($parameters); return $this->conn->executeQuery($sql, $params, $types); } @@ -1764,17 +1770,51 @@ class BasicEntityPersister implements EntityPersister } /** - * Infers field type to be used by parameter type casting. + * Expands the parameters from the given criteria and use the correct binding types if found, + * specialized for OneToMany or ManyToMany associations. * - * @param string $field - * @param mixed $value + * DDC-3380: {@see getManyToManyStatement()} and {@see getOneToManyStatement()}. * - * @return integer + * @param array $criteria + * + * @return array + */ + private function expandToManyParameters($criteria) + { + $params = array(); + $types = array(); + + foreach ($criteria as $criterion) { + if ($criterion['value'] === null) { + continue; // skip null values. + } + + $types[] = $this->getType($criterion['field'], $criterion['value'], $criterion['class']); + $params[] = $this->getValue($criterion['value']); + } + + return array($params, $types); + } + + /** + * Infers the binding type of a field by parameter type casting. + * + * DDC-3380: Added optional $class argument. + * + * @param string $field + * @param mixed $value + * @param ClassMetadata|null $class + * + * @return int|string|null * * @throws \Doctrine\ORM\Query\QueryException */ - private function getType($field, $value) + private function getType($field, $value, ClassMetadata $class = null) { + if ($class === null) { + $class = $this->class; + } + switch (true) { case (isset($this->class->fieldMappings[$field])): $type = $this->class->fieldMappings[$field]['type']; @@ -1802,8 +1842,8 @@ class BasicEntityPersister implements EntityPersister break; - case (isset($this->class->associationMappings[$field])): - $assoc = $this->class->associationMappings[$field]; + case (isset($class->associationMappings[$field])): + $assoc = $class->associationMappings[$field]; if (count($assoc['sourceToTargetKeyColumns']) > 1) { throw Query\QueryException::associationPathCompositeKeyNotSupported(); @@ -1831,6 +1871,67 @@ class BasicEntityPersister implements EntityPersister return $type; } + /** + * Infers the binding type of a column by parameter type casting. + * + * @param string $columnName + * @param mixed $value + * @param ClassMetadata $class + * @return int|string|null + */ + private function getColumnType($columnName, $value, ClassMetadata $class) + { + $type = null; + + switch (true) { + case (isset($class->fieldNames[$columnName])): + $fieldName = $class->fieldNames[$columnName]; + + if (isset($class->fieldMappings[$fieldName])) { + $type = $class->fieldMappings[$fieldName]['type']; + } + + break; + + default: + $type = $this->getAssociationColumnType($columnName, $class); + } + + if (is_array($value)) { + $type = Type::getType($type)->getBindingType(); + $type += Connection::ARRAY_PARAM_OFFSET; + } + + return $type; + } + + /** + * Infers the binding type of a column by traversing association mappings. + * + * @param string $columnName + * @param ClassMetadata $class + * @return string|null + */ + private function getAssociationColumnType($columnName, ClassMetadata $class) + { + foreach ($class->associationMappings as $assoc) { + foreach ($assoc['joinColumns'] as $joinColumn) { + if ($joinColumn['name'] == $columnName) { + $targetClass = $this->em->getClassMetadata($assoc['targetEntity']); + $targetColumn = $joinColumn['referencedColumnName']; + + if (isset($targetClass->fieldNames[$targetColumn])) { + return $targetClass->fieldMappings[$targetClass->fieldNames[$targetColumn]]['type']; + } + + return $this->getAssociationColumnType($targetColumn, $class); + } + } + } + + return null; + } + /** * Retrieves parameter value. * diff --git a/tests/Doctrine/Tests/DbalTypes/Rot13Type.php b/tests/Doctrine/Tests/DbalTypes/Rot13Type.php new file mode 100644 index 000000000..6403b9ebe --- /dev/null +++ b/tests/Doctrine/Tests/DbalTypes/Rot13Type.php @@ -0,0 +1,81 @@ +getVarcharTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + * + * @param AbstractPlatform $platform + * + * @return int|null + */ + public function getDefaultLength(AbstractPlatform $platform) + { + return $platform->getVarcharDefaultLength(); + } + + /** + * {@inheritdoc} + * + * @return string + */ + public function getName() + { + return 'rot13'; + } +} diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/AuxiliaryEntity.php b/tests/Doctrine/Tests/Models/ValueConversionType/AuxiliaryEntity.php new file mode 100644 index 000000000..d37413909 --- /dev/null +++ b/tests/Doctrine/Tests/Models/ValueConversionType/AuxiliaryEntity.php @@ -0,0 +1,16 @@ +associatedEntities = new ArrayCollection(); + } +} diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/InversedManyToManyCompositeIdForeignKeyEntity.php b/tests/Doctrine/Tests/Models/ValueConversionType/InversedManyToManyCompositeIdForeignKeyEntity.php new file mode 100644 index 000000000..b53f559f9 --- /dev/null +++ b/tests/Doctrine/Tests/Models/ValueConversionType/InversedManyToManyCompositeIdForeignKeyEntity.php @@ -0,0 +1,35 @@ +associatedEntities = new ArrayCollection(); + } +} diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/InversedManyToManyEntity.php b/tests/Doctrine/Tests/Models/ValueConversionType/InversedManyToManyEntity.php new file mode 100644 index 000000000..c2cab841c --- /dev/null +++ b/tests/Doctrine/Tests/Models/ValueConversionType/InversedManyToManyEntity.php @@ -0,0 +1,28 @@ +associatedEntities = new ArrayCollection(); + } +} diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyCompositeIdEntity.php b/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyCompositeIdEntity.php new file mode 100644 index 000000000..01892c1aa --- /dev/null +++ b/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyCompositeIdEntity.php @@ -0,0 +1,39 @@ +associatedEntities = new ArrayCollection(); + } +} diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyCompositeIdForeignKeyEntity.php b/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyCompositeIdForeignKeyEntity.php new file mode 100644 index 000000000..571ce8378 --- /dev/null +++ b/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyCompositeIdForeignKeyEntity.php @@ -0,0 +1,40 @@ +associatedEntities = new ArrayCollection(); + } +} diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyEntity.php b/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyEntity.php new file mode 100644 index 000000000..8da0b10b9 --- /dev/null +++ b/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyEntity.php @@ -0,0 +1,33 @@ +associatedEntities = new ArrayCollection(); + } +} diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToOneCompositeIdEntity.php b/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToOneCompositeIdEntity.php new file mode 100644 index 000000000..631b22b8b --- /dev/null +++ b/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToOneCompositeIdEntity.php @@ -0,0 +1,32 @@ +associatedEntities = new ArrayCollection(); + } +} diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToManyCompositeIdForeignKeyEntity.php b/tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToManyCompositeIdForeignKeyEntity.php new file mode 100644 index 000000000..21e35b79a --- /dev/null +++ b/tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToManyCompositeIdForeignKeyEntity.php @@ -0,0 +1,36 @@ +associatedEntities = new ArrayCollection(); + } +} diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToManyEntity.php b/tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToManyEntity.php new file mode 100644 index 000000000..b05c87874 --- /dev/null +++ b/tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToManyEntity.php @@ -0,0 +1,33 @@ +associatedEntities = new ArrayCollection(); + } +} diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToOneCompositeIdEntity.php b/tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToOneCompositeIdEntity.php new file mode 100644 index 000000000..d8f8a2bab --- /dev/null +++ b/tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToOneCompositeIdEntity.php @@ -0,0 +1,25 @@ +useModelSet('vct_manytomany_compositeid_foreignkey'); + parent::setUp(); + + $auxiliary = new Entity\AuxiliaryEntity(); + $auxiliary->id = 'abc'; + + $inversed = new Entity\InversedManyToManyCompositeIdForeignKeyEntity(); + $inversed->id = 'def'; + $inversed->foreignEntity = $auxiliary; + + $owning = new Entity\OwningManyToManyCompositeIdForeignKeyEntity(); + $owning->id = 'ghi'; + + $inversed->associatedEntities->add($owning); + $owning->associatedEntities->add($inversed); + + $this->_em->persist($auxiliary); + $this->_em->persist($inversed); + $this->_em->persist($owning); + + $this->_em->flush(); + $this->_em->clear(); + } + + public static function tearDownAfterClass() + { + $conn = static::$_sharedConn; + + $conn->executeUpdate('DROP TABLE vct_xref_manytomany_compositeid_foreignkey'); + $conn->executeUpdate('DROP TABLE vct_owning_manytomany_compositeid_foreignkey'); + $conn->executeUpdate('DROP TABLE vct_inversed_manytomany_compositeid_foreignkey'); + $conn->executeUpdate('DROP TABLE vct_auxiliary'); + } + + public function testThatTheValueOfIdentifiersAreConvertedInTheDatabase() + { + $conn = $this->_em->getConnection(); + + $this->assertEquals('qrs', $conn->fetchColumn('SELECT id FROM vct_inversed_manytomany_compositeid_foreignkey LIMIT 1')); + $this->assertEquals('nop', $conn->fetchColumn('SELECT foreign_id FROM vct_inversed_manytomany_compositeid_foreignkey LIMIT 1')); + + $this->assertEquals('tuv', $conn->fetchColumn('SELECT id FROM vct_owning_manytomany_compositeid_foreignkey LIMIT 1')); + + $this->assertEquals('qrs', $conn->fetchColumn('SELECT associated_id FROM vct_xref_manytomany_compositeid_foreignkey LIMIT 1')); + $this->assertEquals('nop', $conn->fetchColumn('SELECT associated_foreign_id FROM vct_xref_manytomany_compositeid_foreignkey LIMIT 1')); + $this->assertEquals('tuv', $conn->fetchColumn('SELECT owning_id FROM vct_xref_manytomany_compositeid_foreignkey LIMIT 1')); + } + + /** + * @depends testThatTheValueOfIdentifiersAreConvertedInTheDatabase + */ + public function testThatEntitiesAreFetchedFromTheDatabase() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdForeignKeyEntity', + array('id' => 'def', 'foreignEntity' => 'abc') + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdForeignKeyEntity', + 'ghi' + ); + + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdForeignKeyEntity', $inversed); + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdForeignKeyEntity', $owning); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdForeignKeyEntity', + array('id' => 'def', 'foreignEntity' => 'abc') + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdForeignKeyEntity', + 'ghi' + ); + + $this->assertEquals('def', $inversed->id); + $this->assertEquals('abc', $inversed->foreignEntity->id); + $this->assertEquals('ghi', $owning->id); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheCollectionFromOwningToInversedIsLoaded() + { + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdForeignKeyEntity', + 'ghi' + ); + + $this->assertCount(1, $owning->associatedEntities); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheCollectionFromInversedToOwningIsLoaded() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdForeignKeyEntity', + array('id' => 'def', 'foreignEntity' => 'abc') + ); + + $this->assertCount(1, $inversed->associatedEntities); + } + + /** + * @depends testThatTheCollectionFromOwningToInversedIsLoaded + * @depends testThatTheCollectionFromInversedToOwningIsLoaded + */ + public function testThatTheJoinTableRowsAreRemovedWhenRemovingTheAssociation() + { + $conn = $this->_em->getConnection(); + + // remove association + + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdForeignKeyEntity', + array('id' => 'def', 'foreignEntity' => 'abc') + ); + + foreach ($inversed->associatedEntities as $owning) { + $inversed->associatedEntities->removeElement($owning); + $owning->associatedEntities->removeElement($inversed); + } + + $this->_em->flush(); + $this->_em->clear(); + + // test association is removed + + $this->assertEquals(0, $conn->fetchColumn('SELECT COUNT(*) FROM vct_xref_manytomany_compositeid_foreignkey')); + } +} diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/ManyToManyCompositeIdTest.php b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/ManyToManyCompositeIdTest.php new file mode 100644 index 000000000..d0f75b4cb --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/ManyToManyCompositeIdTest.php @@ -0,0 +1,162 @@ +useModelSet('vct_manytomany_compositeid'); + parent::setUp(); + + $inversed = new Entity\InversedManyToManyCompositeIdEntity(); + $inversed->id1 = 'abc'; + $inversed->id2 = 'def'; + + $owning = new Entity\OwningManyToManyCompositeIdEntity(); + $owning->id = 'ghi'; + + $inversed->associatedEntities->add($owning); + $owning->associatedEntities->add($inversed); + + $this->_em->persist($inversed); + $this->_em->persist($owning); + + $this->_em->flush(); + $this->_em->clear(); + } + + public static function tearDownAfterClass() + { + $conn = static::$_sharedConn; + + $conn->executeUpdate('DROP TABLE vct_xref_manytomany_compositeid'); + $conn->executeUpdate('DROP TABLE vct_owning_manytomany_compositeid'); + $conn->executeUpdate('DROP TABLE vct_inversed_manytomany_compositeid'); + } + + public function testThatTheValueOfIdentifiersAreConvertedInTheDatabase() + { + $conn = $this->_em->getConnection(); + + $this->assertEquals('nop', $conn->fetchColumn('SELECT id1 FROM vct_inversed_manytomany_compositeid LIMIT 1')); + $this->assertEquals('qrs', $conn->fetchColumn('SELECT id2 FROM vct_inversed_manytomany_compositeid LIMIT 1')); + + $this->assertEquals('tuv', $conn->fetchColumn('SELECT id FROM vct_owning_manytomany_compositeid LIMIT 1')); + + $this->assertEquals('nop', $conn->fetchColumn('SELECT inversed_id1 FROM vct_xref_manytomany_compositeid LIMIT 1')); + $this->assertEquals('qrs', $conn->fetchColumn('SELECT inversed_id2 FROM vct_xref_manytomany_compositeid LIMIT 1')); + $this->assertEquals('tuv', $conn->fetchColumn('SELECT owning_id FROM vct_xref_manytomany_compositeid LIMIT 1')); + } + + /** + * @depends testThatTheValueOfIdentifiersAreConvertedInTheDatabase + */ + public function testThatEntitiesAreFetchedFromTheDatabase() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdEntity', + array('id1' => 'abc', 'id2' => 'def') + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdEntity', + 'ghi' + ); + + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdEntity', $inversed); + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdEntity', $owning); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdEntity', + array('id1' => 'abc', 'id2' => 'def') + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdEntity', + 'ghi' + ); + + $this->assertEquals('abc', $inversed->id1); + $this->assertEquals('def', $inversed->id2); + $this->assertEquals('ghi', $owning->id); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheCollectionFromOwningToInversedIsLoaded() + { + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdEntity', + 'ghi' + ); + + $this->assertCount(1, $owning->associatedEntities); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheCollectionFromInversedToOwningIsLoaded() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdEntity', + array('id1' => 'abc', 'id2' => 'def') + ); + + $this->assertCount(1, $inversed->associatedEntities); + } + + /** + * @depends testThatTheCollectionFromOwningToInversedIsLoaded + * @depends testThatTheCollectionFromInversedToOwningIsLoaded + */ + public function testThatTheJoinTableRowsAreRemovedWhenRemovingTheAssociation() + { + $conn = $this->_em->getConnection(); + + // remove association + + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdEntity', + array('id1' => 'abc', 'id2' => 'def') + ); + + foreach ($inversed->associatedEntities as $owning) { + $inversed->associatedEntities->removeElement($owning); + $owning->associatedEntities->removeElement($inversed); + } + + $this->_em->flush(); + $this->_em->clear(); + + // test association is removed + + $this->assertEquals(0, $conn->fetchColumn('SELECT COUNT(*) FROM vct_xref_manytomany_compositeid')); + } +} diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/ManyToManyTest.php b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/ManyToManyTest.php new file mode 100644 index 000000000..1ff8d7ab2 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/ManyToManyTest.php @@ -0,0 +1,158 @@ +useModelSet('vct_manytomany'); + parent::setUp(); + + $inversed = new Entity\InversedManyToManyEntity(); + $inversed->id = 'abc'; + + $owning = new Entity\OwningManyToManyEntity(); + $owning->id = 'def'; + + $inversed->associatedEntities->add($owning); + $owning->associatedEntities->add($inversed); + + $this->_em->persist($inversed); + $this->_em->persist($owning); + + $this->_em->flush(); + $this->_em->clear(); + } + + public static function tearDownAfterClass() + { + $conn = static::$_sharedConn; + + $conn->executeUpdate('DROP TABLE vct_xref_manytomany'); + $conn->executeUpdate('DROP TABLE vct_owning_manytomany'); + $conn->executeUpdate('DROP TABLE vct_inversed_manytomany'); + } + + public function testThatTheValueOfIdentifiersAreConvertedInTheDatabase() + { + $conn = $this->_em->getConnection(); + + $this->assertEquals('nop', $conn->fetchColumn('SELECT id FROM vct_inversed_manytomany LIMIT 1')); + + $this->assertEquals('qrs', $conn->fetchColumn('SELECT id FROM vct_owning_manytomany LIMIT 1')); + + $this->assertEquals('nop', $conn->fetchColumn('SELECT inversed_id FROM vct_xref_manytomany LIMIT 1')); + $this->assertEquals('qrs', $conn->fetchColumn('SELECT owning_id FROM vct_xref_manytomany LIMIT 1')); + } + + /** + * @depends testThatTheValueOfIdentifiersAreConvertedInTheDatabase + */ + public function testThatEntitiesAreFetchedFromTheDatabase() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyEntity', + 'abc' + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyEntity', + 'def' + ); + + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedManyToManyEntity', $inversed); + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningManyToManyEntity', $owning); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyEntity', + 'abc' + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyEntity', + 'def' + ); + + $this->assertEquals('abc', $inversed->id); + $this->assertEquals('def', $owning->id); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheCollectionFromOwningToInversedIsLoaded() + { + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyEntity', + 'def' + ); + + $this->assertCount(1, $owning->associatedEntities); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheCollectionFromInversedToOwningIsLoaded() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyEntity', + 'abc' + ); + + $this->assertCount(1, $inversed->associatedEntities); + } + + /** + * @depends testThatTheCollectionFromOwningToInversedIsLoaded + * @depends testThatTheCollectionFromInversedToOwningIsLoaded + */ + public function testThatTheJoinTableRowsAreRemovedWhenRemovingTheAssociation() + { + $conn = $this->_em->getConnection(); + + // remove association + + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyEntity', + 'abc' + ); + + foreach ($inversed->associatedEntities as $owning) { + $inversed->associatedEntities->removeElement($owning); + $owning->associatedEntities->removeElement($inversed); + } + + $this->_em->flush(); + $this->_em->clear(); + + // test association is removed + + $this->assertEquals(0, $conn->fetchColumn('SELECT COUNT(*) FROM vct_xref_manytomany')); + } +} diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyCompositeIdForeignKeyTest.php b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyCompositeIdForeignKeyTest.php new file mode 100644 index 000000000..d0f571415 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyCompositeIdForeignKeyTest.php @@ -0,0 +1,140 @@ +useModelSet('vct_onetomany_compositeid_foreignkey'); + parent::setUp(); + + $auxiliary = new Entity\AuxiliaryEntity(); + $auxiliary->id = 'abc'; + + $inversed = new Entity\InversedOneToManyCompositeIdForeignKeyEntity(); + $inversed->id = 'def'; + $inversed->foreignEntity = $auxiliary; + $inversed->someProperty = 'some value to be loaded'; + + $owning = new Entity\OwningManyToOneCompositeIdForeignKeyEntity(); + $owning->id = 'ghi'; + + $inversed->associatedEntities->add($owning); + $owning->associatedEntity = $inversed; + + $this->_em->persist($auxiliary); + $this->_em->persist($inversed); + $this->_em->persist($owning); + + $this->_em->flush(); + $this->_em->clear(); + } + + public static function tearDownAfterClass() + { + $conn = static::$_sharedConn; + + $conn->executeUpdate('DROP TABLE vct_owning_manytoone_compositeid_foreignkey'); + $conn->executeUpdate('DROP TABLE vct_inversed_onetomany_compositeid_foreignkey'); + $conn->executeUpdate('DROP TABLE vct_auxiliary'); + } + + public function testThatTheValueOfIdentifiersAreConvertedInTheDatabase() + { + $conn = $this->_em->getConnection(); + + $this->assertEquals('qrs', $conn->fetchColumn('SELECT id FROM vct_inversed_onetomany_compositeid_foreignkey LIMIT 1')); + $this->assertEquals('nop', $conn->fetchColumn('SELECT foreign_id FROM vct_inversed_onetomany_compositeid_foreignkey LIMIT 1')); + + $this->assertEquals('tuv', $conn->fetchColumn('SELECT id FROM vct_owning_manytoone_compositeid_foreignkey LIMIT 1')); + $this->assertEquals('qrs', $conn->fetchColumn('SELECT associated_id FROM vct_owning_manytoone_compositeid_foreignkey LIMIT 1')); + $this->assertEquals('nop', $conn->fetchColumn('SELECT associated_foreign_id FROM vct_owning_manytoone_compositeid_foreignkey LIMIT 1')); + } + + /** + * @depends testThatTheValueOfIdentifiersAreConvertedInTheDatabase + */ + public function testThatEntitiesAreFetchedFromTheDatabase() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdForeignKeyEntity', + array('id' => 'def', 'foreignEntity' => 'abc') + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdForeignKeyEntity', + 'ghi' + ); + + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdForeignKeyEntity', $inversed); + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdForeignKeyEntity', $owning); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdForeignKeyEntity', + array('id' => 'def', 'foreignEntity' => 'abc') + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdForeignKeyEntity', + 'ghi' + ); + + $this->assertEquals('def', $inversed->id); + $this->assertEquals('abc', $inversed->foreignEntity->id); + $this->assertEquals('ghi', $owning->id); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheProxyFromOwningToInversedIsLoaded() + { + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdForeignKeyEntity', + 'ghi' + ); + + $inversedProxy = $owning->associatedEntity; + + $this->assertEquals('some value to be loaded', $inversedProxy->someProperty); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheCollectionFromInversedToOwningIsLoaded() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdForeignKeyEntity', + array('id' => 'def', 'foreignEntity' => 'abc') + ); + + $this->assertCount(1, $inversed->associatedEntities); + } +} diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyCompositeIdTest.php b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyCompositeIdTest.php new file mode 100644 index 000000000..297b46eb8 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyCompositeIdTest.php @@ -0,0 +1,134 @@ +useModelSet('vct_onetomany_compositeid'); + parent::setUp(); + + $inversed = new Entity\InversedOneToManyCompositeIdEntity(); + $inversed->id1 = 'abc'; + $inversed->id2 = 'def'; + $inversed->someProperty = 'some value to be loaded'; + + $owning = new Entity\OwningManyToOneCompositeIdEntity(); + $owning->id = 'ghi'; + + $inversed->associatedEntities->add($owning); + $owning->associatedEntity = $inversed; + + $this->_em->persist($inversed); + $this->_em->persist($owning); + + $this->_em->flush(); + $this->_em->clear(); + } + + public static function tearDownAfterClass() + { + $conn = static::$_sharedConn; + + $conn->executeUpdate('DROP TABLE vct_owning_manytoone_compositeid'); + $conn->executeUpdate('DROP TABLE vct_inversed_onetomany_compositeid'); + } + + public function testThatTheValueOfIdentifiersAreConvertedInTheDatabase() + { + $conn = $this->_em->getConnection(); + + $this->assertEquals('nop', $conn->fetchColumn('SELECT id1 FROM vct_inversed_onetomany_compositeid LIMIT 1')); + $this->assertEquals('qrs', $conn->fetchColumn('SELECT id2 FROM vct_inversed_onetomany_compositeid LIMIT 1')); + + $this->assertEquals('tuv', $conn->fetchColumn('SELECT id FROM vct_owning_manytoone_compositeid LIMIT 1')); + $this->assertEquals('nop', $conn->fetchColumn('SELECT associated_id1 FROM vct_owning_manytoone_compositeid LIMIT 1')); + $this->assertEquals('qrs', $conn->fetchColumn('SELECT associated_id2 FROM vct_owning_manytoone_compositeid LIMIT 1')); + } + + /** + * @depends testThatTheValueOfIdentifiersAreConvertedInTheDatabase + */ + public function testThatEntitiesAreFetchedFromTheDatabase() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdEntity', + array('id1' => 'abc', 'id2' => 'def') + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdEntity', + 'ghi' + ); + + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdEntity', $inversed); + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdEntity', $owning); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdEntity', + array('id1' => 'abc', 'id2' => 'def') + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdEntity', + 'ghi' + ); + + $this->assertEquals('abc', $inversed->id1); + $this->assertEquals('def', $inversed->id2); + $this->assertEquals('ghi', $owning->id); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheProxyFromOwningToInversedIsLoaded() + { + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdEntity', + 'ghi' + ); + + $inversedProxy = $owning->associatedEntity; + + $this->assertEquals('some value to be loaded', $inversedProxy->someProperty); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheCollectionFromInversedToOwningIsLoaded() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdEntity', + array('id1' => 'abc', 'id2' => 'def') + ); + + $this->assertCount(1, $inversed->associatedEntities); + } +} diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyTest.php b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyTest.php new file mode 100644 index 000000000..25e9135c3 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyTest.php @@ -0,0 +1,130 @@ +useModelSet('vct_onetomany'); + parent::setUp(); + + $inversed = new Entity\InversedOneToManyEntity(); + $inversed->id = 'abc'; + $inversed->someProperty = 'some value to be loaded'; + + $owning = new Entity\OwningManyToOneEntity(); + $owning->id = 'def'; + + $inversed->associatedEntities->add($owning); + $owning->associatedEntity = $inversed; + + $this->_em->persist($inversed); + $this->_em->persist($owning); + + $this->_em->flush(); + $this->_em->clear(); + } + + public static function tearDownAfterClass() + { + $conn = static::$_sharedConn; + + $conn->executeUpdate('DROP TABLE vct_owning_manytoone'); + $conn->executeUpdate('DROP TABLE vct_inversed_onetomany'); + } + + public function testThatTheValueOfIdentifiersAreConvertedInTheDatabase() + { + $conn = $this->_em->getConnection(); + + $this->assertEquals('nop', $conn->fetchColumn('SELECT id FROM vct_inversed_onetomany LIMIT 1')); + + $this->assertEquals('qrs', $conn->fetchColumn('SELECT id FROM vct_owning_manytoone LIMIT 1')); + $this->assertEquals('nop', $conn->fetchColumn('SELECT associated_id FROM vct_owning_manytoone LIMIT 1')); + } + + /** + * @depends testThatTheValueOfIdentifiersAreConvertedInTheDatabase + */ + public function testThatEntitiesAreFetchedFromTheDatabase() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyEntity', + 'abc' + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneEntity', + 'def' + ); + + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedOneToManyEntity', $inversed); + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningManyToOneEntity', $owning); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyEntity', + 'abc' + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneEntity', + 'def' + ); + + $this->assertEquals('abc', $inversed->id); + $this->assertEquals('def', $owning->id); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheProxyFromOwningToInversedIsLoaded() + { + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneEntity', + 'def' + ); + + $inversedProxy = $owning->associatedEntity; + + $this->assertEquals('some value to be loaded', $inversedProxy->someProperty); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheCollectionFromInversedToOwningIsLoaded() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyEntity', + 'abc' + ); + + $this->assertCount(1, $inversed->associatedEntities); + } +} diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToOneCompositeIdForeignKeyTest.php b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToOneCompositeIdForeignKeyTest.php new file mode 100644 index 000000000..b3b58d245 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToOneCompositeIdForeignKeyTest.php @@ -0,0 +1,140 @@ +useModelSet('vct_onetoone_compositeid_foreignkey'); + parent::setUp(); + + $auxiliary = new Entity\AuxiliaryEntity(); + $auxiliary->id = 'abc'; + + $inversed = new Entity\InversedOneToOneCompositeIdForeignKeyEntity(); + $inversed->id = 'def'; + $inversed->foreignEntity = $auxiliary; + $inversed->someProperty = 'some value to be loaded'; + + $owning = new Entity\OwningOneToOneCompositeIdForeignKeyEntity(); + $owning->id = 'ghi'; + + $inversed->associatedEntity = $owning; + $owning->associatedEntity = $inversed; + + $this->_em->persist($auxiliary); + $this->_em->persist($inversed); + $this->_em->persist($owning); + + $this->_em->flush(); + $this->_em->clear(); + } + + public static function tearDownAfterClass() + { + $conn = static::$_sharedConn; + + $conn->executeUpdate('DROP TABLE vct_owning_onetoone_compositeid_foreignkey'); + $conn->executeUpdate('DROP TABLE vct_inversed_onetoone_compositeid_foreignkey'); + $conn->executeUpdate('DROP TABLE vct_auxiliary'); + } + + public function testThatTheValueOfIdentifiersAreConvertedInTheDatabase() + { + $conn = $this->_em->getConnection(); + + $this->assertEquals('qrs', $conn->fetchColumn('SELECT id FROM vct_inversed_onetoone_compositeid_foreignkey LIMIT 1')); + $this->assertEquals('nop', $conn->fetchColumn('SELECT foreign_id FROM vct_inversed_onetoone_compositeid_foreignkey LIMIT 1')); + + $this->assertEquals('tuv', $conn->fetchColumn('SELECT id FROM vct_owning_onetoone_compositeid_foreignkey LIMIT 1')); + $this->assertEquals('qrs', $conn->fetchColumn('SELECT associated_id FROM vct_owning_onetoone_compositeid_foreignkey LIMIT 1')); + $this->assertEquals('nop', $conn->fetchColumn('SELECT associated_foreign_id FROM vct_owning_onetoone_compositeid_foreignkey LIMIT 1')); + } + + /** + * @depends testThatTheValueOfIdentifiersAreConvertedInTheDatabase + */ + public function testThatEntitiesAreFetchedFromTheDatabase() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdForeignKeyEntity', + array('id' => 'def', 'foreignEntity' => 'abc') + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdForeignKeyEntity', + 'ghi' + ); + + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdForeignKeyEntity', $inversed); + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdForeignKeyEntity', $owning); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdForeignKeyEntity', + array('id' => 'def', 'foreignEntity' => 'abc') + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdForeignKeyEntity', + 'ghi' + ); + + $this->assertEquals('def', $inversed->id); + $this->assertEquals('abc', $inversed->foreignEntity->id); + $this->assertEquals('ghi', $owning->id); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheProxyFromOwningToInversedIsLoaded() + { + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdForeignKeyEntity', + 'ghi' + ); + + $inversedProxy = $owning->associatedEntity; + + $this->assertEquals('some value to be loaded', $inversedProxy->someProperty); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheEntityFromInversedToOwningIsEagerLoaded() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdForeignKeyEntity', + array('id' => 'def', 'foreignEntity' => 'abc') + ); + + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdForeignKeyEntity', $inversed->associatedEntity); + } +} diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToOneCompositeIdTest.php b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToOneCompositeIdTest.php new file mode 100644 index 000000000..0390eb7f5 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToOneCompositeIdTest.php @@ -0,0 +1,134 @@ +useModelSet('vct_onetoone_compositeid'); + parent::setUp(); + + $inversed = new Entity\InversedOneToOneCompositeIdEntity(); + $inversed->id1 = 'abc'; + $inversed->id2 = 'def'; + $inversed->someProperty = 'some value to be loaded'; + + $owning = new Entity\OwningOneToOneCompositeIdEntity(); + $owning->id = 'ghi'; + + $inversed->associatedEntity = $owning; + $owning->associatedEntity = $inversed; + + $this->_em->persist($inversed); + $this->_em->persist($owning); + + $this->_em->flush(); + $this->_em->clear(); + } + + public static function tearDownAfterClass() + { + $conn = static::$_sharedConn; + + $conn->executeUpdate('DROP TABLE vct_owning_onetoone_compositeid'); + $conn->executeUpdate('DROP TABLE vct_inversed_onetoone_compositeid'); + } + + public function testThatTheValueOfIdentifiersAreConvertedInTheDatabase() + { + $conn = $this->_em->getConnection(); + + $this->assertEquals('nop', $conn->fetchColumn('SELECT id1 FROM vct_inversed_onetoone_compositeid LIMIT 1')); + $this->assertEquals('qrs', $conn->fetchColumn('SELECT id2 FROM vct_inversed_onetoone_compositeid LIMIT 1')); + + $this->assertEquals('tuv', $conn->fetchColumn('SELECT id FROM vct_owning_onetoone_compositeid LIMIT 1')); + $this->assertEquals('nop', $conn->fetchColumn('SELECT associated_id1 FROM vct_owning_onetoone_compositeid LIMIT 1')); + $this->assertEquals('qrs', $conn->fetchColumn('SELECT associated_id2 FROM vct_owning_onetoone_compositeid LIMIT 1')); + } + + /** + * @depends testThatTheValueOfIdentifiersAreConvertedInTheDatabase + */ + public function testThatEntitiesAreFetchedFromTheDatabase() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdEntity', + array('id1' => 'abc', 'id2' => 'def') + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdEntity', + 'ghi' + ); + + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdEntity', $inversed); + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdEntity', $owning); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdEntity', + array('id1' => 'abc', 'id2' => 'def') + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdEntity', + 'ghi' + ); + + $this->assertEquals('abc', $inversed->id1); + $this->assertEquals('def', $inversed->id2); + $this->assertEquals('ghi', $owning->id); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheProxyFromOwningToInversedIsLoaded() + { + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdEntity', + 'ghi' + ); + + $inversedProxy = $owning->associatedEntity; + + $this->assertEquals('some value to be loaded', $inversedProxy->someProperty); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheEntityFromInversedToOwningIsEagerLoaded() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdEntity', + array('id1' => 'abc', 'id2' => 'def') + ); + + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdEntity', $inversed->associatedEntity); + } +} diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToOneTest.php b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToOneTest.php new file mode 100644 index 000000000..2cdaadcaa --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToOneTest.php @@ -0,0 +1,130 @@ +useModelSet('vct_onetoone'); + parent::setUp(); + + $inversed = new Entity\InversedOneToOneEntity(); + $inversed->id = 'abc'; + $inversed->someProperty = 'some value to be loaded'; + + $owning = new Entity\OwningOneToOneEntity(); + $owning->id = 'def'; + + $inversed->associatedEntity = $owning; + $owning->associatedEntity = $inversed; + + $this->_em->persist($inversed); + $this->_em->persist($owning); + + $this->_em->flush(); + $this->_em->clear(); + } + + public static function tearDownAfterClass() + { + $conn = static::$_sharedConn; + + $conn->executeUpdate('DROP TABLE vct_owning_onetoone'); + $conn->executeUpdate('DROP TABLE vct_inversed_onetoone'); + } + + public function testThatTheValueOfIdentifiersAreConvertedInTheDatabase() + { + $conn = $this->_em->getConnection(); + + $this->assertEquals('nop', $conn->fetchColumn('SELECT id FROM vct_inversed_onetoone LIMIT 1')); + + $this->assertEquals('qrs', $conn->fetchColumn('SELECT id FROM vct_owning_onetoone LIMIT 1')); + $this->assertEquals('nop', $conn->fetchColumn('SELECT associated_id FROM vct_owning_onetoone LIMIT 1')); + } + + /** + * @depends testThatTheValueOfIdentifiersAreConvertedInTheDatabase + */ + public function testThatEntitiesAreFetchedFromTheDatabase() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneEntity', + 'abc' + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneEntity', + 'def' + ); + + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedOneToOneEntity', $inversed); + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningOneToOneEntity', $owning); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneEntity', + 'abc' + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneEntity', + 'def' + ); + + $this->assertEquals('abc', $inversed->id); + $this->assertEquals('def', $owning->id); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheProxyFromOwningToInversedIsLoaded() + { + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneEntity', + 'def' + ); + + $inversedProxy = $owning->associatedEntity; + + $this->assertEquals('some value to be loaded', $inversedProxy->someProperty); + } + + /** + * @depends testThatEntitiesAreFetchedFromTheDatabase + */ + public function testThatTheEntityFromInversedToOwningIsEagerLoaded() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneEntity', + 'abc' + ); + + $this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningOneToOneEntity', $inversed->associatedEntity); + } +} diff --git a/tests/Doctrine/Tests/OrmFunctionalTestCase.php b/tests/Doctrine/Tests/OrmFunctionalTestCase.php index bc301ecfb..0af76186c 100644 --- a/tests/Doctrine/Tests/OrmFunctionalTestCase.php +++ b/tests/Doctrine/Tests/OrmFunctionalTestCase.php @@ -199,6 +199,45 @@ abstract class OrmFunctionalTestCase extends OrmTestCase 'Doctrine\Tests\Models\Quote\Phone', 'Doctrine\Tests\Models\Quote\User' ), + 'vct_onetoone' => array( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneEntity', + 'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneEntity' + ), + 'vct_onetoone_compositeid' => array( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdEntity', + 'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdEntity' + ), + 'vct_onetoone_compositeid_foreignkey' => array( + 'Doctrine\Tests\Models\ValueConversionType\AuxiliaryEntity', + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdForeignKeyEntity', + 'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdForeignKeyEntity' + ), + 'vct_onetomany' => array( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyEntity', + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneEntity' + ), + 'vct_onetomany_compositeid' => array( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdEntity', + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdEntity' + ), + 'vct_onetomany_compositeid_foreignkey' => array( + 'Doctrine\Tests\Models\ValueConversionType\AuxiliaryEntity', + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdForeignKeyEntity', + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdForeignKeyEntity' + ), + 'vct_manytomany' => array( + 'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyEntity', + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyEntity' + ), + 'vct_manytomany_compositeid' => array( + 'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdEntity', + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdEntity' + ), + 'vct_manytomany_compositeid_foreignkey' => array( + 'Doctrine\Tests\Models\ValueConversionType\AuxiliaryEntity', + 'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdForeignKeyEntity', + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdForeignKeyEntity' + ), ); /** @@ -358,6 +397,57 @@ abstract class OrmFunctionalTestCase extends OrmTestCase $conn->executeUpdate('DELETE FROM ' . $platform->quoteIdentifier("quote-user")); } + if (isset($this->_usedModelSets['vct_onetoone'])) { + $conn->executeUpdate('DELETE FROM vct_owning_onetoone'); + $conn->executeUpdate('DELETE FROM vct_inversed_onetoone'); + } + + if (isset($this->_usedModelSets['vct_onetoone_compositeid'])) { + $conn->executeUpdate('DELETE FROM vct_owning_onetoone_compositeid'); + $conn->executeUpdate('DELETE FROM vct_inversed_onetoone_compositeid'); + } + + if (isset($this->_usedModelSets['vct_onetoone_compositeid_foreignkey'])) { + $conn->executeUpdate('DELETE FROM vct_owning_onetoone_compositeid_foreignkey'); + $conn->executeUpdate('DELETE FROM vct_inversed_onetoone_compositeid_foreignkey'); + $conn->executeUpdate('DELETE FROM vct_auxiliary'); + } + + if (isset($this->_usedModelSets['vct_onetomany'])) { + $conn->executeUpdate('DELETE FROM vct_owning_manytoone'); + $conn->executeUpdate('DELETE FROM vct_inversed_onetomany'); + } + + if (isset($this->_usedModelSets['vct_onetomany_compositeid'])) { + $conn->executeUpdate('DELETE FROM vct_owning_manytoone_compositeid'); + $conn->executeUpdate('DELETE FROM vct_inversed_onetomany_compositeid'); + } + + if (isset($this->_usedModelSets['vct_onetomany_compositeid_foreignkey'])) { + $conn->executeUpdate('DELETE FROM vct_owning_manytoone_compositeid_foreignkey'); + $conn->executeUpdate('DELETE FROM vct_inversed_onetomany_compositeid_foreignkey'); + $conn->executeUpdate('DELETE FROM vct_auxiliary'); + } + + if (isset($this->_usedModelSets['vct_manytomany'])) { + $conn->executeUpdate('DELETE FROM vct_xref_manytomany'); + $conn->executeUpdate('DELETE FROM vct_owning_manytomany'); + $conn->executeUpdate('DELETE FROM vct_inversed_manytomany'); + } + + if (isset($this->_usedModelSets['vct_manytomany_compositeid'])) { + $conn->executeUpdate('DELETE FROM vct_xref_manytomany_compositeid'); + $conn->executeUpdate('DELETE FROM vct_owning_manytomany_compositeid'); + $conn->executeUpdate('DELETE FROM vct_inversed_manytomany_compositeid'); + } + + if (isset($this->_usedModelSets['vct_manytomany_compositeid_foreignkey'])) { + $conn->executeUpdate('DELETE FROM vct_xref_manytomany_compositeid_foreignkey'); + $conn->executeUpdate('DELETE FROM vct_owning_manytomany_compositeid_foreignkey'); + $conn->executeUpdate('DELETE FROM vct_inversed_manytomany_compositeid_foreignkey'); + $conn->executeUpdate('DELETE FROM vct_auxiliary'); + } + $this->_em->clear(); }