2009-04-12 23:02:12 +04:00
< ? php
namespace Doctrine\Tests\ORM\Functional ;
2011-03-17 00:51:32 +03:00
use Doctrine\ORM\Mapping\ClassMetadata ;
2012-06-19 02:01:03 +04:00
use Doctrine\Common\Collections\Criteria ;
2009-04-12 23:02:12 +04:00
class SingleTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
2010-07-04 14:17:15 +04:00
private $salesPerson ;
private $engineers = array ();
private $fix ;
private $flex ;
private $ultra ;
public function setUp ()
{
$this -> useModelSet ( 'company' );
2009-04-12 23:02:12 +04:00
parent :: setUp ();
}
2010-07-04 14:17:15 +04:00
public function persistRelatedEmployees ()
{
$this -> salesPerson = new \Doctrine\Tests\Models\Company\CompanyEmployee ();
$this -> salesPerson -> setName ( 'Poor Sales Guy' );
$this -> salesPerson -> setDepartment ( 'Sales' );
$this -> salesPerson -> setSalary ( 100 );
$engineer1 = new \Doctrine\Tests\Models\Company\CompanyEmployee ();
$engineer1 -> setName ( 'Roman B.' );
$engineer1 -> setDepartment ( 'IT' );
$engineer1 -> setSalary ( 100 );
$this -> engineers [] = $engineer1 ;
$engineer2 = new \Doctrine\Tests\Models\Company\CompanyEmployee ();
$engineer2 -> setName ( 'Jonathan W.' );
$engineer2 -> setDepartment ( 'IT' );
$engineer2 -> setSalary ( 100 );
$this -> engineers [] = $engineer2 ;
$engineer3 = new \Doctrine\Tests\Models\Company\CompanyEmployee ();
$engineer3 -> setName ( 'Benjamin E.' );
$engineer3 -> setDepartment ( 'IT' );
$engineer3 -> setSalary ( 100 );
$this -> engineers [] = $engineer3 ;
$engineer4 = new \Doctrine\Tests\Models\Company\CompanyEmployee ();
$engineer4 -> setName ( 'Guilherme B.' );
$engineer4 -> setDepartment ( 'IT' );
$engineer4 -> setSalary ( 100 );
$this -> engineers [] = $engineer4 ;
$this -> _em -> persist ( $this -> salesPerson );
$this -> _em -> persist ( $engineer1 );
$this -> _em -> persist ( $engineer2 );
$this -> _em -> persist ( $engineer3 );
$this -> _em -> persist ( $engineer4 );
}
2009-04-12 23:02:12 +04:00
2010-07-04 14:17:15 +04:00
public function loadFullFixture ()
{
$this -> persistRelatedEmployees ();
$this -> fix = new \Doctrine\Tests\Models\Company\CompanyFixContract ();
$this -> fix -> setFixPrice ( 1000 );
$this -> fix -> setSalesPerson ( $this -> salesPerson );
$this -> fix -> addEngineer ( $this -> engineers [ 0 ]);
$this -> fix -> addEngineer ( $this -> engineers [ 1 ]);
$this -> fix -> markCompleted ();
$this -> flex = new \Doctrine\Tests\Models\Company\CompanyFlexContract ();
$this -> flex -> setSalesPerson ( $this -> salesPerson );
$this -> flex -> setHoursWorked ( 100 );
$this -> flex -> setPricePerHour ( 100 );
$this -> flex -> addEngineer ( $this -> engineers [ 2 ]);
$this -> flex -> addEngineer ( $this -> engineers [ 1 ]);
$this -> flex -> addEngineer ( $this -> engineers [ 3 ]);
$this -> flex -> markCompleted ();
$this -> ultra = new \Doctrine\Tests\Models\Company\CompanyFlexUltraContract ();
$this -> ultra -> setSalesPerson ( $this -> salesPerson );
$this -> ultra -> setHoursWorked ( 150 );
$this -> ultra -> setPricePerHour ( 150 );
$this -> ultra -> setMaxPrice ( 7000 );
$this -> ultra -> addEngineer ( $this -> engineers [ 3 ]);
$this -> ultra -> addEngineer ( $this -> engineers [ 0 ]);
$this -> _em -> persist ( $this -> fix );
$this -> _em -> persist ( $this -> flex );
$this -> _em -> persist ( $this -> ultra );
$this -> _em -> flush ();
$this -> _em -> clear ();
}
2009-05-03 15:49:48 +04:00
2010-07-04 14:17:15 +04:00
public function testPersistChildOfBaseClass ()
{
$this -> persistRelatedEmployees ();
2009-05-03 15:49:48 +04:00
2010-07-04 14:17:15 +04:00
$fixContract = new \Doctrine\Tests\Models\Company\CompanyFixContract ();
$fixContract -> setFixPrice ( 1000 );
$fixContract -> setSalesPerson ( $this -> salesPerson );
2009-05-29 01:06:24 +04:00
2010-07-04 14:17:15 +04:00
$this -> _em -> persist ( $fixContract );
2009-04-12 23:02:12 +04:00
$this -> _em -> flush ();
$this -> _em -> clear ();
2010-07-04 14:17:15 +04:00
$contract = $this -> _em -> find ( 'Doctrine\Tests\Models\Company\CompanyFixContract' , $fixContract -> getId ());
2009-05-03 14:58:16 +04:00
2011-02-20 00:50:58 +03:00
$this -> assertInstanceOf ( 'Doctrine\Tests\Models\Company\CompanyFixContract' , $contract );
2010-07-04 14:17:15 +04:00
$this -> assertEquals ( 1000 , $contract -> getFixPrice ());
$this -> assertEquals ( $this -> salesPerson -> getId (), $contract -> getSalesPerson () -> getId ());
}
2009-05-03 14:58:16 +04:00
2010-07-04 14:17:15 +04:00
public function testPersistDeepChildOfBaseClass ()
{
$this -> persistRelatedEmployees ();
2009-05-03 14:58:16 +04:00
2010-07-04 14:17:15 +04:00
$ultraContract = new \Doctrine\Tests\Models\Company\CompanyFlexUltraContract ();
$ultraContract -> setSalesPerson ( $this -> salesPerson );
$ultraContract -> setHoursWorked ( 100 );
$ultraContract -> setPricePerHour ( 50 );
$ultraContract -> setMaxPrice ( 7000 );
2010-04-26 15:02:30 +04:00
2010-07-04 14:17:15 +04:00
$this -> _em -> persist ( $ultraContract );
$this -> _em -> flush ();
2010-04-26 15:02:30 +04:00
$this -> _em -> clear ();
2010-07-04 14:17:15 +04:00
$contract = $this -> _em -> find ( 'Doctrine\Tests\Models\Company\CompanyFlexUltraContract' , $ultraContract -> getId ());
2009-05-03 14:58:16 +04:00
2011-02-20 00:50:58 +03:00
$this -> assertInstanceOf ( 'Doctrine\Tests\Models\Company\CompanyFlexUltraContract' , $contract );
2010-07-04 14:17:15 +04:00
$this -> assertEquals ( 7000 , $contract -> getMaxPrice ());
$this -> assertEquals ( 100 , $contract -> getHoursWorked ());
$this -> assertEquals ( 50 , $contract -> getPricePerHour ());
}
2009-05-03 14:58:16 +04:00
2010-07-04 14:17:15 +04:00
public function testChildClassLifecycleUpdate ()
{
$this -> loadFullFixture ();
2009-05-03 14:58:16 +04:00
2010-07-04 14:17:15 +04:00
$fix = $this -> _em -> find ( 'Doctrine\Tests\Models\Company\CompanyContract' , $this -> fix -> getId ());
$fix -> setFixPrice ( 2500 );
2009-11-13 13:11:14 +03:00
$this -> _em -> flush ();
$this -> _em -> clear ();
2010-07-04 14:17:15 +04:00
$newFix = $this -> _em -> find ( 'Doctrine\Tests\Models\Company\CompanyContract' , $this -> fix -> getId ());
$this -> assertEquals ( 2500 , $newFix -> getFixPrice ());
2009-04-12 23:02:12 +04:00
}
2010-07-04 14:17:15 +04:00
public function testChildClassLifecycleRemove ()
2009-11-16 20:03:33 +03:00
{
2010-07-04 14:17:15 +04:00
$this -> loadFullFixture ();
2009-11-16 20:03:33 +03:00
2010-07-04 14:17:15 +04:00
$fix = $this -> _em -> find ( 'Doctrine\Tests\Models\Company\CompanyContract' , $this -> fix -> getId ());
$this -> _em -> remove ( $fix );
2009-11-16 20:03:33 +03:00
$this -> _em -> flush ();
2010-07-04 14:17:15 +04:00
$this -> assertNull ( $this -> _em -> find ( 'Doctrine\Tests\Models\Company\CompanyContract' , $this -> fix -> getId ()));
2009-11-16 20:03:33 +03:00
}
2010-07-04 14:17:15 +04:00
public function testFindAllForAbstractBaseClass ()
2009-11-21 21:52:02 +03:00
{
2010-07-04 14:17:15 +04:00
$this -> loadFullFixture ();
$contracts = $this -> _em -> getRepository ( 'Doctrine\Tests\Models\Company\CompanyContract' ) -> findAll ();
2009-11-21 21:52:02 +03:00
2010-07-04 14:17:15 +04:00
$this -> assertEquals ( 3 , count ( $contracts ));
$this -> assertContainsOnly ( 'Doctrine\Tests\Models\Company\CompanyContract' , $contracts );
2009-11-21 21:52:02 +03:00
}
2009-04-12 23:02:12 +04:00
2010-07-04 14:17:15 +04:00
public function testFindAllForChildClass ()
{
$this -> loadFullFixture ();
2009-04-12 23:02:12 +04:00
2010-07-04 14:17:15 +04:00
$this -> assertEquals ( 1 , count ( $this -> _em -> getRepository ( 'Doctrine\Tests\Models\Company\CompanyFixContract' ) -> findAll ()));
$this -> assertEquals ( 2 , count ( $this -> _em -> getRepository ( 'Doctrine\Tests\Models\Company\CompanyFlexContract' ) -> findAll ()));
$this -> assertEquals ( 1 , count ( $this -> _em -> getRepository ( 'Doctrine\Tests\Models\Company\CompanyFlexUltraContract' ) -> findAll ()));
2009-04-12 23:02:12 +04:00
}
2010-07-04 14:17:15 +04:00
public function testFindForAbstractBaseClass ()
{
$this -> loadFullFixture ();
2009-04-12 23:02:12 +04:00
2010-07-04 14:17:15 +04:00
$contract = $this -> _em -> find ( 'Doctrine\Tests\Models\Company\CompanyContract' , $this -> fix -> getId ());
2011-02-20 00:50:58 +03:00
$this -> assertInstanceOf ( 'Doctrine\Tests\Models\Company\CompanyFixContract' , $contract );
2010-07-04 14:17:15 +04:00
$this -> assertEquals ( 1000 , $contract -> getFixPrice ());
2009-04-12 23:02:12 +04:00
}
2010-07-04 14:17:15 +04:00
public function testQueryForAbstractBaseClass ()
{
$this -> loadFullFixture ();
$contracts = $this -> _em -> createQuery ( 'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c' ) -> getResult ();
$this -> assertEquals ( 3 , count ( $contracts ));
$this -> assertContainsOnly ( 'Doctrine\Tests\Models\Company\CompanyContract' , $contracts );
2009-04-12 23:02:12 +04:00
}
2009-05-03 14:58:16 +04:00
2010-07-04 14:17:15 +04:00
public function testQueryForChildClass ()
{
$this -> loadFullFixture ();
$this -> assertEquals ( 1 , count ( $this -> _em -> createQuery ( 'SELECT c FROM Doctrine\Tests\Models\Company\CompanyFixContract c' ) -> getResult ()));
$this -> assertEquals ( 2 , count ( $this -> _em -> createQuery ( 'SELECT c FROM Doctrine\Tests\Models\Company\CompanyFlexContract c' ) -> getResult ()));
$this -> assertEquals ( 1 , count ( $this -> _em -> createQuery ( 'SELECT c FROM Doctrine\Tests\Models\Company\CompanyFlexUltraContract c' ) -> getResult ()));
2009-05-03 14:58:16 +04:00
}
2010-07-04 14:17:15 +04:00
public function testQueryBaseClassWithJoin ()
{
$this -> loadFullFixture ();
$contracts = $this -> _em -> createQuery ( 'SELECT c, p FROM Doctrine\Tests\Models\Company\CompanyContract c JOIN c.salesPerson p' ) -> getResult ();
$this -> assertEquals ( 3 , count ( $contracts ));
$this -> assertContainsOnly ( 'Doctrine\Tests\Models\Company\CompanyContract' , $contracts );
2009-05-03 14:58:16 +04:00
}
2009-04-12 23:02:12 +04:00
2010-07-04 14:17:15 +04:00
public function testQueryScalarWithDiscrimnatorValue ()
{
$this -> loadFullFixture ();
$contracts = $this -> _em -> createQuery ( 'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c ORDER BY c.id' ) -> getScalarResult ();
2010-07-04 15:34:14 +04:00
$discrValues = \array_map ( function ( $a ) {
return $a [ 'c_discr' ];
}, $contracts );
sort ( $discrValues );
$this -> assertEquals ( array ( 'fix' , 'flexible' , 'flexultra' ), $discrValues );
2009-05-03 14:58:16 +04:00
}
2010-07-04 14:17:15 +04:00
public function testQueryChildClassWithCondition ()
{
$this -> loadFullFixture ();
$dql = 'SELECT c FROM Doctrine\Tests\Models\Company\CompanyFixContract c WHERE c.fixPrice = ?1' ;
$contract = $this -> _em -> createQuery ( $dql ) -> setParameter ( 1 , 1000 ) -> getSingleResult ();
2011-02-20 00:50:58 +03:00
$this -> assertInstanceOf ( 'Doctrine\Tests\Models\Company\CompanyFixContract' , $contract );
2010-07-04 14:17:15 +04:00
$this -> assertEquals ( 1000 , $contract -> getFixPrice ());
2009-05-03 14:58:16 +04:00
}
2010-07-04 14:17:15 +04:00
public function testUpdateChildClassWithCondition ()
{
$this -> loadFullFixture ();
$dql = 'UPDATE Doctrine\Tests\Models\Company\CompanyFlexContract c SET c.hoursWorked = c.hoursWorked * 2 WHERE c.hoursWorked = 150' ;
$affected = $this -> _em -> createQuery ( $dql ) -> execute ();
$this -> assertEquals ( 1 , $affected );
$flexContract = $this -> _em -> find ( 'Doctrine\Tests\Models\Company\CompanyContract' , $this -> flex -> getId ());
$ultraContract = $this -> _em -> find ( 'Doctrine\Tests\Models\Company\CompanyContract' , $this -> ultra -> getId ());
$this -> assertEquals ( 300 , $ultraContract -> getHoursWorked ());
$this -> assertEquals ( 100 , $flexContract -> getHoursWorked ());
2009-05-03 14:58:16 +04:00
}
2010-07-04 14:17:15 +04:00
public function testUpdateBaseClassWithCondition ()
{
$this -> loadFullFixture ();
$dql = 'UPDATE Doctrine\Tests\Models\Company\CompanyContract c SET c.completed = true WHERE c.completed = false' ;
$affected = $this -> _em -> createQuery ( $dql ) -> execute ();
$this -> assertEquals ( 1 , $affected );
$dql = 'UPDATE Doctrine\Tests\Models\Company\CompanyContract c SET c.completed = false' ;
$affected = $this -> _em -> createQuery ( $dql ) -> execute ();
$this -> assertEquals ( 3 , $affected );
2009-05-03 14:58:16 +04:00
}
2010-07-04 14:17:15 +04:00
public function testDeleteByChildClassCondition ()
{
$this -> loadFullFixture ();
$dql = 'DELETE Doctrine\Tests\Models\Company\CompanyFlexContract c' ;
$affected = $this -> _em -> createQuery ( $dql ) -> execute ();
$this -> assertEquals ( 2 , $affected );
2009-05-03 14:58:16 +04:00
}
2009-12-03 16:17:56 +03:00
2010-07-04 14:17:15 +04:00
public function testDeleteByBaseClassCondition ()
{
$this -> loadFullFixture ();
$dql = " DELETE Doctrine \T ests \ Models \ Company \ CompanyContract c WHERE c.completed = true " ;
$affected = $this -> _em -> createQuery ( $dql ) -> execute ();
$this -> assertEquals ( 2 , $affected );
$contracts = $this -> _em -> createQuery ( 'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c' ) -> getResult ();
$this -> assertEquals ( 1 , count ( $contracts ));
$this -> assertFalse ( $contracts [ 0 ] -> isCompleted (), " Only non completed contracts should be left. " );
}
2010-07-10 00:55:30 +04:00
/**
* @ group DDC - 130
*/
public function testDeleteJoinTableRecords ()
{
$this -> loadFullFixture ();
// remove managed copy of the fix contract
$this -> _em -> remove ( $this -> _em -> find ( get_class ( $this -> fix ), $this -> fix -> getId ()));
$this -> _em -> flush ();
$this -> assertNull ( $this -> _em -> find ( get_class ( $this -> fix ), $this -> fix -> getId ()), " Contract should not be present in the database anymore. " );
}
2010-09-28 00:13:14 +04:00
/**
* @ group DDC - 817
*/
public function testFindByAssociation ()
{
$this -> loadFullFixture ();
$repos = $this -> _em -> getRepository ( " Doctrine \T ests \ Models \ Company \ CompanyContract " );
$contracts = $repos -> findBy ( array ( 'salesPerson' => $this -> salesPerson -> getId ()));
$this -> assertEquals ( 3 , count ( $contracts ), " There should be 3 entities related to " . $this -> salesPerson -> getId () . " for 'Doctrine \T ests \ Models \ Company \ CompanyContract' " );
$repos = $this -> _em -> getRepository ( " Doctrine \T ests \ Models \ Company \ CompanyFixContract " );
$contracts = $repos -> findBy ( array ( 'salesPerson' => $this -> salesPerson -> getId ()));
$this -> assertEquals ( 1 , count ( $contracts ), " There should be 1 entities related to " . $this -> salesPerson -> getId () . " for 'Doctrine \T ests \ Models \ Company \ CompanyFixContract' " );
$repos = $this -> _em -> getRepository ( " Doctrine \T ests \ Models \ Company \ CompanyFlexContract " );
$contracts = $repos -> findBy ( array ( 'salesPerson' => $this -> salesPerson -> getId ()));
$this -> assertEquals ( 2 , count ( $contracts ), " There should be 2 entities related to " . $this -> salesPerson -> getId () . " for 'Doctrine \T ests \ Models \ Company \ CompanyFlexContract' " );
$repos = $this -> _em -> getRepository ( " Doctrine \T ests \ Models \ Company \ CompanyFlexUltraContract " );
$contracts = $repos -> findBy ( array ( 'salesPerson' => $this -> salesPerson -> getId ()));
$this -> assertEquals ( 1 , count ( $contracts ), " There should be 1 entities related to " . $this -> salesPerson -> getId () . " for 'Doctrine \T ests \ Models \ Company \ CompanyFlexUltraContract' " );
}
2010-10-11 22:11:23 +04:00
2012-06-19 02:01:03 +04:00
/**
* @ group DDC - 1637
*/
public function testInheritanceMatching ()
{
$this -> loadFullFixture ();
$repository = $this -> _em -> getRepository ( " Doctrine \T ests \ Models \ Company \ CompanyContract " );
$contracts = $repository -> matching ( new Criteria (
2012-08-01 23:37:22 +04:00
Criteria :: expr () -> eq ( 'salesPerson' , $this -> salesPerson -> getId ())
2012-06-19 02:01:03 +04:00
));
$this -> assertEquals ( 3 , count ( $contracts ));
$repository = $this -> _em -> getRepository ( " Doctrine \T ests \ Models \ Company \ CompanyFixContract " );
$contracts = $repository -> matching ( new Criteria (
2012-08-01 23:37:22 +04:00
Criteria :: expr () -> eq ( 'salesPerson' , $this -> salesPerson -> getId ())
2012-06-19 02:01:03 +04:00
));
$this -> assertEquals ( 1 , count ( $contracts ));
}
2010-10-11 22:11:23 +04:00
/**
* @ group DDC - 834
*/
public function testGetReferenceEntityWithSubclasses ()
{
$this -> loadFullFixture ();
$ref = $this -> _em -> getReference ( 'Doctrine\Tests\Models\Company\CompanyContract' , $this -> fix -> getId ());
2011-02-20 00:50:58 +03:00
$this -> assertNotInstanceOf ( 'Doctrine\ORM\Proxy\Proxy' , $ref , " Cannot Request a proxy from a class that has subclasses. " );
$this -> assertInstanceOf ( 'Doctrine\Tests\Models\Company\CompanyContract' , $ref );
$this -> assertInstanceOf ( 'Doctrine\Tests\Models\Company\CompanyFixContract' , $ref , " Direct fetch of the reference has to load the child class Emplyoee directly. " );
2010-10-11 22:11:23 +04:00
$this -> _em -> clear ();
$ref = $this -> _em -> getReference ( 'Doctrine\Tests\Models\Company\CompanyFixContract' , $this -> fix -> getId ());
2011-02-20 00:50:58 +03:00
$this -> assertInstanceOf ( 'Doctrine\ORM\Proxy\Proxy' , $ref , " A proxy can be generated only if no subclasses exists for the requested reference. " );
2010-10-11 22:11:23 +04:00
}
2011-03-17 00:51:32 +03:00
/**
* @ group DDC - 952
*/
public function testEagerLoadInheritanceHierachy ()
{
$this -> loadFullFixture ();
$dql = 'SELECT f FROM Doctrine\Tests\Models\Company\CompanyFixContract f WHERE f.id = ?1' ;
$contract = $this -> _em -> createQuery ( $dql )
-> setFetchMode ( 'Doctrine\Tests\Models\Company\CompanyFixContract' , 'salesPerson' , ClassMetadata :: FETCH_EAGER )
-> setParameter ( 1 , $this -> fix -> getId ())
-> getSingleResult ();
$this -> assertNotInstanceOf ( 'Doctrine\ORM\Proxy\Proxy' , $contract -> getSalesPerson ());
}
2009-12-03 16:17:56 +03:00
}