From 592122fbcb0734cef41103de50e2266e6dc58daf Mon Sep 17 00:00:00 2001 From: John Keller Date: Tue, 12 Apr 2016 13:43:45 -0700 Subject: [PATCH 1/5] add functional test and bug fix for issue #5762 --- .../ORM/Internal/Hydration/ObjectHydrator.php | 3 + .../ORM/Functional/Ticket/GH5762Test.php | 228 ++++++++++++++++++ 2 files changed, 231 insertions(+) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH5762Test.php diff --git a/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php index 3cedaada0..d7a429f00 100644 --- a/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php +++ b/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php @@ -332,6 +332,9 @@ class ObjectHydrator extends AbstractHydrator // Split the row data into chunks of class data. $rowData = $this->gatherRowData($row, $id, $nonemptyComponents); + // reset result pointers for each data row + $this->resultPointers = array(); + // Hydrate the data chunks foreach ($rowData['data'] as $dqlAlias => $data) { $entityName = $this->_rsm->aliasMap[$dqlAlias]; diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5762Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5762Test.php new file mode 100644 index 000000000..809417c04 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5762Test.php @@ -0,0 +1,228 @@ +_schemaTool->createSchema(array( + $this->_em->getClassMetadata(__NAMESPACE__ . '\GH5762Driver'), + $this->_em->getClassMetadata(__NAMESPACE__ . '\GH5762DriverRide'), + $this->_em->getClassMetadata(__NAMESPACE__ . '\GH5762Car'), + )); + } + + public function testIssue() + { + $result = $this->fetchData(); + + $this->assertInstanceOf(__NAMESPACE__ . '\GH5762Driver', $result); + $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result->getDriverRides()); + $this->assertInstanceOf(__NAMESPACE__ . '\GH5762DriverRide', $result->getDriverRides()->get(0)); + $this->assertInstanceOf(__NAMESPACE__ . '\GH5762Car', $result->getDriverRides()->get(0)->getCar()); + + $cars = array(); + foreach ($result->getDriverRides() as $ride) { + $cars[] = $ride->getCar()->getBrand(); + } + $this->assertEquals(count($cars), count(array_unique($cars))); + + $this->assertContains('BMW', $cars); + $this->assertContains('Crysler', $cars); + $this->assertContains('Dodge', $cars); + $this->assertContains('Mercedes', $cars); + $this->assertContains('Volvo', $cars); + } + + private function fetchData() + { + $this->createData(); + + $qb = $this->_em->createQueryBuilder(); + $qb->select('d, dr, c') + ->from(__NAMESPACE__ . '\GH5762Driver', 'd') + ->leftJoin('d.driverRides', 'dr') + ->leftJoin('dr.car', 'c') + ->where('d.id = 1'); + + return $qb->getQuery()->getSingleResult(); + } + + private function createData() + { + $car1 = new GH5762Car('BMW', '7 Series'); + $car2 = new GH5762Car('Crysler', '300'); + $car3 = new GH5762Car('Dodge', 'Dart'); + $car4 = new GH5762Car('Mercedes', 'C-Class'); + $car5 = new GH5762Car('Volvo', 'XC90'); + + $driver = new GH5762Driver(1, 'John Doe'); + + $ride1 = new GH5762DriverRide($driver, $car1); + $ride2 = new GH5762DriverRide($driver, $car2); + $ride3 = new GH5762DriverRide($driver, $car3); + $ride4 = new GH5762DriverRide($driver, $car4); + $ride5 = new GH5762DriverRide($driver, $car5); + + $this->_em->persist($car1); + $this->_em->persist($car2); + $this->_em->persist($car3); + $this->_em->persist($car4); + $this->_em->persist($car5); + + $this->_em->persist($driver); + + $this->_em->persist($ride1); + $this->_em->persist($ride2); + $this->_em->persist($ride3); + $this->_em->persist($ride4); + $this->_em->persist($ride5); + + $this->_em->flush(); + $this->_em->clear(); + } +} + +/** + * @Entity + * @Table(name="driver") + */ +class GH5762Driver +{ + + /** + * @Id + * @Column(type="integer") + * @GeneratedValue(strategy="NONE") + */ + private $id; + + /** + * @Column(type="string", length=255); + */ + private $name; + + /** + * @OneToMany(targetEntity="GH5762DriverRide", mappedBy="driver") + */ + private $driverRides; + + function __construct($id, $name) + { + $this->driverRides = new ArrayCollection(); + $this->id = $id; + $this->name = $name; + } + + function getId() + { + return $this->id; + } + + function getName() + { + return $this->name; + } + + function getDriverRides() + { + return $this->driverRides; + } +} + +/** + * @Entity + * @Table(name="driver_ride") + */ +class GH5762DriverRide +{ + + /** + * @Id + * @ManyToOne(targetEntity="GH5762Driver", inversedBy="driverRides") + * @JoinColumn(name="driver_id", referencedColumnName="id") + */ + private $driver; + + /** + * @Id + * @ManyToOne(targetEntity="GH5762Car", inversedBy="carRides") + * @JoinColumn(name="car", referencedColumnName="brand") + */ + private $car; + + function __construct(GH5762Driver $driver, GH5762Car $car) + { + $this->driver = $driver; + $this->car = $car; + + $this->driver->getDriverRides()->add($this); + $this->car->getCarRides()->add($this); + } + + function getDriver() + { + return $this->driver; + } + + function getCar() + { + return $this->car; + } +} + +/** + * @Entity + * @Table(name="car") + */ +class GH5762Car +{ + + /** + * @Id + * @Column(type="string", length=25) + * @GeneratedValue(strategy="NONE") + */ + private $brand; + + /** + * @Column(type="string", length=255); + */ + private $model; + + /** + * @OneToMany(targetEntity="GH5762DriverRide", mappedBy="car") + */ + private $carRides; + + function __construct($brand, $model) + { + $this->carRides = new ArrayCollection(); + $this->brand = $brand; + $this->model = $model; + } + + function getBrand() + { + return $this->brand; + } + + function getModel() + { + return $this->model; + } + + function getCarRides() + { + return $this->carRides; + } +} From 5eedccc22ab6c46f5563e4dbb6e4b9c1b2da9ea9 Mon Sep 17 00:00:00 2001 From: Alexander Kurilo Date: Mon, 29 Aug 2016 23:17:24 +0300 Subject: [PATCH 2/5] Remove irrelevant accessors (#5762) --- .../ORM/Functional/Ticket/GH5762Test.php | 84 +++++-------------- 1 file changed, 21 insertions(+), 63 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5762Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5762Test.php index 809417c04..ff3dac7e6 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5762Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5762Test.php @@ -15,9 +15,9 @@ class GH5762Test extends \Doctrine\Tests\OrmFunctionalTestCase parent::setup(); $this->_schemaTool->createSchema(array( - $this->_em->getClassMetadata(__NAMESPACE__ . '\GH5762Driver'), - $this->_em->getClassMetadata(__NAMESPACE__ . '\GH5762DriverRide'), - $this->_em->getClassMetadata(__NAMESPACE__ . '\GH5762Car'), + $this->_em->getClassMetadata(GH5762Driver::class), + $this->_em->getClassMetadata(GH5762DriverRide::class), + $this->_em->getClassMetadata(GH5762Car::class), )); } @@ -26,13 +26,13 @@ class GH5762Test extends \Doctrine\Tests\OrmFunctionalTestCase $result = $this->fetchData(); $this->assertInstanceOf(__NAMESPACE__ . '\GH5762Driver', $result); - $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result->getDriverRides()); - $this->assertInstanceOf(__NAMESPACE__ . '\GH5762DriverRide', $result->getDriverRides()->get(0)); - $this->assertInstanceOf(__NAMESPACE__ . '\GH5762Car', $result->getDriverRides()->get(0)->getCar()); + $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result->driverRides); + $this->assertInstanceOf(__NAMESPACE__ . '\GH5762DriverRide', $result->driverRides->get(0)); + $this->assertInstanceOf(__NAMESPACE__ . '\GH5762Car', $result->driverRides->get(0)->car); $cars = array(); - foreach ($result->getDriverRides() as $ride) { - $cars[] = $ride->getCar()->getBrand(); + foreach ($result->driverRides as $ride) { + $cars[] = $ride->car->brand; } $this->assertEquals(count($cars), count(array_unique($cars))); @@ -93,50 +93,34 @@ class GH5762Test extends \Doctrine\Tests\OrmFunctionalTestCase } /** - * @Entity + * @Entity * @Table(name="driver") */ class GH5762Driver { - /** * @Id * @Column(type="integer") * @GeneratedValue(strategy="NONE") */ - private $id; + public $id; /** * @Column(type="string", length=255); */ - private $name; + public $name; /** * @OneToMany(targetEntity="GH5762DriverRide", mappedBy="driver") */ - private $driverRides; + public $driverRides; - function __construct($id, $name) + public function __construct($id, $name) { $this->driverRides = new ArrayCollection(); $this->id = $id; $this->name = $name; } - - function getId() - { - return $this->id; - } - - function getName() - { - return $this->name; - } - - function getDriverRides() - { - return $this->driverRides; - } } /** @@ -145,38 +129,27 @@ class GH5762Driver */ class GH5762DriverRide { - /** * @Id * @ManyToOne(targetEntity="GH5762Driver", inversedBy="driverRides") * @JoinColumn(name="driver_id", referencedColumnName="id") */ - private $driver; + public $driver; /** * @Id * @ManyToOne(targetEntity="GH5762Car", inversedBy="carRides") * @JoinColumn(name="car", referencedColumnName="brand") */ - private $car; + public $car; function __construct(GH5762Driver $driver, GH5762Car $car) { $this->driver = $driver; $this->car = $car; - $this->driver->getDriverRides()->add($this); - $this->car->getCarRides()->add($this); - } - - function getDriver() - { - return $this->driver; - } - - function getCar() - { - return $this->car; + $this->driver->driverRides->add($this); + $this->car->carRides->add($this); } } @@ -192,37 +165,22 @@ class GH5762Car * @Column(type="string", length=25) * @GeneratedValue(strategy="NONE") */ - private $brand; + public $brand; /** * @Column(type="string", length=255); */ - private $model; + public $model; /** * @OneToMany(targetEntity="GH5762DriverRide", mappedBy="car") */ - private $carRides; + public $carRides; - function __construct($brand, $model) + public function __construct($brand, $model) { $this->carRides = new ArrayCollection(); $this->brand = $brand; $this->model = $model; } - - function getBrand() - { - return $this->brand; - } - - function getModel() - { - return $this->model; - } - - function getCarRides() - { - return $this->carRides; - } } From 6ab27993fc08810689bc11ac50ac25b853943951 Mon Sep 17 00:00:00 2001 From: Alexander Kurilo Date: Mon, 29 Aug 2016 22:29:41 +0300 Subject: [PATCH 3/5] Use ::class const instead of FQCN string (#5762) --- .../Tests/ORM/Functional/Ticket/GH5762Test.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5762Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5762Test.php index ff3dac7e6..a602921de 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5762Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5762Test.php @@ -3,11 +3,13 @@ namespace Doctrine\Tests\ORM\Functional\Ticket; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\ORM\PersistentCollection; +use Doctrine\Tests\OrmFunctionalTestCase; /** * @group GH-5762 */ -class GH5762Test extends \Doctrine\Tests\OrmFunctionalTestCase +class GH5762Test extends OrmFunctionalTestCase { protected function setup() @@ -25,10 +27,10 @@ class GH5762Test extends \Doctrine\Tests\OrmFunctionalTestCase { $result = $this->fetchData(); - $this->assertInstanceOf(__NAMESPACE__ . '\GH5762Driver', $result); - $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result->driverRides); - $this->assertInstanceOf(__NAMESPACE__ . '\GH5762DriverRide', $result->driverRides->get(0)); - $this->assertInstanceOf(__NAMESPACE__ . '\GH5762Car', $result->driverRides->get(0)->car); + $this->assertInstanceOf(GH5762Driver::class, $result); + $this->assertInstanceOf(PersistentCollection::class, $result->driverRides); + $this->assertInstanceOf(GH5762DriverRide::class, $result->driverRides->get(0)); + $this->assertInstanceOf(GH5762Car::class, $result->driverRides->get(0)->car); $cars = array(); foreach ($result->driverRides as $ride) { @@ -49,7 +51,7 @@ class GH5762Test extends \Doctrine\Tests\OrmFunctionalTestCase $qb = $this->_em->createQueryBuilder(); $qb->select('d, dr, c') - ->from(__NAMESPACE__ . '\GH5762Driver', 'd') + ->from(GH5762Driver::class, 'd') ->leftJoin('d.driverRides', 'dr') ->leftJoin('dr.car', 'c') ->where('d.id = 1'); From c4a2a348f4e1ca72da76cea187c939d6a8fbd2f7 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Wed, 7 Sep 2016 23:17:40 +0200 Subject: [PATCH 4/5] #5975 short array syntax --- lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php index d7a429f00..f9039e7ab 100644 --- a/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php +++ b/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php @@ -333,7 +333,7 @@ class ObjectHydrator extends AbstractHydrator $rowData = $this->gatherRowData($row, $id, $nonemptyComponents); // reset result pointers for each data row - $this->resultPointers = array(); + $this->resultPointers = []; // Hydrate the data chunks foreach ($rowData['data'] as $dqlAlias => $data) { From aa6dc9695d8d81c14561606b8634907605ba3c0d Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Wed, 7 Sep 2016 23:18:39 +0200 Subject: [PATCH 5/5] #5975 minor test cleanups --- .../ORM/Functional/Ticket/GH5762Test.php | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5762Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5762Test.php index a602921de..b42dd6534 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5762Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5762Test.php @@ -11,10 +11,9 @@ use Doctrine\Tests\OrmFunctionalTestCase; */ class GH5762Test extends OrmFunctionalTestCase { - - protected function setup() + protected function setUp() { - parent::setup(); + parent::setUp(); $this->_schemaTool->createSchema(array( $this->_em->getClassMetadata(GH5762Driver::class), @@ -27,22 +26,23 @@ class GH5762Test extends OrmFunctionalTestCase { $result = $this->fetchData(); - $this->assertInstanceOf(GH5762Driver::class, $result); - $this->assertInstanceOf(PersistentCollection::class, $result->driverRides); - $this->assertInstanceOf(GH5762DriverRide::class, $result->driverRides->get(0)); - $this->assertInstanceOf(GH5762Car::class, $result->driverRides->get(0)->car); + self::assertInstanceOf(GH5762Driver::class, $result); + self::assertInstanceOf(PersistentCollection::class, $result->driverRides); + self::assertInstanceOf(GH5762DriverRide::class, $result->driverRides->get(0)); + self::assertInstanceOf(GH5762Car::class, $result->driverRides->get(0)->car); $cars = array(); foreach ($result->driverRides as $ride) { $cars[] = $ride->car->brand; } - $this->assertEquals(count($cars), count(array_unique($cars))); - $this->assertContains('BMW', $cars); - $this->assertContains('Crysler', $cars); - $this->assertContains('Dodge', $cars); - $this->assertContains('Mercedes', $cars); - $this->assertContains('Volvo', $cars); + self::assertEquals(count($cars), count(array_unique($cars))); + + self::assertContains('BMW', $cars); + self::assertContains('Crysler', $cars); + self::assertContains('Dodge', $cars); + self::assertContains('Mercedes', $cars); + self::assertContains('Volvo', $cars); } private function fetchData()