Commit 30ed4391 authored by romanb's avatar romanb

[2.0][DDC-144][DDC-113] Fixed.

parent 3d14da41
...@@ -16,4 +16,9 @@ class LifecycleEventArgs extends \Doctrine\Common\EventArgs ...@@ -16,4 +16,9 @@ class LifecycleEventArgs extends \Doctrine\Common\EventArgs
{ {
return $this->_entity; return $this->_entity;
} }
public function getEntityManager()
{
return $this->_em;
}
} }
\ No newline at end of file
...@@ -79,7 +79,7 @@ class AnnotationDriver implements Driver ...@@ -79,7 +79,7 @@ class AnnotationDriver implements Driver
} else if (isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass'])) { } else if (isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass'])) {
$metadata->isMappedSuperclass = true; $metadata->isMappedSuperclass = true;
} else { } else {
throw DoctrineException::classIsNotAValidEntityOrMapperSuperClass($className); throw DoctrineException::classIsNotAValidEntityOrMappedSuperClass($className);
} }
// Evaluate DoctrineTable annotation // Evaluate DoctrineTable annotation
......
...@@ -64,7 +64,7 @@ class JoinedSubclassPersister extends StandardEntityPersister ...@@ -64,7 +64,7 @@ class JoinedSubclassPersister extends StandardEntityPersister
*/ */
private function _getVersionedClassMetadata() private function _getVersionedClassMetadata()
{ {
if ($isVersioned = $this->_class->isVersioned) { if ($this->_class->isVersioned) {
if (isset($this->_class->fieldMappings[$this->_class->versionField]['inherited'])) { if (isset($this->_class->fieldMappings[$this->_class->versionField]['inherited'])) {
$definingClassName = $this->_class->fieldMappings[$this->_class->versionField]['inherited']; $definingClassName = $this->_class->fieldMappings[$this->_class->versionField]['inherited'];
$versionedClass = $this->_em->getClassMetadata($definingClassName); $versionedClass = $this->_em->getClassMetadata($definingClassName);
...@@ -125,43 +125,59 @@ class JoinedSubclassPersister extends StandardEntityPersister ...@@ -125,43 +125,59 @@ class JoinedSubclassPersister extends StandardEntityPersister
$idGen = $this->_class->idGenerator; $idGen = $this->_class->idGenerator;
$isPostInsertId = $idGen->isPostInsertGenerator(); $isPostInsertId = $idGen->isPostInsertGenerator();
// Prepare statements for all tables // Prepare statement for the root table
$stmts = $classes = array(); $rootClass = $this->_class->name == $this->_class->rootEntityName ?
$stmts[$this->_class->primaryTable['name']] = $this->_conn->prepare($this->getInsertSql()); $this->_class : $this->_em->getClassMetadata($this->_class->rootEntityName);
$rootPersister = $this->_em->getUnitOfWork()->getEntityPersister($rootClass->name);
$rootTableName = $rootClass->primaryTable['name'];
$rootTableStmt = $this->_conn->prepare($rootPersister->getInsertSql());
if ($this->_sqlLogger !== null) { if ($this->_sqlLogger !== null) {
$sql[$this->_class->primaryTable['name']] = $this->getInsertSql(); $sql = array();
$sql[$rootTableName] = $rootPersister->getInsertSql();
}
// Prepare statements for sub tables.
$subTableStmts = array();
if ($rootClass !== $this->_class) {
$subTableStmts[$this->_class->primaryTable['name']] = $this->_conn->prepare($this->getInsertSql());
if ($this->_sqlLogger !== null) {
$sql[$this->_class->primaryTable['name']] = $this->getInsertSql();
}
} }
foreach ($this->_class->parentClasses as $parentClassName) { foreach ($this->_class->parentClasses as $parentClassName) {
$parentClass = $this->_em->getClassMetadata($parentClassName); $parentClass = $this->_em->getClassMetadata($parentClassName);
$parentPersister = $this->_em->getUnitOfWork()->getEntityPersister($parentClassName); $parentTableName = $parentClass->primaryTable['name'];
$stmts[$parentClass->primaryTable['name']] = $this->_conn->prepare($parentPersister->getInsertSql()); if ($parentClass !== $rootClass) {
if ($this->_sqlLogger !== null) { $parentPersister = $this->_em->getUnitOfWork()->getEntityPersister($parentClassName);
$sql[$parentClass->primaryTable['name']] = $parentPersister->getInsertSql(); $subTableStmts[$parentTableName] = $this->_conn->prepare($parentPersister->getInsertSql());
if ($this->_sqlLogger !== null) {
$sql[$parentTableName] = $parentPersister->getInsertSql();
}
} }
} }
$rootTableName = $this->_em->getClassMetadata($this->_class->rootEntityName)->primaryTable['name'];
// Execute all inserts. For each entity:
// 1) Insert on root table
// 2) Insert on sub tables
foreach ($this->_queuedInserts as $entity) { foreach ($this->_queuedInserts as $entity) {
$insertData = array(); $insertData = array();
$this->_prepareData($entity, $insertData, true); $this->_prepareData($entity, $insertData, true);
// Execute insert on root table // Execute insert on root table
$stmt = $stmts[$rootTableName];
$paramIndex = 1; $paramIndex = 1;
if ($this->_sqlLogger !== null) { if ($this->_sqlLogger !== null) {
$params = array(); $params = array();
foreach ($insertData[$rootTableName] as $columnName => $value) { foreach ($insertData[$rootTableName] as $columnName => $value) {
$params[$paramIndex] = $value; $params[$paramIndex] = $value;
$stmt->bindValue($paramIndex++, $value); $rootTableStmt->bindValue($paramIndex++, $value);
} }
$this->_sqlLogger->logSql($sql[$rootTableName], $params); $this->_sqlLogger->logSql($sql[$rootTableName], $params);
} else { } else {
foreach ($insertData[$rootTableName] as $columnName => $value) { foreach ($insertData[$rootTableName] as $columnName => $value) {
$stmt->bindValue($paramIndex++, $value); $rootTableStmt->bindValue($paramIndex++, $value);
} }
} }
$stmt->execute(); $rootTableStmt->execute();
unset($insertData[$rootTableName]);
if ($isPostInsertId) { if ($isPostInsertId) {
$id = $idGen->generate($this->_em, $entity); $id = $idGen->generate($this->_em, $entity);
...@@ -170,9 +186,10 @@ class JoinedSubclassPersister extends StandardEntityPersister ...@@ -170,9 +186,10 @@ class JoinedSubclassPersister extends StandardEntityPersister
$id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity); $id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity);
} }
// Execute inserts on subtables // Execute inserts on subtables.
foreach ($insertData as $tableName => $data) { // The order doesn't matter because all child tables link to the root table via FK.
$stmt = $stmts[$tableName]; foreach ($subTableStmts as $tableName => $stmt) {
$data = isset($insertData[$tableName]) ? $insertData[$tableName] : array();
$paramIndex = 1; $paramIndex = 1;
if ($this->_sqlLogger !== null) { if ($this->_sqlLogger !== null) {
$params = array(); $params = array();
...@@ -197,7 +214,8 @@ class JoinedSubclassPersister extends StandardEntityPersister ...@@ -197,7 +214,8 @@ class JoinedSubclassPersister extends StandardEntityPersister
} }
} }
foreach ($stmts as $stmt) { $rootTableStmt->closeCursor();
foreach ($subTableStmts as $stmt) {
$stmt->closeCursor(); $stmt->closeCursor();
} }
......
...@@ -168,6 +168,8 @@ class StandardEntityPersister ...@@ -168,6 +168,8 @@ class StandardEntityPersister
$stmt->bindValue($paramIndex++, $value); $stmt->bindValue($paramIndex++, $value);
} }
} }
} else if ($this->_sqlLogger !== null) {
$this->_sqlLogger->logSql($this->getInsertSql());
} }
$stmt->execute(); $stmt->execute();
......
...@@ -370,12 +370,6 @@ class UnitOfWork implements PropertyChangedListener ...@@ -370,12 +370,6 @@ class UnitOfWork implements PropertyChangedListener
* Computes all the changes that have been done to entities and collections * Computes all the changes that have been done to entities and collections
* since the last commit and stores these changes in the _entityChangeSet map * since the last commit and stores these changes in the _entityChangeSet map
* temporarily for access by the persisters, until the UoW commit is finished. * temporarily for access by the persisters, until the UoW commit is finished.
*
* @param array $entities The entities for which to compute the changesets. If this
* parameter is not specified, the changesets of all entities in the identity
* map are computed if automatic dirty checking is enabled (the default).
* If automatic dirty checking is disabled, only those changesets will be
* computed that have been scheduled through scheduleForDirtyCheck().
*/ */
public function computeChangeSets() public function computeChangeSets()
{ {
...@@ -579,6 +573,13 @@ class UnitOfWork implements PropertyChangedListener ...@@ -579,6 +573,13 @@ class UnitOfWork implements PropertyChangedListener
$state = $this->getEntityState($entry, self::STATE_NEW); $state = $this->getEntityState($entry, self::STATE_NEW);
$oid = spl_object_hash($entry); $oid = spl_object_hash($entry);
if ($state == self::STATE_NEW) { if ($state == self::STATE_NEW) {
if (isset($targetClass->lifecycleCallbacks[Events::prePersist])) {
$targetClass->invokeLifecycleCallbacks(Events::prePersist, $entry);
}
if ($this->_evm->hasListeners(Events::prePersist)) {
$this->_evm->dispatchEvent(Events::prePersist, new LifecycleEventArgs($entry));
}
// Get identifier, if possible (not post-insert) // Get identifier, if possible (not post-insert)
$idGen = $targetClass->idGenerator; $idGen = $targetClass->idGenerator;
if ( ! $idGen->isPostInsertGenerator()) { if ( ! $idGen->isPostInsertGenerator()) {
...@@ -696,7 +697,7 @@ class UnitOfWork implements PropertyChangedListener ...@@ -696,7 +697,7 @@ class UnitOfWork implements PropertyChangedListener
} }
} }
} }
$postInsertIds = $persister->executeInserts(); $postInsertIds = $persister->executeInserts();
if ($postInsertIds) { if ($postInsertIds) {
...@@ -866,7 +867,7 @@ class UnitOfWork implements PropertyChangedListener ...@@ -866,7 +867,7 @@ class UnitOfWork implements PropertyChangedListener
} }
$this->_entityInsertions[$oid] = $entity; $this->_entityInsertions[$oid] = $entity;
if (isset($this->_entityIdentifiers[$oid])) { if (isset($this->_entityIdentifiers[$oid])) {
$this->addToIdentityMap($entity); $this->addToIdentityMap($entity);
} }
......
...@@ -72,18 +72,24 @@ class SqliteSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -72,18 +72,24 @@ class SqliteSchemaManagerTest extends SchemaManagerFunctionalTestCase
/** /**
* @expectedException \Exception * @expectedException \Exception
*/ */
public function testCreateSequence() // This test is not correct. createSequence expects an object.
// PHPUnit wrapping the PHP error in an exception hides this but it shows up
// when the tests are run in the build (phing).
/*public function testCreateSequence()
{ {
$this->_sm->createSequence('seqname', 1, 1); $this->_sm->createSequence('seqname', 1, 1);
} }*/
/** /**
* @expectedException \Exception * @expectedException \Exception
*/ */
public function testCreateForeignKey() // This test is not correct. createForeignKey expects an object.
// PHPUnit wrapping the PHP error in an exception hides this but it shows up
// when the tests are run in the build (phing).
/*public function testCreateForeignKey()
{ {
$this->_sm->createForeignKey('table', array()); $this->_sm->createForeignKey('table', array());
} }*/
/** /**
* @expectedException \Exception * @expectedException \Exception
......
...@@ -8,4 +8,6 @@ class SchemaManagerMock extends \Doctrine\DBAL\Schema\AbstractSchemaManager ...@@ -8,4 +8,6 @@ class SchemaManagerMock extends \Doctrine\DBAL\Schema\AbstractSchemaManager
{ {
parent::__construct($conn); parent::__construct($conn);
} }
protected function _getPortableTableColumnDefinition($tableColumn) {}
} }
\ No newline at end of file
...@@ -86,14 +86,20 @@ class LifecycleCallbackTest extends \Doctrine\Tests\OrmFunctionalTestCase ...@@ -86,14 +86,20 @@ class LifecycleCallbackTest extends \Doctrine\Tests\OrmFunctionalTestCase
*/ */
public function testCascadedEntitiesCallsPrePersist() public function testCascadedEntitiesCallsPrePersist()
{ {
//$this->_em->getConnection()->getConfiguration()->setSqlLogger(new \Doctrine\DBAL\Logging\EchoSqlLogger);
$e1 = new LifecycleCallbackTestEntity; $e1 = new LifecycleCallbackTestEntity;
$e2 = new LifecycleCallbackTestEntity; $e2 = new LifecycleCallbackTestEntity;
$c = new LifecycleCallbackCascader(); $c = new LifecycleCallbackCascader();
$this->_em->persist($c);
$c->entities[] = $e1; $c->entities[] = $e1;
$c->entities[] = $e2; $c->entities[] = $e2;
$e1->cascader = $c;
$this->_em->persist($c); $e2->cascader = $c;
//$this->_em->persist($c);
$this->_em->flush(); $this->_em->flush();
$this->assertTrue($e1->prePersistCallbackInvoked); $this->assertTrue($e1->prePersistCallbackInvoked);
...@@ -184,7 +190,7 @@ class LifecycleCallbackCascader ...@@ -184,7 +190,7 @@ class LifecycleCallbackCascader
private $id; private $id;
/** /**
* @OneToMany(targetEntity="LifecycleCallbackTestEntity", mappedBy="product", cascade={"persist"}) * @OneToMany(targetEntity="LifecycleCallbackTestEntity", mappedBy="cascader", cascade={"persist"})
*/ */
public $entities; public $entities;
......
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
require_once __DIR__ . '/../../../TestInit.php';
class DDC144Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp() {
parent::setUp();
//$this->_em->getConnection()->getConfiguration()->setSqlLogger(new \Doctrine\DBAL\Logging\EchoSqlLogger);
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC144FlowElement'),
// $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC144Expression'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC144Operand'),
));
}
/**
* @group DDC-144
*/
public function testIssue()
{
$operand = new DDC144Operand;
$operand->property = 'flowValue';
$operand->operandProperty = 'operandValue';
$this->_em->persist($operand);
$this->_em->flush();
}
}
/**
* @Entity
* @Table(name="ddc144_flowelements")
* @InheritanceType("JOINED")
* @DiscriminatorColumn(type="string", name="discr")
* @DiscriminatorMap({"flowelement" = "DDC144FlowElement", "operand" = "DDC144Operand"})
*/
class DDC144FlowElement {
/**
* @Id @Column(type="integer") @GeneratedValue(strategy="AUTO")
* @var integer
*/
public $id;
/** @Column(type="string") */
public $property;
}
// /** @Entity @Table(name="ddc144_expressions") */
abstract class DDC144Expression extends DDC144FlowElement {
abstract function method();
}
/** @Entity @Table(name="ddc144_operands") */
class DDC144Operand extends DDC144Expression {
/** @Column(type="string") */
public $operandProperty;
function method() {}
}
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