Commit 7bbdac1c authored by romanb's avatar romanb

[2.0][DDC-61][DDC-108] Fixed. Started exception refactoring.

parent 460aeeb1
......@@ -6,7 +6,11 @@
This section details the changes made to Doctrine 2.0-ALPHA3 to make it easier for you
to upgrade your projects to use this version.
## CLI Changes
The $args variable used in the cli-config.php for configuring the Doctrine CLI has been renamed to $globalArguments.
## Proxy class changes
You are now required to make supply some minimalist configuration with regards to proxy objects. That involves 2 new configuration options. First, the directory where generated proxy classes should be placed needs to be specified. Secondly, you need to configure the namespace used for proxy classes. The following snippet shows an example:
......
......@@ -252,7 +252,7 @@ class Parser
(! $this->_isNestedAnnotation && $this->_lexer->lookahead != null &&
! $this->_lexer->isNextToken('(') &&
! $this->_lexer->isNextToken('@')) ||
! class_exists($name) ||
! class_exists($name, false) ||
! is_subclass_of($name, 'Doctrine\Common\Annotations\Annotation')
) {
$this->_lexer->skipUntil('@');
......
......@@ -96,9 +96,9 @@ class IsolatedClassLoader
*/
public function loadClass($className)
{
if (class_exists($className, false) || interface_exists($className, false)) {
/*if (class_exists($className, false) || interface_exists($className, false)) {
return false;
}
}*/
if (strpos($className, $this->_namespace.$this->_namespaceSeparator) !== 0) {
return false;
......
......@@ -2,4 +2,10 @@
namespace Doctrine\DBAL;
class DBALException extends \Exception {}
\ No newline at end of file
class DBALException extends \Exception
{
public static function notSupported($method)
{
return new self("Operation '$method' is not supported.");
}
}
\ No newline at end of file
......@@ -21,7 +21,7 @@
namespace Doctrine\DBAL\Platforms;
use Doctrine\Common\DoctrineException,
use Doctrine\DBAL\DBALException,
Doctrine\DBAL\Connection,
Doctrine\DBAL\Types;
......@@ -103,7 +103,7 @@ abstract class AbstractPlatform
*/
public function getRegexpExpression()
{
throw DoctrineException::regularExpressionOperatorNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
/**
......@@ -374,7 +374,7 @@ abstract class AbstractPlatform
$values = $this->getIdentifiers($values);
if (count($values) == 0) {
throw DoctrineException::valuesArrayForInOperatorInvalid();
throw \InvalidArgumentException('Values must not be empty.');
}
return $column . ' IN (' . implode(', ', $values) . ')';
}
......@@ -537,7 +537,7 @@ abstract class AbstractPlatform
*/
public function getCreateSequenceSql($sequenceName, $start = 1, $allocationSize = 1)
{
throw DoctrineException::createSequenceNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
/**
......@@ -591,7 +591,7 @@ abstract class AbstractPlatform
public function getCreateIndexSql($table, $name, array $definition)
{
if ( ! isset($definition['columns'])) {
throw DoctrineException::indexFieldsArrayRequired();
throw \InvalidArgumentException("Incomplete definition. 'columns' required.");
}
$type = '';
......@@ -601,7 +601,7 @@ abstract class AbstractPlatform
$type = strtoupper($definition['type']) . ' ';
break;
default:
throw DoctrineException::unknownIndexType($definition['type']);
throw \InvalidArgumentException('Unknown type: ' . $definition['type']);
}
}
......@@ -658,7 +658,7 @@ abstract class AbstractPlatform
*/
public function getAlterTableSql($name, array $changes, $check = false)
{
throw DoctrineException::alterTableNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
/**
......@@ -870,12 +870,12 @@ abstract class AbstractPlatform
if (strtolower($definition['type']) == 'unique') {
$type = strtoupper($definition['type']) . ' ';
} else {
throw DoctrineException::unknownIndexType($definition['type']);
throw \InvalidArgumentException('Invalid type: ' . $definition['type']);
}
}
if ( ! isset($definition['columns']) || ! is_array($definition['columns'])) {
throw DoctrineException::indexFieldsArrayRequired();
throw \InvalidArgumentException("Incomplete definition. 'columns' required.");
}
$query = $type . 'INDEX ' . $name;
......@@ -931,7 +931,7 @@ abstract class AbstractPlatform
*/
public function getShowDatabasesSql()
{
throw DoctrineException::showDatabasesNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
/**
......@@ -1023,7 +1023,7 @@ abstract class AbstractPlatform
return $upper;
break;
default:
throw DoctrineException::unknownForeignKeyReferentialAction($upper);
throw \InvalidArgumentException('Invalid foreign key action: ' . $upper);
}
}
......@@ -1043,13 +1043,13 @@ abstract class AbstractPlatform
$sql .= 'FOREIGN KEY (';
if ( ! isset($definition['local'])) {
throw DoctrineException::localReferenceFieldMissing();
throw new \InvalidArgumentException("Incomplete definition. 'local' required.");
}
if ( ! isset($definition['foreign'])) {
throw DoctrineException::foreignReferenceFieldMissing();
throw new \InvalidArgumentException("Incomplete definition. 'foreign' required.");
}
if ( ! isset($definition['foreignTable'])) {
throw DoctrineException::foreignReferenceTableMissing();
throw new \InvalidArgumentException("Incomplete definition. 'foreignTable' required.");
}
if ( ! is_array($definition['local'])) {
......@@ -1124,7 +1124,7 @@ abstract class AbstractPlatform
*/
public function getMatchPatternExpression($pattern, $operator = null, $field = null)
{
throw DoctrineException::matchPatternExpressionNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
/**
......@@ -1231,88 +1231,88 @@ abstract class AbstractPlatform
case Connection::TRANSACTION_SERIALIZABLE:
return 'SERIALIZABLE';
default:
throw DoctrineException::isolationLevelNotSupported($isolation);
throw new \InvalidArgumentException('Invalid isolation level:' . $level);
}
}
public function getListDatabasesSql()
{
throw DoctrineException::listDatabasesNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
public function getListFunctionsSql()
{
throw DoctrineException::listFunctionsNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
public function getListTriggersSql($table = null)
{
throw DoctrineException::listTriggersNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
public function getListSequencesSql($database)
{
throw DoctrineException::listSequencesNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
public function getListTableConstraintsSql($table)
{
throw DoctrineException::listTableConstraintsNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
public function getListTableColumnsSql($table)
{
throw DoctrineException::listTableColumnsNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
public function getListTablesSql()
{
throw DoctrineException::listTablesNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
public function getListUsersSql()
{
throw DoctrineException::listUsersNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
public function getListViewsSql()
{
throw DoctrineException::listViewsNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
public function getListTableIndexesSql($table)
{
throw DoctrineException::listTableIndexesNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
public function getListTableForeignKeysSql($table)
{
throw DoctrineException::listTableForeignKeysNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
public function getCreateViewSql($name, $sql)
{
throw DoctrineException::createViewNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
public function getDropViewSql($name)
{
throw DoctrineException::dropViewNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
public function getDropSequenceSql($sequenceName)
{
throw DoctrineException::dropSequenceNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
public function getSequenceNextValSql($sequenceName)
{
throw DoctrineException::sequenceNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
public function getCreateDatabaseSql($database)
{
throw DoctrineException::createDatabaseNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
/**
......@@ -1322,7 +1322,7 @@ abstract class AbstractPlatform
*/
public function getSetTransactionIsolationSql($level)
{
throw DoctrineException::setTransactionIsolationLevelNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
/**
......@@ -1335,7 +1335,7 @@ abstract class AbstractPlatform
*/
public function getCharsetFieldDeclaration($charset)
{
throw DoctrineException::getCharsetFieldDeclarationNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
/**
......@@ -1347,7 +1347,7 @@ abstract class AbstractPlatform
*/
public function getDateTimeTypeDeclarationSql(array $fieldDeclaration)
{
throw DoctrineException::getDateTimeTypeDeclarationNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
/**
......@@ -1359,7 +1359,7 @@ abstract class AbstractPlatform
*/
public function getDateTypeDeclarationSql(array $fieldDeclaration)
{
throw DoctrineException::getDateTypeDeclarationNotSupported($this);
throw DBALException::notSupported(__METHOD__);
}
/**
......
......@@ -70,6 +70,8 @@ final class ClassMetadata extends ClassMetadataInfo
$this->namespace = $this->reflClass->getNamespaceName();
$this->primaryTable['name'] = $this->reflClass->getShortName();
$this->rootEntityName = $entityName;
//$this->prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
}
/**
......@@ -366,5 +368,9 @@ final class ClassMetadata extends ClassMetadataInfo
$this->reflFields[$field] = $this->reflClass->getProperty($field);
$this->reflFields[$field]->setAccessible(true);
}
//$this->prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
}
//public $prototype;
}
......@@ -214,34 +214,33 @@ class OneToOneMapping extends AssociationMapping
*/
public function load($sourceEntity, $targetEntity, $em, array $joinColumnValues = array())
{
$sourceClass = $em->getClassMetadata($this->sourceEntityName);
$targetClass = $em->getClassMetadata($this->targetEntityName);
$conditions = array();
if ($this->isOwningSide) {
foreach ($this->sourceToTargetKeyColumns as $sourceKeyColumn => $targetKeyColumn) {
if (isset($sourceClass->fieldNames[$sourceKeyColumn])) {
$conditions[$targetKeyColumn] = $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity);
} else {
$conditions[$targetKeyColumn] = $joinColumnValues[$sourceKeyColumn];
}
}
$inverseField = isset($targetClass->inverseMappings[$this->sourceEntityName][$this->sourceFieldName]) ?
$targetClass->inverseMappings[$this->sourceEntityName][$this->sourceFieldName]->sourceFieldName
: false;
$targetEntity = $em->getUnitOfWork()->getEntityPersister($this->targetEntityName)->load($conditions, $targetEntity, $this);
$hints = array();
if ($inverseField) {
$hints['fetched'][$targetClass->rootEntityName][$inverseField] = true;
}
$targetEntity = $em->getUnitOfWork()->getEntityPersister($this->targetEntityName)->load($joinColumnValues, $targetEntity, $this, $hints);
if ($targetEntity !== null && $targetClass->hasInverseAssociationMapping($this->sourceEntityName, $this->sourceFieldName)) {
$targetClass->setFieldValue($targetEntity,
$targetClass->inverseMappings[$this->sourceEntityName][$this->sourceFieldName]->sourceFieldName,
$sourceEntity);
if ($targetEntity !== null && $inverseField) {
$targetClass->reflFields[$inverseField]->setValue($targetEntity, $sourceEntity);
}
} else {
$owningAssoc = $em->getClassMetadata($this->targetEntityName)->getAssociationMapping($this->mappedByFieldName);
$conditions = array();
$sourceClass = $em->getClassMetadata($this->sourceEntityName);
$owningAssoc = $targetClass->getAssociationMapping($this->mappedByFieldName);
// TRICKY: since the association is specular source and target are flipped
foreach ($owningAssoc->targetToSourceKeyColumns as $sourceKeyColumn => $targetKeyColumn) {
if (isset($sourceClass->fieldNames[$sourceKeyColumn])) {
$conditions[$targetKeyColumn] = $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity);
} else {
//TODO: Should never happen. Exception?
$conditions[$targetKeyColumn] = $joinColumnValues[$sourceKeyColumn];
}
}
......
......@@ -406,16 +406,18 @@ class StandardEntityPersister
* @param array $criteria The criteria by which to load the entity.
* @param object $entity The entity to load the data into. If not specified,
* a new entity is created.
* @param $assoc The association that connects the entity to load to another entity, if any.
* @param array $hints Hints for entity creation.
* @return The loaded entity instance or NULL if the entity/the data can not be found.
*/
public function load(array $criteria, $entity = null, $assoc = null)
public function load(array $criteria, $entity = null, $assoc = null, array $hints = array())
{
$stmt = $this->_conn->prepare($this->_getSelectEntitiesSql($criteria, $assoc));
$stmt->execute(array_values($criteria));
$result = $stmt->fetch(Connection::FETCH_ASSOC);
$stmt->closeCursor();
return $this->_createEntity($result, $entity);
return $this->_createEntity($result, $entity, $hints);
}
/**
......@@ -557,10 +559,11 @@ class StandardEntityPersister
* Creates or fills a single entity object from an SQL result.
*
* @param $result The SQL result.
* @param $entity The entity object to fill.
* @param object $entity The entity object to fill.
* @param array $hints Hints for entity creation.
* @return object The filled and managed entity object.
*/
private function _createEntity($result, $entity = null)
private function _createEntity($result, $entity = null, array $hints = array())
{
if ($result === false) {
return null;
......@@ -582,8 +585,6 @@ class StandardEntityPersister
$joinColumnValues[$column] = $value;
}
}
$hints = array();
if ($entity !== null) {
$hints[Query::HINT_REFRESH] = true;
......
......@@ -588,23 +588,18 @@ class UnitOfWork implements PropertyChangedListener
$this->addToIdentityMap($entry);
}
// Collect the original data and changeset, recursing into associations.
$data = array();
$changeSet = array();
foreach ($targetClass->reflFields as $name => $refProp) {
$data[$name] = $refProp->getValue($entry);
$changeSet[$name] = array(null, $data[$name]);
if (isset($targetClass->associationMappings[$name])) {
if ($data[$name] !== null) {
$this->_computeAssociationChanges($targetClass->associationMappings[$name], $data[$name]);
}
}
}
// NEW entities are INSERTed within the current unit of work.
$this->_entityInsertions[$oid] = $entry;
$this->_entityChangeSets[$oid] = $changeSet;
$this->_originalEntityData[$oid] = $data;
$this->_computeEntityChanges($targetClass, $entry);
// Look for changes in associations of the entity
foreach ($targetClass->associationMappings as $assoc2) {
$val = $targetClass->reflFields[$assoc2->sourceFieldName]->getValue($entry);
if ($val !== null) {
$this->_computeAssociationChanges($assoc2, $val);
}
}
} else if ($state == self::STATE_REMOVED) {
throw DoctrineException::removedEntityInCollectionDetected();
}
......@@ -1675,6 +1670,7 @@ class UnitOfWork implements PropertyChangedListener
$oid = spl_object_hash($entity);
$overrideLocalValues = isset($hints[Query::HINT_REFRESH]);
} else {
//$entity = clone $class->prototype;
$entity = new $className;
$oid = spl_object_hash($entity);
$this->_entityIdentifiers[$oid] = $id;
......@@ -1702,7 +1698,7 @@ class UnitOfWork implements PropertyChangedListener
if ( ! isset($hints[Query::HINT_FORCE_PARTIAL_LOAD])) {
foreach ($class->associationMappings as $field => $assoc) {
// Check if the association is not among the fetch-joined associations already.
if (isset($hints['fetched'][$className][$field])) {
if (isset($hints['fetched'][$class->rootEntityName][$field])) {
continue;
}
......@@ -1728,16 +1724,21 @@ class UnitOfWork implements PropertyChangedListener
if (isset($this->_identityMap[$targetClass->rootEntityName][$relatedIdHash])) {
$newValue = $this->_identityMap[$targetClass->rootEntityName][$relatedIdHash];
} else {
$newValue = $this->_em->getProxyFactory()->getProxy($assoc->targetEntityName, $associatedId);
$this->_entityIdentifiers[spl_object_hash($newValue)] = $associatedId;
$this->_identityMap[$targetClass->rootEntityName][$relatedIdHash] = $newValue;
if ($targetClass->subClasses) {
// If it might be a subtype, it can not be lazy
$newValue = $assoc->load($entity, null, $this->_em, $associatedId);
} else {
$newValue = $this->_em->getProxyFactory()->getProxy($assoc->targetEntityName, $associatedId);
$this->_entityIdentifiers[spl_object_hash($newValue)] = $associatedId;
$this->_identityMap[$targetClass->rootEntityName][$relatedIdHash] = $newValue;
}
}
$this->_originalEntityData[$oid][$field] = $newValue;
$class->reflFields[$field]->setValue($entity, $newValue);
}
} else {
// Inverse side can never be lazy
$targetEntity = $assoc->load($entity, new $assoc->targetEntityName, $this->_em);
$targetEntity = $assoc->load($entity, null, $this->_em);
$class->reflFields[$field]->setValue($entity, $targetEntity);
}
} else {
......
......@@ -20,7 +20,7 @@ class ClassLoaderTest extends \Doctrine\Tests\DoctrineTestCase
$globalClassLoader->register();
}
public function testIsolatedClassLoaderReturnsFalseOnClassExists()
/*public function testIsolatedClassLoaderReturnsFalseOnClassExists()
{
$classLoader = new IsolatedClassLoader('ClassLoaderTest');
$classLoader->setBasePath( __DIR__);
......@@ -30,5 +30,5 @@ class ClassLoaderTest extends \Doctrine\Tests\DoctrineTestCase
$this->assertEquals($classLoader->loadClass('ClassLoaderTest_ClassA'), true);
$this->assertEquals($classLoader->loadClass('ClassLoaderTest_ClassA'), false);
$this->assertEquals($classLoader->loadClass('ClassLoaderTest_ClassC'), true);
}
}*/
}
\ No newline at end of file
......@@ -65,7 +65,7 @@ class OraclePlatformTest extends \Doctrine\Tests\DbalTestCase
}
/**
* @expectedException Doctrine\Common\DoctrineException
* @expectedException Doctrine\DBAL\DBALException
*/
public function testRLike()
{
......@@ -80,7 +80,7 @@ class OraclePlatformTest extends \Doctrine\Tests\DbalTestCase
}
/**
* @expectedException Doctrine\Common\DoctrineException
* @expectedException Doctrine\DBAL\DBALException
*/
public function testGetCharsetFieldDeclaration()
{
......@@ -108,7 +108,7 @@ class OraclePlatformTest extends \Doctrine\Tests\DbalTestCase
}
/**
* @expectedException Doctrine\Common\DoctrineException
* @expectedException Doctrine\DBAL\DBALException
*/
public function testShowDatabasesThrowsException()
{
......@@ -116,7 +116,7 @@ class OraclePlatformTest extends \Doctrine\Tests\DbalTestCase
}
/**
* @expectedException Doctrine\Common\DoctrineException
* @expectedException Doctrine\DBAL\DBALException
*/
public function testCreateDatabaseThrowsException()
{
......
......@@ -16,7 +16,7 @@ class CompanyEvent {
private $id;
/**
* @OneToOne(targetEntity="CompanyOrganization",cascade={"persist"})
* @ManyToOne(targetEntity="CompanyOrganization",cascade={"persist"})
* @JoinColumn(name="org_id", referencedColumnName="id")
*/
private $organization;
......@@ -32,4 +32,5 @@ class CompanyEvent {
public function setOrganization(CompanyOrganization $org) {
$this->organization = $org;
}
}
\ No newline at end of file
......@@ -27,4 +27,18 @@ class CompanyOrganization {
$this->events[] = $event;
$event->setOrganization($this);
}
/**
* @OneToOne(targetEntity="CompanyEvent", cascade={"persist"})
* @JoinColumn(name="main_event_id", referencedColumnName="id", nullable=true)
*/
private $mainevent;
public function getMainEvent() {
return $this->mainevent;
}
public function setMainEvent($event) {
$this->mainevent = $event;
}
}
\ No newline at end of file
......@@ -59,41 +59,6 @@ class EntityManagerTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals(\Doctrine\ORM\EntityManager::FLUSHMODE_COMMIT, $this->_em->getFlushMode());
}
public function testCommit_FlushModeOnCommit_FlushUnitOfWork()
{
$this->markTestSkipped('_unitOfWork is private, but EntityManager does not use getUnitofWork() all the time');
$uow = $this->getMock('\Doctrine\ORM\UnitOfWork', array(), array(), '', false);
$uow->expects($this->once())
->method('flush');
$this->_em->setUnitOfWork($uow);
$this->_em->setFlushMode(\Doctrine\ORM\EntityManager::FLUSHMODE_COMMIT);
$this->assertSame($uow, $this->_em->getUnitOfWork());
$this->_em->beginTransaction();
$this->_em->commit();
}
public function testCommit_FlushModeAuto_FlushUnitOfWork()
{
$this->markTestSkipped('_unitOfWork is private, but EntityManager does not use getUnitofWork() all the time');
$uow = $this->getMock('\Doctrine\ORM\UnitOfWork', array(), array(), '', false);
$uow->expects($this->once())
->method('flush');
$this->_em->setUnitOfWork($uow);
$this->_em->setFlushMode(\Doctrine\ORM\EntityManager::FLUSHMODE_AUTO);
$this->assertSame($uow, $this->_em->getUnitOfWork());
$this->_em->beginTransaction();
$this->_em->commit();
}
public function testCreateNativeQuery()
{
$rsm = new \Doctrine\ORM\Query\ResultSetMapping();
......
......@@ -24,6 +24,7 @@ class AllTests
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\NativeQueryTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\SingleTableInheritanceTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\ClassTableInheritanceTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\ClassTableInheritanceTest2');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\DetachedEntityTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\QueryCacheTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\ResultCacheTest');
......
......@@ -224,6 +224,7 @@ class ClassTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals(1, count($result));
$this->assertTrue($result[0] instanceof CompanyOrganization);
$this->assertNull($result[0]->getMainEvent());
$events = $result[0]->getEvents();
......@@ -238,4 +239,40 @@ class ClassTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertTrue($events[1] instanceof CompanyAuction);
}
}
public function testLazyLoading2()
{
$org = new CompanyOrganization;
$event1 = new CompanyAuction;
$event1->setData('auction');
$org->setMainEvent($event1);
$this->_em->persist($org);
$this->_em->flush();
$this->_em->clear();
$q = $this->_em->createQuery('select a from Doctrine\Tests\Models\Company\CompanyEvent a where a.id = ?1');
$q->setParameter(1, $event1->getId());
$result = $q->getResult();
$this->assertEquals(1, count($result));
$this->assertTrue($result[0] instanceof CompanyAuction, sprintf("Is of class %s",get_class($result[0])));
$this->_em->clear();
$q = $this->_em->createQuery('select a from Doctrine\Tests\Models\Company\CompanyOrganization a where a.id = ?1');
$q->setParameter(1, $org->getId());
$result = $q->getResult();
$this->assertEquals(1, count($result));
$this->assertTrue($result[0] instanceof CompanyOrganization);
$mainEvent = $result[0]->getMainEvent();
// mainEvent should have been loaded because it can't be lazy
$this->assertTrue($mainEvent instanceof CompanyAuction);
$this->assertFalse($mainEvent instanceof \Doctrine\ORM\Proxy\Proxy);
}
}
<?php
namespace Doctrine\Tests\ORM\Functional;
require_once __DIR__ . '/../../TestInit.php';
/**
* Functional tests for the Class Table Inheritance mapping strategy.
*
* @author robo
*/
class ClassTableInheritanceTest2 extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp() {
parent::setUp();
try {
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\CTIParent'),
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\CTIChild'),
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\CTIRelated')
));
} catch (\Exception $e) {
// Swallow all exceptions. We do not test the schema tool here.
}
}
public function testOneToOneAssocToBaseTypeBidirectional()
{
$child = new CTIChild;
$child->setData('hello');
$related = new CTIRelated;
$related->setCTIParent($child);
$this->_em->persist($related);
$this->_em->persist($child);
$this->_em->flush();
$this->_em->clear();
$relatedId = $related->getId();
$related2 = $this->_em->find('Doctrine\Tests\ORM\Functional\CTIRelated', $relatedId);
$this->assertTrue($related2 instanceof CTIRelated);
$this->assertTrue($related2->getCTIParent() instanceof CTIChild);
$this->assertFalse($related2->getCTIParent() instanceof \Doctrine\ORM\Proxy\Proxy);
$this->assertEquals('hello', $related2->getCTIParent()->getData());
$this->assertSame($related2, $related2->getCTIParent()->getRelated());
}
}
/**
* @Entity @Table(name="cti_parents")
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="type", type="string")
* @DiscriminatorMap({"parent" = "CTIParent", "child" = "CTIChild"})
*/
class CTIParent {
/**
* @Id @Column(type="integer")
* @GeneratedValue(strategy="AUTO")
*/
private $id;
/** @OneToOne(targetEntity="CTIRelated", mappedBy="ctiParent") */
private $related;
public function getId() {
return $this->id;
}
public function getRelated() {
return $this->related;
}
public function setRelated($related) {
$this->related = $related;
$related->setCTIParent($this);
}
}
/**
* @Entity @Table(name="cti_children")
*/
class CTIChild extends CTIParent {
/**
* @Column(type="string")
*/
private $data;
public function getData() {
return $this->data;
}
public function setData($data) {
$this->data = $data;
}
}
/** @Entity */
class CTIRelated {
/**
* @Id @Column(type="integer")
* @GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @OneToOne(targetEntity="CTIParent")
* @JoinColumn(name="ctiparent_id", referencedColumnName="id")
*/
private $ctiParent;
public function getId() {
return $this->id;
}
public function getCTIParent() {
return $this->ctiParent;
}
public function setCTIParent($ctiParent) {
$this->ctiParent = $ctiParent;
}
}
......@@ -104,6 +104,7 @@ class OrmFunctionalTestCase extends OrmTestCase
$conn->executeUpdate('DELETE FROM company_persons');
$conn->executeUpdate('DELETE FROM company_raffles');
$conn->executeUpdate('DELETE FROM company_auctions');
$conn->executeUpdate('UPDATE company_organizations SET main_event_id = NULL');
$conn->executeUpdate('DELETE FROM company_events');
$conn->executeUpdate('DELETE FROM company_organizations');
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment