From cd728344e96281a51afba6a4eb22f4e0058757f0 Mon Sep 17 00:00:00 2001 From: Guido Contreras Woda Date: Tue, 23 Dec 2014 09:48:02 -0300 Subject: [PATCH 1/4] Allow an association to be set as primary key through the builder --- .../ORM/Mapping/Builder/AssociationBuilder.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php b/lib/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php index 942a662e4..2536f5be6 100644 --- a/lib/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php +++ b/lib/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php @@ -183,6 +183,17 @@ class AssociationBuilder return $this; } + /** + * Sets field as primary key. + * + * @return AssociationBuilder + */ + public function isPrimaryKey() + { + $this->mapping['id'] = true; + return $this; + } + /** * @return ClassMetadataBuilder * From 51881fed942e1e2d7b52a1213ed3b770d84e3b2f Mon Sep 17 00:00:00 2001 From: Guido Contreras Woda Date: Tue, 23 Dec 2014 10:16:07 -0300 Subject: [PATCH 2/4] Added tests and validation on joinColumns being set before checking if its a composite key. --- .../ORM/Mapping/ClassMetadataInfo.php | 4 + .../ORM/Mapping/ClassMetadataBuilderTest.php | 161 +++++++++++++++++- 2 files changed, 164 insertions(+), 1 deletion(-) diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index c3c8d8c83..a93f46a74 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -1461,6 +1461,10 @@ class ClassMetadataInfo implements ClassMetadata } if ( ! in_array($mapping['fieldName'], $this->identifier)) { + if (!isset($mapping['joinColumns'])) { + throw MappingException::illegalInverseIdentifierAssociation($this->name, $mapping['fieldName']); + } + if (count($mapping['joinColumns']) >= 2) { throw MappingException::cannotMapCompositePrimaryKeyEntitiesAsForeignId( $mapping['targetEntity'], $this->name, $mapping['fieldName'] diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataBuilderTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataBuilderTest.php index ad236b2d9..a3ce514bb 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataBuilderTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataBuilderTest.php @@ -332,6 +332,67 @@ class ClassMetadataBuilderTest extends \Doctrine\Tests\OrmTestCase ), $this->cm->associationMappings); } + public function testIdentityOnCreateManyToOne() + { + $this->assertIsFluent( + $this->builder->createManyToOne('groups', 'Doctrine\Tests\Models\CMS\CmsGroup') + ->addJoinColumn('group_id', 'id', true, false, 'CASCADE') + ->cascadeAll() + ->fetchExtraLazy() + ->isPrimaryKey() + ->build() + ); + + $this->assertEquals(array('groups' => array ( + 'fieldName' => 'groups', + 'targetEntity' => 'Doctrine\\Tests\\Models\\CMS\\CmsGroup', + 'cascade' => array ( + 0 => 'remove', + 1 => 'persist', + 2 => 'refresh', + 3 => 'merge', + 4 => 'detach', + ), + 'fetch' => 4, + 'joinColumns' => array ( + 0 => + array ( + 'name' => 'group_id', + 'referencedColumnName' => 'id', + 'nullable' => true, + 'unique' => false, + 'onDelete' => 'CASCADE', + 'columnDefinition' => NULL, + ), + ), + 'type' => 2, + 'mappedBy' => NULL, + 'inversedBy' => NULL, + 'isOwningSide' => true, + 'sourceEntity' => 'Doctrine\\Tests\\Models\\CMS\\CmsUser', + 'isCascadeRemove' => true, + 'isCascadePersist' => true, + 'isCascadeRefresh' => true, + 'isCascadeMerge' => true, + 'isCascadeDetach' => true, + 'sourceToTargetKeyColumns' => + array ( + 'group_id' => 'id', + ), + 'joinColumnFieldNames' => + array ( + 'group_id' => 'group_id', + ), + 'targetToSourceKeyColumns' => + array ( + 'id' => 'group_id', + ), + 'orphanRemoval' => false, + 'id' => true + ), + ), $this->cm->associationMappings); + } + public function testCreateOneToOne() { $this->assertIsFluent( @@ -386,11 +447,83 @@ class ClassMetadataBuilderTest extends \Doctrine\Tests\OrmTestCase array ( 'id' => 'group_id', ), - 'orphanRemoval' => false, + 'orphanRemoval' => false ), ), $this->cm->associationMappings); } + public function testCreateOneToOneWithIdentity() + { + $this->assertIsFluent( + $this->builder->createOneToOne('groups', 'Doctrine\Tests\Models\CMS\CmsGroup') + ->addJoinColumn('group_id', 'id', true, false, 'CASCADE') + ->cascadeAll() + ->fetchExtraLazy() + ->isPrimaryKey() + ->build() + ); + + $this->assertEquals(array('groups' => array ( + 'fieldName' => 'groups', + 'targetEntity' => 'Doctrine\\Tests\\Models\\CMS\\CmsGroup', + 'cascade' => array ( + 0 => 'remove', + 1 => 'persist', + 2 => 'refresh', + 3 => 'merge', + 4 => 'detach', + ), + 'fetch' => 4, + 'id' => true, + 'joinColumns' => array ( + 0 => + array ( + 'name' => 'group_id', + 'referencedColumnName' => 'id', + 'nullable' => true, + 'unique' => false, + 'onDelete' => 'CASCADE', + 'columnDefinition' => NULL, + ), + ), + 'type' => 1, + 'mappedBy' => NULL, + 'inversedBy' => NULL, + 'isOwningSide' => true, + 'sourceEntity' => 'Doctrine\\Tests\\Models\\CMS\\CmsUser', + 'isCascadeRemove' => true, + 'isCascadePersist' => true, + 'isCascadeRefresh' => true, + 'isCascadeMerge' => true, + 'isCascadeDetach' => true, + 'sourceToTargetKeyColumns' => + array ( + 'group_id' => 'id', + ), + 'joinColumnFieldNames' => + array ( + 'group_id' => 'group_id', + ), + 'targetToSourceKeyColumns' => + array ( + 'id' => 'group_id', + ), + 'orphanRemoval' => false + ), + ), $this->cm->associationMappings); + } + + public function testDisallowCreateOneToOneWithIdentityOnInverseSide() + { + $this->setExpectedException('Doctrine\ORM\Mapping\MappingException'); + + $this->builder->createOneToOne('groups', 'Doctrine\Tests\Models\CMS\CmsGroup') + ->mappedBy('test') + ->fetchExtraLazy() + ->isPrimaryKey() + ->build(); + } + public function testCreateManyToMany() { $this->assertIsFluent( @@ -474,6 +607,20 @@ class ClassMetadataBuilderTest extends \Doctrine\Tests\OrmTestCase ), $this->cm->associationMappings); } + public function testDisallowIdentityOnCreateManyToMany() + { + $this->setExpectedException('Doctrine\ORM\Mapping\MappingException'); + + $this->builder->createManyToMany('groups', 'Doctrine\Tests\Models\CMS\CmsGroup') + ->isPrimaryKey() + ->setJoinTable('groups_users') + ->addJoinColumn('group_id', 'id', true, false, 'CASCADE') + ->addInverseJoinColumn('user_id', 'id') + ->cascadeAll() + ->fetchExtraLazy() + ->build(); + } + public function testCreateOneToMany() { $this->assertIsFluent( @@ -513,6 +660,18 @@ class ClassMetadataBuilderTest extends \Doctrine\Tests\OrmTestCase ), $this->cm->associationMappings); } + public function testDisallowIdentityOnCreateOneToMany() + { + $this->setExpectedException('Doctrine\ORM\Mapping\MappingException'); + + $this->builder->createOneToMany('groups', 'Doctrine\Tests\Models\CMS\CmsGroup') + ->isPrimaryKey() + ->mappedBy('test') + ->setOrderBy(array('test')) + ->setIndexBy('test') + ->build(); + } + public function assertIsFluent($ret) { $this->assertSame($this->builder, $ret, "Return Value has to be same instance as used builder"); From baeab5d4f41a4c5ce882709b0ab12985aab8b90b Mon Sep 17 00:00:00 2001 From: Guido Contreras Woda Date: Tue, 23 Dec 2014 10:20:35 -0300 Subject: [PATCH 3/4] More consistent test naming --- .../Tests/ORM/Mapping/ClassMetadataBuilderTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataBuilderTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataBuilderTest.php index a3ce514bb..e05382202 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataBuilderTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataBuilderTest.php @@ -332,7 +332,7 @@ class ClassMetadataBuilderTest extends \Doctrine\Tests\OrmTestCase ), $this->cm->associationMappings); } - public function testIdentityOnCreateManyToOne() + public function testCreateManyToOneWithIdentity() { $this->assertIsFluent( $this->builder->createManyToOne('groups', 'Doctrine\Tests\Models\CMS\CmsGroup') @@ -513,7 +513,7 @@ class ClassMetadataBuilderTest extends \Doctrine\Tests\OrmTestCase ), $this->cm->associationMappings); } - public function testDisallowCreateOneToOneWithIdentityOnInverseSide() + public function testThrowsExceptionOnCreateOneToOneWithIdentityOnInverseSide() { $this->setExpectedException('Doctrine\ORM\Mapping\MappingException'); @@ -607,7 +607,7 @@ class ClassMetadataBuilderTest extends \Doctrine\Tests\OrmTestCase ), $this->cm->associationMappings); } - public function testDisallowIdentityOnCreateManyToMany() + public function testThrowsExceptionOnCreateManyToManyWithIdentity() { $this->setExpectedException('Doctrine\ORM\Mapping\MappingException'); @@ -660,7 +660,7 @@ class ClassMetadataBuilderTest extends \Doctrine\Tests\OrmTestCase ), $this->cm->associationMappings); } - public function testDisallowIdentityOnCreateOneToMany() + public function testThrowsExceptionOnCreateOneToManyWithIdentity() { $this->setExpectedException('Doctrine\ORM\Mapping\MappingException'); From 1f67218dc56335dca43cce43ed85c5ba315318e1 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Mon, 16 Feb 2015 02:06:22 +0000 Subject: [PATCH 4/4] #1229 - code style fixes (alignment/spacing) --- .../Mapping/Builder/AssociationBuilder.php | 3 +- .../ORM/Mapping/ClassMetadataInfo.php | 2 +- .../ORM/Mapping/ClassMetadataBuilderTest.php | 236 ++++++++++-------- 3 files changed, 128 insertions(+), 113 deletions(-) diff --git a/lib/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php b/lib/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php index 2536f5be6..9a9c4dabe 100644 --- a/lib/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php +++ b/lib/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php @@ -186,11 +186,12 @@ class AssociationBuilder /** * Sets field as primary key. * - * @return AssociationBuilder + * @return self */ public function isPrimaryKey() { $this->mapping['id'] = true; + return $this; } diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index a93f46a74..51791af0d 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -1461,7 +1461,7 @@ class ClassMetadataInfo implements ClassMetadata } if ( ! in_array($mapping['fieldName'], $this->identifier)) { - if (!isset($mapping['joinColumns'])) { + if (! isset($mapping['joinColumns'])) { throw MappingException::illegalInverseIdentifierAssociation($this->name, $mapping['fieldName']); } diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataBuilderTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataBuilderTest.php index e05382202..f82079481 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataBuilderTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataBuilderTest.php @@ -335,62 +335,68 @@ class ClassMetadataBuilderTest extends \Doctrine\Tests\OrmTestCase public function testCreateManyToOneWithIdentity() { $this->assertIsFluent( - $this->builder->createManyToOne('groups', 'Doctrine\Tests\Models\CMS\CmsGroup') - ->addJoinColumn('group_id', 'id', true, false, 'CASCADE') - ->cascadeAll() - ->fetchExtraLazy() - ->isPrimaryKey() - ->build() + $this + ->builder + ->createManyToOne('groups', 'Doctrine\Tests\Models\CMS\CmsGroup') + ->addJoinColumn('group_id', 'id', true, false, 'CASCADE') + ->cascadeAll() + ->fetchExtraLazy() + ->isPrimaryKey() + ->build() ); - $this->assertEquals(array('groups' => array ( - 'fieldName' => 'groups', - 'targetEntity' => 'Doctrine\\Tests\\Models\\CMS\\CmsGroup', - 'cascade' => array ( - 0 => 'remove', - 1 => 'persist', - 2 => 'refresh', - 3 => 'merge', - 4 => 'detach', + $this->assertEquals( + array( + 'groups' => array( + 'fieldName' => 'groups', + 'targetEntity' => 'Doctrine\\Tests\\Models\\CMS\\CmsGroup', + 'cascade' => array( + 0 => 'remove', + 1 => 'persist', + 2 => 'refresh', + 3 => 'merge', + 4 => 'detach', + ), + 'fetch' => 4, + 'joinColumns' => array( + 0 => + array( + 'name' => 'group_id', + 'referencedColumnName' => 'id', + 'nullable' => true, + 'unique' => false, + 'onDelete' => 'CASCADE', + 'columnDefinition' => NULL, + ), + ), + 'type' => 2, + 'mappedBy' => NULL, + 'inversedBy' => NULL, + 'isOwningSide' => true, + 'sourceEntity' => 'Doctrine\\Tests\\Models\\CMS\\CmsUser', + 'isCascadeRemove' => true, + 'isCascadePersist' => true, + 'isCascadeRefresh' => true, + 'isCascadeMerge' => true, + 'isCascadeDetach' => true, + 'sourceToTargetKeyColumns' => + array( + 'group_id' => 'id', + ), + 'joinColumnFieldNames' => + array( + 'group_id' => 'group_id', + ), + 'targetToSourceKeyColumns' => + array( + 'id' => 'group_id', + ), + 'orphanRemoval' => false, + 'id' => true ), - 'fetch' => 4, - 'joinColumns' => array ( - 0 => - array ( - 'name' => 'group_id', - 'referencedColumnName' => 'id', - 'nullable' => true, - 'unique' => false, - 'onDelete' => 'CASCADE', - 'columnDefinition' => NULL, - ), - ), - 'type' => 2, - 'mappedBy' => NULL, - 'inversedBy' => NULL, - 'isOwningSide' => true, - 'sourceEntity' => 'Doctrine\\Tests\\Models\\CMS\\CmsUser', - 'isCascadeRemove' => true, - 'isCascadePersist' => true, - 'isCascadeRefresh' => true, - 'isCascadeMerge' => true, - 'isCascadeDetach' => true, - 'sourceToTargetKeyColumns' => - array ( - 'group_id' => 'id', - ), - 'joinColumnFieldNames' => - array ( - 'group_id' => 'group_id', - ), - 'targetToSourceKeyColumns' => - array ( - 'id' => 'group_id', - ), - 'orphanRemoval' => false, - 'id' => true - ), - ), $this->cm->associationMappings); + ), + $this->cm->associationMappings + ); } public function testCreateOneToOne() @@ -455,73 +461,81 @@ class ClassMetadataBuilderTest extends \Doctrine\Tests\OrmTestCase public function testCreateOneToOneWithIdentity() { $this->assertIsFluent( - $this->builder->createOneToOne('groups', 'Doctrine\Tests\Models\CMS\CmsGroup') - ->addJoinColumn('group_id', 'id', true, false, 'CASCADE') - ->cascadeAll() - ->fetchExtraLazy() - ->isPrimaryKey() - ->build() + $this + ->builder + ->createOneToOne('groups', 'Doctrine\Tests\Models\CMS\CmsGroup') + ->addJoinColumn('group_id', 'id', true, false, 'CASCADE') + ->cascadeAll() + ->fetchExtraLazy() + ->isPrimaryKey() + ->build() ); - $this->assertEquals(array('groups' => array ( - 'fieldName' => 'groups', - 'targetEntity' => 'Doctrine\\Tests\\Models\\CMS\\CmsGroup', - 'cascade' => array ( - 0 => 'remove', - 1 => 'persist', - 2 => 'refresh', - 3 => 'merge', - 4 => 'detach', + $this->assertEquals( + array( + 'groups' => array( + 'fieldName' => 'groups', + 'targetEntity' => 'Doctrine\\Tests\\Models\\CMS\\CmsGroup', + 'cascade' => array( + 0 => 'remove', + 1 => 'persist', + 2 => 'refresh', + 3 => 'merge', + 4 => 'detach', + ), + 'fetch' => 4, + 'id' => true, + 'joinColumns' => array( + 0 => + array( + 'name' => 'group_id', + 'referencedColumnName' => 'id', + 'nullable' => true, + 'unique' => false, + 'onDelete' => 'CASCADE', + 'columnDefinition' => NULL, + ), + ), + 'type' => 1, + 'mappedBy' => NULL, + 'inversedBy' => NULL, + 'isOwningSide' => true, + 'sourceEntity' => 'Doctrine\\Tests\\Models\\CMS\\CmsUser', + 'isCascadeRemove' => true, + 'isCascadePersist' => true, + 'isCascadeRefresh' => true, + 'isCascadeMerge' => true, + 'isCascadeDetach' => true, + 'sourceToTargetKeyColumns' => + array( + 'group_id' => 'id', + ), + 'joinColumnFieldNames' => + array( + 'group_id' => 'group_id', + ), + 'targetToSourceKeyColumns' => + array( + 'id' => 'group_id', + ), + 'orphanRemoval' => false ), - 'fetch' => 4, - 'id' => true, - 'joinColumns' => array ( - 0 => - array ( - 'name' => 'group_id', - 'referencedColumnName' => 'id', - 'nullable' => true, - 'unique' => false, - 'onDelete' => 'CASCADE', - 'columnDefinition' => NULL, - ), - ), - 'type' => 1, - 'mappedBy' => NULL, - 'inversedBy' => NULL, - 'isOwningSide' => true, - 'sourceEntity' => 'Doctrine\\Tests\\Models\\CMS\\CmsUser', - 'isCascadeRemove' => true, - 'isCascadePersist' => true, - 'isCascadeRefresh' => true, - 'isCascadeMerge' => true, - 'isCascadeDetach' => true, - 'sourceToTargetKeyColumns' => - array ( - 'group_id' => 'id', - ), - 'joinColumnFieldNames' => - array ( - 'group_id' => 'group_id', - ), - 'targetToSourceKeyColumns' => - array ( - 'id' => 'group_id', - ), - 'orphanRemoval' => false - ), - ), $this->cm->associationMappings); + ), + $this->cm->associationMappings + ); } public function testThrowsExceptionOnCreateOneToOneWithIdentityOnInverseSide() { $this->setExpectedException('Doctrine\ORM\Mapping\MappingException'); - $this->builder->createOneToOne('groups', 'Doctrine\Tests\Models\CMS\CmsGroup') - ->mappedBy('test') - ->fetchExtraLazy() - ->isPrimaryKey() - ->build(); + $this + ->builder + ->createOneToOne('groups', 'Doctrine\Tests\Models\CMS\CmsGroup') + ->mappedBy('test') + ->fetchExtraLazy() + ->isPrimaryKey() + ->build(); } public function testCreateManyToMany()