1
0
mirror of synced 2024-12-12 22:36:02 +03:00

[2.0] DDC-337 - Collections that are fetched through StandardEntityPersister and ordered are sorted by any given ORDER BY snippet. Now only the DQL Parser is missing in this regard.

This commit is contained in:
beberlei 2010-02-14 21:21:43 +00:00
parent ab3a6cc16e
commit 30d1b54db1
6 changed files with 155 additions and 5 deletions

View File

@ -135,6 +135,6 @@ class OneToManyMapping extends AssociationMapping
}
}
$persister->loadOneToManyCollection($conditions, $targetCollection);
$persister->loadOneToManyCollection($this, $conditions, $targetCollection);
}
}

View File

@ -540,14 +540,20 @@ class StandardEntityPersister
/**
* Loads a collection of entities in a one-to-many association.
*
* @param OneToManyMapping $assoc
* @param array $criteria The criteria by which to select the entities.
* @param PersistentCollection The collection to fill.
*/
public function loadOneToManyCollection(array $criteria, PersistentCollection $coll)
public function loadOneToManyCollection($assoc, array $criteria, PersistentCollection $coll)
{
$owningAssoc = $this->_class->associationMappings[$coll->getMapping()->mappedByFieldName];
$sql = $this->_getSelectEntitiesSql($criteria, $owningAssoc);
if ($assoc->orderBy !== null) {
$sql .= ' ORDER BY '.str_replace('%alias%', $this->_class->getTableName(), $assoc->orderBy);
}
$params = array_values($criteria);
if ($this->_sqlLogger !== null) {
@ -565,6 +571,7 @@ class StandardEntityPersister
/**
* Loads a collection of entities of a many-to-many association.
*
* @param ManyToManyMapping $assoc
* @param array $criteria
* @param PersistentCollection $coll The collection to fill.
*/
@ -716,7 +723,8 @@ class StandardEntityPersister
/**
* Gets the SQL to select a collection of entities in a many-many association.
*
*
* @param ManyToManyMapping $assoc
* @param array $criteria
* @return string
*/
@ -750,11 +758,16 @@ class StandardEntityPersister
$columnName = $joinTableName . '.' . $owningAssoc->getQuotedJoinColumnName($joinColumn, $this->_platform);
$conditionSql .= $columnName . ' = ?';
}
$orderBySql = '';
if ($manyToMany->orderBy !== null) {
$orderBySql = ' ORDER BY '.str_replace('%alias%', $this->_class->getTableName(), $manyToMany->orderBy);
}
return 'SELECT ' . $this->_getSelectColumnList()
. ' FROM ' . $this->_class->getQuotedTableName($this->_platform)
. $joinSql
. ' WHERE ' . $conditionSql;
. ' WHERE ' . $conditionSql . $orderBySql;
}
/** @override */

View File

@ -18,4 +18,9 @@ class RoutingLocation
* @Column(type="string")
*/
public $name;
public function getName()
{
return $this->name;
}
}

View File

@ -17,14 +17,21 @@ class RoutingRoute
public $id;
/**
* @ManyToMany(targetEntity="Doctrine\Tests\Models\Routing\RoutingLeg", cascade={"all"})
* @ManyToMany(targetEntity="RoutingLeg", cascade={"all"})
* @JoinTable(name="RoutingRouteLegs",
* joinColumns={@JoinColumn(name="route_id", referencedColumnName="id")},
* inverseJoinColumns={@JoinColumn(name="leg_id", referencedColumnName="id", unique=true)}
* )
* @OrderBy("%alias%.departureDate ASC")
*/
public $legs;
/**
* @OneToMany(targetEntity="RoutingRouteBooking", mappedBy="route")
* @OrderBy("%alias%.passengerName ASC")
*/
public $bookings = array();
public function __construct()
{
$this->legs = new ArrayCollection();

View File

@ -0,0 +1,32 @@
<?php
namespace Doctrine\Tests\Models\Routing;
/**
* @Entity
*/
class RoutingRouteBooking
{
/**
* @Id
* @Column(type="integer")
* @generatedValue(strategy="AUTO")
*/
public $id;
/**
* @ManyToOne(targetEntity="RoutingRoute")
* @JoinColumn(name="route_id", referencedColumnName="id")
*/
public $route;
/**
* @Column(type="string")
*/
public $passengerName = null;
public function getPassengerName()
{
return $this->passengerName;
}
}

View File

@ -0,0 +1,93 @@
<?php
namespace Doctrine\Tests\ORM\Functional;
use Doctrine\Tests\Models\Routing\RoutingRoute;
use Doctrine\Tests\Models\Routing\RoutingLocation;
use Doctrine\Tests\Models\Routing\RoutingLeg;
use Doctrine\Tests\Models\Routing\RoutingRouteBooking;
require_once __DIR__ . '/../../TestInit.php';
class OrderedAssociationTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected $locations = array();
public function setUp()
{
$this->useModelSet('routing');
parent::setUp();
$locations = array("Berlin", "Bonn", "Brasilia", "Atlanta");
foreach ($locations AS $locationName) {
$location = new RoutingLocation();
$location->name = $locationName;
$this->_em->persist($location);
$this->locations[$locationName] = $location;
}
$this->_em->flush();
}
public function testLazyManyToManyCollection_IsRetrievedWithOrderByClause()
{
$route = new RoutingRoute();
$leg1 = new RoutingLeg();
$leg1->fromLocation = $this->locations['Berlin'];
$leg1->toLocation = $this->locations['Bonn'];
$leg1->departureDate = new \DateTime("now");
$leg1->arrivalDate = new \DateTime("now +5 hours");
$leg2 = new RoutingLeg();
$leg2->fromLocation = $this->locations['Bonn'];
$leg2->toLocation = $this->locations['Brasilia'];
$leg2->departureDate = new \DateTime("now +6 hours");
$leg2->arrivalDate = new \DateTime("now +24 hours");
$route->legs[] = $leg2;
$route->legs[] = $leg1;
$this->_em->persist($route);
$this->_em->flush();
$routeId = $route->id;
$this->_em->clear();
$route = $this->_em->find('Doctrine\Tests\Models\Routing\RoutingRoute', $routeId);
$this->assertEquals(2, count($route->legs));
$this->assertEquals("Berlin", $route->legs[0]->fromLocation->getName());
$this->assertEquals("Bonn", $route->legs[1]->fromLocation->getName());
}
public function testLazyOneToManyCollection_IsRetrievedWithOrderByClause()
{
$route = new RoutingRoute();
$this->_em->persist($route);
$this->_em->flush();
$routeId = $route->id;
$booking1 = new RoutingRouteBooking();
$booking1->passengerName = "Guilherme";
$booking2 = new RoutingRouteBooking();
$booking2->passengerName = "Benjamin";
$route->bookings[] = $booking1;
$booking1->route = $route;
$route->bookings[] = $booking2;
$booking2->route = $route;
$this->_em->persist($booking1);
$this->_em->persist($booking2);
$this->_em->flush();
$this->_em->clear();
$route = $this->_em->find('Doctrine\Tests\Models\Routing\RoutingRoute', $routeId);
$this->assertEquals(2, count($route->bookings));
$this->assertEquals('Benjamin', $route->bookings[0]->getPassengerName());
$this->assertEquals('Guilherme', $route->bookings[1]->getPassengerName());
}
}