[2.0] Progress on UnitOfWork, persisters and basic functional tests.
This commit is contained in:
parent
36763dadb6
commit
e202cb1ce1
29 changed files with 533 additions and 296 deletions
|
@ -23,7 +23,6 @@ namespace Doctrine\DBAL;
|
|||
|
||||
use Doctrine\Common\EventManager;
|
||||
use Doctrine\Common\DoctrineException;
|
||||
#use Doctrine\DBAL\Exceptions\ConnectionException;
|
||||
|
||||
/**
|
||||
* A wrapper around a Doctrine\DBAL\Driver\Connection that adds features like
|
||||
|
@ -251,7 +250,6 @@ class Connection
|
|||
/**
|
||||
* Deletes table row(s) matching the specified identifier.
|
||||
*
|
||||
* @throws Doctrine_Connection_Exception if something went wrong at the database level
|
||||
* @param string $table The table to delete data from
|
||||
* @param array $identifier An associateve array containing identifier fieldname-value pairs.
|
||||
* @return integer The number of affected rows
|
||||
|
@ -289,12 +287,7 @@ class Connection
|
|||
|
||||
$set = array();
|
||||
foreach ($data as $columnName => $value) {
|
||||
if ($value instanceof Doctrine_Expression) {
|
||||
$set[] = $this->quoteIdentifier($columnName) . ' = ' . $value->getSql();
|
||||
unset($data[$columnName]);
|
||||
} else {
|
||||
$set[] = $this->quoteIdentifier($columnName) . ' = ?';
|
||||
}
|
||||
$set[] = $this->quoteIdentifier($columnName) . ' = ?';
|
||||
}
|
||||
|
||||
$params = array_merge(array_values($data), array_values($identifier));
|
||||
|
@ -328,12 +321,7 @@ class Connection
|
|||
$a = array();
|
||||
foreach ($data as $columnName => $value) {
|
||||
$cols[] = $this->quoteIdentifier($columnName);
|
||||
if ($value instanceof Doctrine_DBAL_Expression) {
|
||||
$a[] = $value->getSql();
|
||||
unset($data[$columnName]);
|
||||
} else {
|
||||
$a[] = '?';
|
||||
}
|
||||
$a[] = '?';
|
||||
}
|
||||
|
||||
$query = 'INSERT INTO ' . $this->quoteIdentifier($tableName)
|
||||
|
@ -495,13 +483,8 @@ class Connection
|
|||
*/
|
||||
public function prepare($statement)
|
||||
{
|
||||
echo $statement . PHP_EOL;
|
||||
$this->connect();
|
||||
try {
|
||||
return $this->_conn->prepare($statement);
|
||||
} catch (PDOException $e) {
|
||||
$this->rethrowException($e, $this);
|
||||
}
|
||||
return $this->_conn->prepare($statement);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -571,6 +554,7 @@ class Connection
|
|||
return $count;
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
//TODO: Wrap
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
@ -688,7 +672,7 @@ class Connection
|
|||
{
|
||||
$this->connect();
|
||||
if ($this->_transactionNestingLevel == 0) {
|
||||
return $this->_conn->beginTransaction();
|
||||
$this->_conn->beginTransaction();
|
||||
}
|
||||
++$this->_transactionNestingLevel;
|
||||
return true;
|
||||
|
@ -710,7 +694,7 @@ class Connection
|
|||
$this->connect();
|
||||
|
||||
if ($this->_transactionNestingLevel == 1) {
|
||||
return $this->_conn->commit();
|
||||
$this->_conn->commit();
|
||||
}
|
||||
--$this->_transactionNestingLevel;
|
||||
|
||||
|
@ -740,7 +724,7 @@ class Connection
|
|||
|
||||
if ($this->_transactionNestingLevel == 1) {
|
||||
$this->_transactionNestingLevel = 0;
|
||||
return $this->_conn->rollback();
|
||||
$this->_conn->rollback();
|
||||
|
||||
}
|
||||
--$this->_transactionNestingLevel;
|
||||
|
@ -807,7 +791,7 @@ class Connection
|
|||
protected function _getSequenceName($sqn)
|
||||
{
|
||||
return sprintf($this->conn->getAttribute(Doctrine::ATTR_SEQNAME_FORMAT),
|
||||
preg_replace('/[^a-z0-9_\$.]/i', '_', $sqn));
|
||||
preg_replace('/[^a-z0-9_\$.]/i', '_', $sqn));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -819,7 +803,7 @@ class Connection
|
|||
protected function _getIndexName($idx)
|
||||
{
|
||||
return sprintf($this->conn->getAttribute(Doctrine::ATTR_IDXNAME_FORMAT),
|
||||
preg_replace('/[^a-z0-9_\$]/i', '_', $idx));
|
||||
preg_replace('/[^a-z0-9_\$]/i', '_', $idx));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -835,15 +819,6 @@ class Connection
|
|||
return sprintf($this->conn->getAttribute(Doctrine::ATTR_TBLNAME_FORMAT),
|
||||
$table);*/
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a string representation of this object
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return Doctrine_Lib::getConnectionAsString($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the wrapped driver connection.
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
<?php
|
||||
|
||||
#namespace Doctrine\DBAL\Driver\PDOMySql;
|
||||
namespace Doctrine\DBAL\Driver\PDOMySql;
|
||||
|
||||
#use Doctrine\DBAL\Driver;
|
||||
|
||||
class Doctrine_DBAL_Driver_PDOMySql_Driver implements Doctrine_DBAL_Driver
|
||||
class Driver implements \Doctrine\DBAL\Driver
|
||||
{
|
||||
/**
|
||||
* Attempts to establish a connection with the underlying driver.
|
||||
|
@ -17,12 +15,12 @@ class Doctrine_DBAL_Driver_PDOMySql_Driver implements Doctrine_DBAL_Driver
|
|||
*/
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
|
||||
{
|
||||
$conn = new Doctrine_DBAL_Driver_PDOConnection(
|
||||
$conn = new \Doctrine\DBAL\Driver\PDOConnection(
|
||||
$this->_constructPdoDsn($params),
|
||||
$username,
|
||||
$password,
|
||||
$driverOptions);
|
||||
$conn->setAttribute(PDO::ATTR_AUTOCOMMIT, false);
|
||||
$conn->setAttribute(\PDO::ATTR_AUTOCOMMIT, false);
|
||||
return $conn;
|
||||
}
|
||||
|
||||
|
@ -54,12 +52,12 @@ class Doctrine_DBAL_Driver_PDOMySql_Driver implements Doctrine_DBAL_Driver
|
|||
|
||||
public function getDatabasePlatform()
|
||||
{
|
||||
return new Doctrine_DBAL_Platforms_MySqlPlatform();
|
||||
return new \Doctrine\DBAL\Platforms\MySqlPlatform();
|
||||
}
|
||||
|
||||
public function getSchemaManager(Doctrine_DBAL_Connection $conn)
|
||||
public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
|
||||
{
|
||||
return new Doctrine_DBAL_Schema_MySqlSchemaManager($conn);
|
||||
return new \Doctrine\DBAL\Schema\MySqlSchemaManager($conn);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -400,56 +400,42 @@ class SqlitePlatform extends AbstractPlatform
|
|||
/** @override */
|
||||
public function getIntegerTypeDeclarationSql(array $field)
|
||||
{
|
||||
return 'INT ' . $this->_getCommonIntegerTypeDeclarationSql($field);
|
||||
return $this->_getCommonIntegerTypeDeclarationSql($field);
|
||||
}
|
||||
|
||||
/** @override */
|
||||
public function getBigIntTypeDeclarationSql(array $field)
|
||||
{
|
||||
return 'BIGINT ' . $this->_getCommonIntegerTypeDeclarationSql($field);
|
||||
return $this->_getCommonIntegerTypeDeclarationSql($field);
|
||||
}
|
||||
|
||||
/** @override */
|
||||
public function getTinyIntTypeDeclarationSql(array $field)
|
||||
{
|
||||
return 'TINYINT ' . $this->_getCommonIntegerTypeDeclarationSql($field);
|
||||
return $this->_getCommonIntegerTypeDeclarationSql($field);
|
||||
}
|
||||
|
||||
/** @override */
|
||||
public function getSmallIntTypeDeclarationSql(array $field)
|
||||
{
|
||||
return 'SMALLINT ' . $this->_getCommonIntegerTypeDeclarationSql($field);
|
||||
return $this->_getCommonIntegerTypeDeclarationSql($field);
|
||||
}
|
||||
|
||||
/** @override */
|
||||
public function getMediumIntTypeDeclarationSql(array $field)
|
||||
{
|
||||
return 'MEDIUMINT ' . $this->_getCommonIntegerTypeDeclarationSql($field);
|
||||
return $this->_getCommonIntegerTypeDeclarationSql($field);
|
||||
}
|
||||
|
||||
/** @override */
|
||||
protected function _getCommonIntegerTypeDeclarationSql(array $columnDef)
|
||||
{
|
||||
$default = $autoinc = '';
|
||||
if ( ! empty($columnDef['autoincrement'])) {
|
||||
$autoinc = ' AUTO_INCREMENT';
|
||||
} else if (array_key_exists('default', $columnDef)) {
|
||||
if ($field['default'] === '') {
|
||||
$field['default'] = empty($columnDef['notnull']) ? null : 0;
|
||||
}
|
||||
if (is_null($columnDef['default'])) {
|
||||
$default = ' DEFAULT NULL';
|
||||
} else {
|
||||
$default = ' DEFAULT ' . $this->quote($columnDef['default']);
|
||||
}
|
||||
} else if (empty($columnDef['notnull'])) {
|
||||
$default = ' DEFAULT NULL';
|
||||
}
|
||||
$autoinc = ! empty($columnDef['autoincrement']) ? 'AUTOINCREMENT' : '';
|
||||
$pk = ! empty($columnDef['primary']) ? 'PRIMARY KEY' : '';
|
||||
|
||||
$notnull = (isset($columnDef['notnull']) && $columnDef['notnull']) ? ' NOT NULL' : '';
|
||||
$unsigned = (isset($columnDef['unsigned']) && $columnDef['unsigned']) ? ' UNSIGNED' : '';
|
||||
//$unsigned = (isset($columnDef['unsigned']) && $columnDef['unsigned']) ? ' UNSIGNED' : '';
|
||||
|
||||
return $unsigned . $default . $notnull . $autoinc;
|
||||
return "INTEGER $pk $autoinc";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -494,14 +480,13 @@ class SqlitePlatform extends AbstractPlatform
|
|||
|
||||
$autoinc = false;
|
||||
foreach($fields as $field) {
|
||||
if (isset($field['autoincrement']) && $field['autoincrement'] ||
|
||||
(isset($field['autoinc']) && $field['autoinc'])) {
|
||||
if (isset($field['autoincrement']) && $field['autoincrement']) {
|
||||
$autoinc = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($options['primary']) && ! empty($options['primary'])) {
|
||||
if ( ! $autoinc && isset($options['primary']) && ! empty($options['primary'])) {
|
||||
$keyColumns = array_values($options['primary']);
|
||||
$keyColumns = array_map(array($this, 'quoteIdentifier'), $keyColumns);
|
||||
$queryFields.= ', PRIMARY KEY('.implode(', ', $keyColumns).')';
|
||||
|
|
|
@ -269,7 +269,7 @@ abstract class AbstractSchemaManager
|
|||
if ($count == 0) {
|
||||
$options['primary'] = array();
|
||||
}
|
||||
$count++;
|
||||
++$count;
|
||||
$options['primary'][] = $columnName;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -589,4 +589,3 @@ class SqliteSchemaManager extends AbstractSchemaManager
|
|||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -21,12 +21,12 @@
|
|||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
#use Doctrine\Common\Configuration;
|
||||
use Doctrine\Common\EventManager;
|
||||
use Doctrine\Common\DoctrineException;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\ORM\Exceptions\EntityManagerException;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Mapping\ClassMetadataFactory;
|
||||
|
||||
/**
|
||||
* The EntityManager is the central access point to ORM functionality.
|
||||
|
@ -96,13 +96,6 @@ class EntityManager
|
|||
*/
|
||||
private $_metadataFactory;
|
||||
|
||||
/**
|
||||
* The EntityPersister instances used to persist entity instances.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_persisters = array();
|
||||
|
||||
/**
|
||||
* The EntityRepository instances.
|
||||
*
|
||||
|
@ -167,7 +160,7 @@ class EntityManager
|
|||
$this->_name = $name;
|
||||
$this->_config = $config;
|
||||
$this->_eventManager = $eventManager;
|
||||
$this->_metadataFactory = new \Doctrine\ORM\Mapping\ClassMetadataFactory(
|
||||
$this->_metadataFactory = new ClassMetadataFactory(
|
||||
$this->_config->getMetadataDriverImpl(),
|
||||
$this->_conn->getDatabasePlatform());
|
||||
$this->_metadataFactory->setCacheDriver($this->_config->getMetadataCacheImpl());
|
||||
|
@ -285,28 +278,6 @@ class EntityManager
|
|||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the EntityPersister for an Entity.
|
||||
*
|
||||
* This is usually not of interest for users, mainly for internal use.
|
||||
*
|
||||
* @param string $entityName The name of the Entity.
|
||||
* @return Doctrine\ORM\Persister\AbstractEntityPersister
|
||||
*/
|
||||
public function getEntityPersister($entityName)
|
||||
{
|
||||
if ( ! isset($this->_persisters[$entityName])) {
|
||||
$class = $this->getClassMetadata($entityName);
|
||||
if ($class->isInheritanceTypeJoined()) {
|
||||
$persister = new \Doctrine\ORM\Persisters\JoinedSubclassPersister($this, $class);
|
||||
} else {
|
||||
$persister = new \Doctrine\ORM\Persisters\StandardEntityPersister($this, $class);
|
||||
}
|
||||
$this->_persisters[$entityName] = $persister;
|
||||
}
|
||||
return $this->_persisters[$entityName];
|
||||
}
|
||||
|
||||
/**
|
||||
* Detaches an entity from the manager. It's lifecycle is no longer managed.
|
||||
*
|
||||
|
|
|
@ -69,6 +69,7 @@ class ClassExporter
|
|||
$column['name'] = $mapping['columnName'];
|
||||
$column['type'] = $mapping['type'];
|
||||
$column['length'] = $mapping['length'];
|
||||
$column['notnull'] = ! $mapping['nullable'];
|
||||
|
||||
if ($class->isIdentifier($fieldName)) {
|
||||
$column['primary'] = true;
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Doctrine\ORM\Id;
|
||||
|
||||
use Doctrine\Common\DoctrineException;
|
||||
|
||||
/**
|
||||
* Special generator for application-assigned identifiers (doesnt really generate anything).
|
||||
*
|
||||
|
@ -20,6 +22,7 @@ class Assigned extends AbstractIdGenerator
|
|||
public function generate($entity)
|
||||
{
|
||||
$class = $this->_em->getClassMetadata(get_class($entity));
|
||||
$identifier = null;
|
||||
if ($class->isIdentifierComposite()) {
|
||||
$identifier = array();
|
||||
$idFields = $class->getIdentifierFieldNames();
|
||||
|
@ -39,7 +42,7 @@ class Assigned extends AbstractIdGenerator
|
|||
}
|
||||
|
||||
if ( ! $identifier) {
|
||||
throw new Doctrine_Exception("Entity '$entity' is missing an assigned ID.");
|
||||
throw new DoctrineException("Entity of type '" . get_class($entity) . "' is missing an assigned ID.");
|
||||
}
|
||||
|
||||
return $identifier;
|
||||
|
|
|
@ -66,7 +66,6 @@ class ObjectHydrator extends AbstractHydrator
|
|||
foreach ($this->_collections as $coll) {
|
||||
$coll->_takeSnapshot();
|
||||
$coll->_setHydrationFlag(false);
|
||||
//$this->_uow->addManagedCollection($coll);
|
||||
}
|
||||
|
||||
// Clean up
|
||||
|
@ -116,7 +115,7 @@ class ObjectHydrator extends AbstractHydrator
|
|||
|
||||
private function getCollection($component)
|
||||
{
|
||||
$coll = new \Doctrine\ORM\Collection($this->_em, $component);
|
||||
$coll = new \Doctrine\ORM\PersistentCollection($this->_em, $component);
|
||||
$this->_collections[] = $coll;
|
||||
return $coll;
|
||||
}
|
||||
|
@ -338,7 +337,7 @@ class ObjectHydrator extends AbstractHydrator
|
|||
->getValue($baseElement));
|
||||
}
|
||||
} else if ( ! $this->isFieldSet($baseElement, $relationAlias)) {
|
||||
$coll = new \Doctrine\ORM\Collection($this->_em, $entityName);
|
||||
$coll = new \Doctrine\ORM\PersistentCollection($this->_em, $entityName);
|
||||
$this->_collections[] = $coll;
|
||||
$this->setRelatedElement($baseElement, $relationAlias, $coll);
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ class AnnotationDriver
|
|||
}
|
||||
$mapping['type'] = $columnAnnot->type;
|
||||
$mapping['length'] = $columnAnnot->length;
|
||||
$mapping['nullable'] = $columnAnnot->nullable;
|
||||
if ($idAnnot = $property->getAnnotation('DoctrineId')) {
|
||||
$mapping['id'] = true;
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@ final class DoctrineJoinColumn extends \Addendum\Annotation {
|
|||
final class DoctrineColumn extends \Addendum\Annotation {
|
||||
public $type;
|
||||
public $length;
|
||||
public $unique;
|
||||
public $nullable;
|
||||
public $unique = false;
|
||||
public $nullable = false;
|
||||
}
|
||||
final class DoctrineOneToOne extends \Addendum\Annotation {
|
||||
public $targetEntity;
|
||||
|
|
|
@ -128,12 +128,10 @@ class OneToOneMapping extends AssociationMapping
|
|||
$sourceClass = $entityManager->getClassMetadata($this->_sourceEntityName);
|
||||
$targetClass = $entityManager->getClassMetadata($this->_targetEntityName);
|
||||
|
||||
$dql = 'SELECT t.* FROM ' . $targetClass->getClassName() . ' t WHERE ';
|
||||
$dql = 'SELECT t FROM ' . $targetClass->getClassName() . ' t WHERE ';
|
||||
$params = array();
|
||||
foreach ($this->_sourceToTargetKeyFields as $sourceKeyField => $targetKeyField) {
|
||||
if ($params) {
|
||||
$dql .= " AND ";
|
||||
}
|
||||
if ($params) $dql .= " AND ";
|
||||
$dql .= "t.$targetKeyField = ?";
|
||||
$params[] = $sourceClass->getReflectionProperty($sourceKeyField)->getValue($entity);
|
||||
}
|
||||
|
|
|
@ -42,9 +42,8 @@ use Doctrine\ORM\Mapping\AssociationMapping;
|
|||
* @version $Revision: 4930 $
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @todo Rename to PersistentCollection
|
||||
*/
|
||||
final class Collection extends \Doctrine\Common\Collections\Collection
|
||||
final class PersistentCollection extends \Doctrine\Common\Collections\Collection
|
||||
{
|
||||
/**
|
||||
* The base type of the collection.
|
||||
|
@ -111,6 +110,8 @@ final class Collection extends \Doctrine\Common\Collections\Collection
|
|||
*/
|
||||
private $_ownerClass;
|
||||
|
||||
private $_isDirty = false;
|
||||
|
||||
/**
|
||||
* Creates a new persistent collection.
|
||||
*/
|
||||
|
@ -122,7 +123,7 @@ final class Collection extends \Doctrine\Common\Collections\Collection
|
|||
$this->_ownerClass = $em->getClassMetadata($entityBaseType);
|
||||
if ($keyField !== null) {
|
||||
if ( ! $this->_ownerClass->hasField($keyField)) {
|
||||
throw new Doctrine_Exception("Invalid field '$keyField' can't be uses as key.");
|
||||
throw new DoctrineException("Invalid field '$keyField' can't be used as key.");
|
||||
}
|
||||
$this->_keyField = $keyField;
|
||||
}
|
||||
|
@ -155,21 +156,21 @@ final class Collection extends \Doctrine\Common\Collections\Collection
|
|||
* Sets the collection owner. Used (only?) during hydration.
|
||||
*
|
||||
* @param object $entity
|
||||
* @param AssociationMapping $relation
|
||||
* @param AssociationMapping $assoc
|
||||
*/
|
||||
public function _setOwner($entity, AssociationMapping $relation)
|
||||
public function _setOwner($entity, AssociationMapping $assoc)
|
||||
{
|
||||
$this->_owner = $entity;
|
||||
$this->_association = $relation;
|
||||
if ($relation->isInverseSide()) {
|
||||
$this->_association = $assoc;
|
||||
if ($assoc->isInverseSide()) {
|
||||
// for sure bidirectional
|
||||
$this->_backRefFieldName = $relation->getMappedByFieldName();
|
||||
$this->_backRefFieldName = $assoc->getMappedByFieldName();
|
||||
} else {
|
||||
$targetClass = $this->_em->getClassMetadata($relation->getTargetEntityName());
|
||||
if ($targetClass->hasInverseAssociationMapping($relation->getSourceFieldName())) {
|
||||
$targetClass = $this->_em->getClassMetadata($assoc->getTargetEntityName());
|
||||
if ($targetClass->hasInverseAssociationMapping($assoc->getSourceFieldName())) {
|
||||
// bidirectional
|
||||
$this->_backRefFieldName = $targetClass->getInverseAssociationMapping(
|
||||
$relation->getSourceFieldName())->getSourceFieldName();
|
||||
$assoc->getSourceFieldName())->getSourceFieldName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -327,7 +328,7 @@ final class Collection extends \Doctrine\Common\Collections\Collection
|
|||
*
|
||||
* @return integer
|
||||
*/
|
||||
protected function _compareRecords($a, $b)
|
||||
private function _compareRecords($a, $b)
|
||||
{
|
||||
if ($a === $b) {
|
||||
return 0;
|
||||
|
@ -342,7 +343,7 @@ final class Collection extends \Doctrine\Common\Collections\Collection
|
|||
*/
|
||||
public function getMapping()
|
||||
{
|
||||
return $this->relation;
|
||||
return $this->_association;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -362,10 +363,21 @@ final class Collection extends \Doctrine\Common\Collections\Collection
|
|||
|
||||
private function _changed()
|
||||
{
|
||||
if ( ! $this->_em->getUnitOfWork()->isCollectionScheduledForUpdate($this)) {
|
||||
$this->_isDirty = true;
|
||||
/*if ( ! $this->_em->getUnitOfWork()->isCollectionScheduledForUpdate($this)) {
|
||||
//var_dump(get_class($this->_snapshot[0]));
|
||||
//echo "NOT!";
|
||||
//$this->_em->getUnitOfWork()->scheduleCollectionUpdate($this);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
public function isDirty()
|
||||
{
|
||||
return $this->_isDirty;
|
||||
}
|
||||
|
||||
public function setDirty($dirty)
|
||||
{
|
||||
$this->_isDirty = $dirty;
|
||||
}
|
||||
}
|
|
@ -2,12 +2,21 @@
|
|||
|
||||
namespace Doctrine\ORM\Persisters;
|
||||
|
||||
use Doctrine\ORM\Collection;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\PersistentCollection;
|
||||
|
||||
class AbstractCollectionPersister
|
||||
abstract class AbstractCollectionPersister
|
||||
{
|
||||
|
||||
public function recreate(Doctrine_Collection $coll)
|
||||
protected $_em;
|
||||
protected $_conn;
|
||||
|
||||
public function __construct(EntityManager $em)
|
||||
{
|
||||
$this->_em = $em;
|
||||
$this->_conn = $em->getConnection();
|
||||
}
|
||||
|
||||
public function recreate(PersistentCollection $coll)
|
||||
{
|
||||
if ($coll->getRelation()->isInverseSide()) {
|
||||
return;
|
||||
|
@ -15,44 +24,75 @@ class AbstractCollectionPersister
|
|||
//...
|
||||
}
|
||||
|
||||
public function delete(Doctrine_Collection $coll)
|
||||
public function delete(PersistentCollection $coll)
|
||||
{
|
||||
if ($coll->getRelation()->isInverseSide()) {
|
||||
return;
|
||||
}
|
||||
//...
|
||||
}
|
||||
|
||||
public function update(PersistentCollection $coll)
|
||||
{
|
||||
$this->deleteRows($coll);
|
||||
$this->updateRows($coll);
|
||||
$this->insertRows($coll);
|
||||
}
|
||||
|
||||
/* collection update actions */
|
||||
|
||||
public function deleteRows(Collection $coll)
|
||||
public function deleteRows(PersistentCollection $coll)
|
||||
{
|
||||
//$collection->getDeleteDiff();
|
||||
if ($coll->getMapping()->isInverseSide()) {
|
||||
return; // ignore inverse side
|
||||
}
|
||||
|
||||
$deleteDiff = $coll->getDeleteDiff();
|
||||
$sql = $this->_getDeleteRowSql($coll);
|
||||
$uow = $this->_em->getUnitOfWork();
|
||||
foreach ($deleteDiff as $element) {
|
||||
$this->_conn->exec($sql, $uow->getEntityIdentifier($element));
|
||||
}
|
||||
}
|
||||
|
||||
public function updateRows(Collection $coll)
|
||||
public function updateRows(PersistentCollection $coll)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function insertRows(Collection $coll)
|
||||
public function insertRows(PersistentCollection $coll)
|
||||
{
|
||||
//$collection->getInsertDiff();
|
||||
if ($coll->getMapping()->isInverseSide()) {
|
||||
return; // ignore inverse side
|
||||
}
|
||||
|
||||
$insertDiff = $coll->getInsertDiff();
|
||||
$sql = $this->_getInsertRowSql($coll);
|
||||
$uow = $this->_em->getUnitOfWork();
|
||||
foreach ($insertDiff as $element) {
|
||||
$this->_conn->exec($sql/*, $uow->getEntityIdentifier($element)*/);
|
||||
}
|
||||
}
|
||||
|
||||
protected function _getDeleteRowSql()
|
||||
{
|
||||
|
||||
}
|
||||
/**
|
||||
* Gets the SQL statement used for deleting a row from the collection.
|
||||
*
|
||||
* @param PersistentCollection $coll
|
||||
*/
|
||||
abstract protected function _getDeleteRowSql(PersistentCollection $coll);
|
||||
|
||||
protected function _getUpdateRowSql()
|
||||
{
|
||||
|
||||
}
|
||||
/**
|
||||
* Gets the SQL statement used for updating a row in the collection.
|
||||
*
|
||||
* @param PersistentCollection $coll
|
||||
*/
|
||||
abstract protected function _getUpdateRowSql();
|
||||
|
||||
protected function _getDeleteRowSql()
|
||||
{
|
||||
|
||||
}
|
||||
/**
|
||||
* Gets the SQL statement used for inserting a row from to the collection.
|
||||
*
|
||||
* @param PersistentCollection $coll
|
||||
*/
|
||||
abstract protected function _getInsertRowSql();
|
||||
}
|
||||
|
||||
|
|
|
@ -172,7 +172,8 @@ abstract class AbstractEntityPersister
|
|||
{
|
||||
foreach ($this->_em->getUnitOfWork()->getEntityChangeSet($entity) as $field => $change) {
|
||||
if (is_array($change)) {
|
||||
list ($oldVal, $newVal) = each($change);
|
||||
$oldVal = $change[0];
|
||||
$newVal = $change[1];
|
||||
} else {
|
||||
$oldVal = null;
|
||||
$newVal = $change;
|
||||
|
@ -182,20 +183,21 @@ abstract class AbstractEntityPersister
|
|||
$columnName = $this->_classMetadata->getColumnName($field);
|
||||
|
||||
if ($this->_classMetadata->hasAssociation($field)) {
|
||||
if ($newVal !== null) {
|
||||
$assocMapping = $this->_classMetadata->getAssociationMapping($field);
|
||||
if ( ! $assocMapping->isOneToOne() || $assocMapping->isInverseSide()) {
|
||||
//echo "NOT TO-ONE OR INVERSE!";
|
||||
continue;
|
||||
}
|
||||
foreach ($assocMapping->getSourceToTargetKeyColumns() as $sourceColumn => $targetColumn) {
|
||||
//TODO: throw exc if field not set
|
||||
$otherClass = $this->_em->getClassMetadata($assocMapping->getTargetEntityName());
|
||||
$assocMapping = $this->_classMetadata->getAssociationMapping($field);
|
||||
if ( ! $assocMapping->isOneToOne() || $assocMapping->isInverseSide()) {
|
||||
//echo "NOT TO-ONE OR INVERSE!";
|
||||
continue;
|
||||
}
|
||||
foreach ($assocMapping->getSourceToTargetKeyColumns() as $sourceColumn => $targetColumn) {
|
||||
//TODO: throw exc if field not set
|
||||
$otherClass = $this->_em->getClassMetadata($assocMapping->getTargetEntityName());
|
||||
if (is_null($newVal)) {
|
||||
$result[$sourceColumn] = null;
|
||||
} else {
|
||||
$result[$sourceColumn] = $otherClass->getReflectionProperty(
|
||||
$otherClass->getFieldName($targetColumn))->getValue($newVal);
|
||||
$otherClass->getFieldName($targetColumn))->getValue($newVal);
|
||||
}
|
||||
} else if ( ! $isInsert) {
|
||||
echo "NO INSERT AND NEWVAL NULL ON 1-1 ASSOC, OWNING SIDE";
|
||||
|
||||
}
|
||||
} else if (is_null($newVal)) {
|
||||
$result[$columnName] = null;
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Persisters;
|
||||
|
||||
/**
|
||||
* The joined subclass persister maps a single entity instance to several tables in the
|
||||
* database as it is defined by <tt>Class Table Inheritance</tt>.
|
||||
|
@ -26,19 +28,19 @@
|
|||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version $Revision$
|
||||
* @link www.phpdoctrine.org
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
*/
|
||||
class Doctrine_ORM_Persisters_JoinedSubclassPersister extends Doctrine_ORM_Persisters_AbstractEntityPersister
|
||||
class JoinedSubclassPersister extends AbstractEntityPersister
|
||||
{
|
||||
/**
|
||||
* Inserts an entity that is part of a Class Table Inheritance hierarchy.
|
||||
*
|
||||
* @param Doctrine_Entity $record record to be inserted
|
||||
* @param object $record record to be inserted
|
||||
* @return boolean
|
||||
* @override
|
||||
*/
|
||||
public function insert(Doctrine_ORM_Entity $entity)
|
||||
public function insert($entity)
|
||||
{
|
||||
$class = $entity->getClass();
|
||||
|
||||
|
@ -88,7 +90,7 @@ class Doctrine_ORM_Persisters_JoinedSubclassPersister extends Doctrine_ORM_Persi
|
|||
* @param Doctrine_Entity $record record to be updated
|
||||
* @return boolean whether or not the update was successful
|
||||
*/
|
||||
protected function _doUpdate(Doctrine_ORM_Entity $record)
|
||||
protected function _doUpdate($entity)
|
||||
{
|
||||
$conn = $this->_conn;
|
||||
$classMetadata = $this->_classMetadata;
|
||||
|
|
26
lib/Doctrine/ORM/Persisters/ManyToManyPersister.php
Normal file
26
lib/Doctrine/ORM/Persisters/ManyToManyPersister.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Persisters;
|
||||
|
||||
/**
|
||||
* Persister for many-to-many collections.
|
||||
*
|
||||
* @author robo
|
||||
*/
|
||||
class ManyToManyPersister extends AbstractCollectionPersister
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @param <type> $coll
|
||||
* @override
|
||||
*/
|
||||
protected function _getDeleteRowSql(PersistentCollection $coll)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,48 @@
|
|||
<?php
|
||||
|
||||
class Doctrine_ORM_Persisters_OneToManyPersister extends Doctrine_ORM_Persisters_AbstractCollectionPersister
|
||||
namespace Doctrine\ORM\Persisters;
|
||||
|
||||
use Doctrine\ORM\PersistentCollection;
|
||||
|
||||
/**
|
||||
* Persister for one-to-many collections.
|
||||
*/
|
||||
class OneToManyPersister extends AbstractCollectionPersister
|
||||
{
|
||||
|
||||
|
||||
protected function _getDeleteRowSql(PersistentCollection $coll)
|
||||
{
|
||||
$mapping = $coll->getMapping();
|
||||
$targetClass = $this->_em->getClassMetadata($mapping->getTargetEntityName());
|
||||
$table = $targetClass->getTableName();
|
||||
|
||||
$ownerMapping = $targetClass->getAssociationMapping($mapping->getMappedByFieldName());
|
||||
|
||||
$setClause = '';
|
||||
foreach ($ownerMapping->getSourceToTargetKeyColumns() as $sourceCol => $targetCol) {
|
||||
if ($setClause != '') $setClause .= ', ';
|
||||
$setClause .= "$sourceCol = NULL";
|
||||
}
|
||||
|
||||
$whereClause = '';
|
||||
foreach ($targetClass->getIdentifierColumnNames() as $idColumn) {
|
||||
if ($whereClause != '') $whereClause .= ' AND ';
|
||||
$whereClause .= "$idColumn = ?";
|
||||
}
|
||||
|
||||
return "UPDATE $table SET $setClause WHERE $whereClause";
|
||||
}
|
||||
|
||||
protected function _getInsertRowSql()
|
||||
{
|
||||
return "UPDATE xxx SET foreign_key = yyy WHERE foreign_key = zzz";
|
||||
}
|
||||
|
||||
/* Not used for OneToManyPersister */
|
||||
protected function _getUpdateRowSql()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -508,14 +508,38 @@ class Query extends AbstractQuery
|
|||
/**
|
||||
* Gets the list of results for the query.
|
||||
*
|
||||
* Alias for execute(array(), $hydrationMode).
|
||||
* Alias for execute(array(), HYDRATE_OBJECT).
|
||||
*
|
||||
* @param integer $hydrationMode
|
||||
* @return mixed
|
||||
* @return Collection
|
||||
*/
|
||||
public function getResultList($hydrationMode = null)
|
||||
public function getResultList()
|
||||
{
|
||||
return $this->execute(array(), $hydrationMode);
|
||||
return $this->execute(array(), self::HYDRATE_OBJECT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the array of results for the query.
|
||||
* Object graphs are represented as nested array structures.
|
||||
*
|
||||
* Alias for execute(array(), HYDRATE_ARRAY).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getResultArray()
|
||||
{
|
||||
return $this->execute(array(), self::HYDRATE_ARRAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the scalar results for the query.
|
||||
*
|
||||
* Alias for execute(array(), HYDRATE_SCALAR).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getScalarResult()
|
||||
{
|
||||
return $this->execute(array(), self::HYDRATE_SCALAR);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -532,8 +556,7 @@ class Query extends AbstractQuery
|
|||
$result = $this->execute(array(), $hydrationMode);
|
||||
if (count($result) > 1) {
|
||||
throw QueryException::nonUniqueResult();
|
||||
}
|
||||
|
||||
}
|
||||
return is_array($result) ? array_shift($result) : $result->getFirst();
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace Doctrine\ORM;
|
|||
|
||||
use Doctrine\ORM\Internal\CommitOrderCalculator;
|
||||
use Doctrine\ORM\Internal\CommitOrderNode;
|
||||
use Doctrine\ORM\Collection;
|
||||
use Doctrine\ORM\PersistentCollection;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\Exceptions\UnitOfWorkException;
|
||||
|
||||
|
@ -77,7 +77,7 @@ class UnitOfWork
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_identityMap = array();
|
||||
private $_identityMap = array();
|
||||
|
||||
/**
|
||||
* Map of all identifiers. Keys are object ids.
|
||||
|
@ -94,7 +94,7 @@ class UnitOfWork
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_originalEntityData = array();
|
||||
private $_originalEntityData = array();
|
||||
|
||||
/**
|
||||
* Map of data changes. Keys are object ids.
|
||||
|
@ -102,20 +102,20 @@ class UnitOfWork
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_entityChangeSets = array();
|
||||
private $_entityChangeSets = array();
|
||||
|
||||
/**
|
||||
* The states of entities in this UnitOfWork.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_entityStates = array();
|
||||
private $_entityStates = array();
|
||||
|
||||
/**
|
||||
* Map of entities that are scheduled for dirty checking at commit time.
|
||||
* This is only used if automatic dirty checking is disabled.
|
||||
*/
|
||||
protected $_scheduledForDirtyCheck = array();
|
||||
private $_scheduledForDirtyCheck = array();
|
||||
|
||||
/**
|
||||
* A list of all new entities that need to be INSERTed.
|
||||
|
@ -124,7 +124,7 @@ class UnitOfWork
|
|||
* @todo Index by class name.
|
||||
* @todo Rename to _inserts?
|
||||
*/
|
||||
protected $_newEntities = array();
|
||||
private $_newEntities = array();
|
||||
|
||||
/**
|
||||
* A list of all dirty entities that need to be UPDATEd.
|
||||
|
@ -132,7 +132,7 @@ class UnitOfWork
|
|||
* @var array
|
||||
* @todo Rename to _updates?
|
||||
*/
|
||||
protected $_dirtyEntities = array();
|
||||
private $_dirtyEntities = array();
|
||||
|
||||
/**
|
||||
* A list of all deleted entities.
|
||||
|
@ -142,35 +142,44 @@ class UnitOfWork
|
|||
* @var array
|
||||
* @todo Rename to _deletions?
|
||||
*/
|
||||
protected $_deletedEntities = array();
|
||||
private $_deletedEntities = array();
|
||||
|
||||
/**
|
||||
* All collection deletions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_collectionDeletions = array();
|
||||
private $_collectionDeletions = array();
|
||||
|
||||
/**
|
||||
* All collection creations.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_collectionCreations = array();
|
||||
private $_collectionCreations = array();
|
||||
|
||||
/**
|
||||
* All collection updates.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_collectionUpdates = array();
|
||||
private $_collectionUpdates = array();
|
||||
|
||||
/**
|
||||
* List of collections visited during a commit-phase of a UnitOfWork.
|
||||
* At the end of the UnitOfWork all these collections will make new snapshots
|
||||
* of their data.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_visitedCollections = array();
|
||||
|
||||
/**
|
||||
* The EntityManager that "owns" this UnitOfWork instance.
|
||||
*
|
||||
* @var Doctrine\ORM\EntityManager
|
||||
*/
|
||||
protected $_em;
|
||||
private $_em;
|
||||
|
||||
/**
|
||||
* The calculator used to calculate the order in which changes to
|
||||
|
@ -178,7 +187,21 @@ class UnitOfWork
|
|||
*
|
||||
* @var Doctrine\ORM\Internal\CommitOrderCalculator
|
||||
*/
|
||||
protected $_commitOrderCalculator;
|
||||
private $_commitOrderCalculator;
|
||||
|
||||
/**
|
||||
* The entity persister instances used to persist entity instances.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_persisters = array();
|
||||
|
||||
/**
|
||||
* The collection persister instances used to persist collections.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_collectionPersisters = array();
|
||||
|
||||
/**
|
||||
* Initializes a new UnitOfWork instance, bound to the given EntityManager.
|
||||
|
@ -198,18 +221,13 @@ class UnitOfWork
|
|||
*/
|
||||
public function commit()
|
||||
{
|
||||
// Compute changes in managed entities
|
||||
// Compute changes done since last commit
|
||||
$this->computeChangeSets();
|
||||
|
||||
/*foreach ($this->_managedCollections as $coll) {
|
||||
if ($coll->isDirty()) {
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
if (empty($this->_newEntities) &&
|
||||
empty($this->_deletedEntities) &&
|
||||
empty($this->_dirtyEntities)) {
|
||||
empty($this->_dirtyEntities) &&
|
||||
empty($this->_collectionUpdates)) {
|
||||
return; // Nothing to do.
|
||||
}
|
||||
|
||||
|
@ -226,7 +244,11 @@ class UnitOfWork
|
|||
}
|
||||
|
||||
//TODO: collection deletions (deletions of complete collections)
|
||||
//TODO: collection updates (deleteRows, updateRows, insertRows on join tables)
|
||||
//TODO: collection updates (deleteRows, updateRows, insertRows)
|
||||
foreach ($this->_collectionUpdates as $collectionToUpdate) {
|
||||
$this->getCollectionPersister($collectionToUpdate->getMapping())
|
||||
->update($collectionToUpdate);
|
||||
}
|
||||
//TODO: collection recreations (insertions of complete collections)
|
||||
|
||||
// Entity deletions come last and need to be in reverse commit order
|
||||
|
@ -236,11 +258,18 @@ class UnitOfWork
|
|||
|
||||
//TODO: commit transaction here?
|
||||
|
||||
// Take new snapshots from visited collections
|
||||
foreach ($this->_visitedCollections as $coll) {
|
||||
$coll->_takeSnapshot();
|
||||
}
|
||||
|
||||
// Clear up
|
||||
$this->_newEntities = array();
|
||||
$this->_dirtyEntities = array();
|
||||
$this->_deletedEntities = array();
|
||||
$this->_entityChangeSets = array();
|
||||
$this->_collectionUpdates = array();
|
||||
$this->_visitedCollections = array();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -258,7 +287,7 @@ class UnitOfWork
|
|||
}
|
||||
|
||||
/**
|
||||
* Computes all the changes that have been done to entities
|
||||
* Computes all the changes that have been done to entities and collections
|
||||
* since the last commit and stores these changes in the _entityChangeSet map
|
||||
* temporarily for access by the persisters, until the UoW commit is finished.
|
||||
*
|
||||
|
@ -289,10 +318,27 @@ class UnitOfWork
|
|||
foreach ($entities as $entity) {
|
||||
$oid = spl_object_hash($entity);
|
||||
$state = $this->getEntityState($entity);
|
||||
|
||||
// Look for changes in the entity itself by comparing against the
|
||||
// original data we have.
|
||||
if ($state == self::STATE_MANAGED || $state == self::STATE_NEW) {
|
||||
$actualData = array();
|
||||
foreach ($class->getReflectionProperties() as $name => $refProp) {
|
||||
$actualData[$name] = $refProp->getValue($entity);
|
||||
if ( ! $class->isIdentifier($name) || $class->isIdentifierNatural()) {
|
||||
$actualData[$name] = $refProp->getValue($entity);
|
||||
}
|
||||
|
||||
if ($class->isCollectionValuedAssociation($name) && ! ($actualData[$name] instanceof PersistentCollection)) {
|
||||
// Inject PersistentCollection
|
||||
//TODO: If $actualData[$name] is Collection then unwrap the array
|
||||
$assoc = $class->getAssociationMapping($name);
|
||||
$coll = new PersistentCollection($this->_em, $assoc->getTargetEntityName(),
|
||||
$actualData[$name] ? $actualData[$name] : array());
|
||||
$coll->_setOwner($entity, $assoc);
|
||||
if ( ! $coll->isEmpty()) $coll->setDirty(true);
|
||||
$class->getReflectionProperty($name)->setValue($entity, $coll);
|
||||
$actualData[$name] = $coll;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! isset($this->_originalEntityData[$oid])) {
|
||||
|
@ -308,11 +354,11 @@ class UnitOfWork
|
|||
$entityIsDirty = false;
|
||||
|
||||
foreach ($actualData as $propName => $actualValue) {
|
||||
$orgValue = isset($originalData[$propName]) ? $originalData[$propName] : null;
|
||||
$orgValue = isset($originalData[$propName]) ? $originalData[$propName] : null;
|
||||
if (is_object($orgValue) && $orgValue !== $actualValue) {
|
||||
$changeSet[$propName] = array($orgValue => $actualValue);
|
||||
$changeSet[$propName] = array($orgValue, $actualValue);
|
||||
} else if ($orgValue != $actualValue || (is_null($orgValue) xor is_null($actualValue))) {
|
||||
$changeSet[$propName] = array($orgValue => $actualValue);
|
||||
$changeSet[$propName] = array($orgValue, $actualValue);
|
||||
}
|
||||
|
||||
if (isset($changeSet[$propName])) {
|
||||
|
@ -320,16 +366,7 @@ class UnitOfWork
|
|||
$assoc = $class->getAssociationMapping($propName);
|
||||
if ($assoc->isOneToOne() && $assoc->isOwningSide()) {
|
||||
$entityIsDirty = true;
|
||||
} else if ( ! $assoc->isOneToOne()) {
|
||||
if ( ! $actualValue instanceof Collection) {
|
||||
// Inject PersistentCollection
|
||||
$coll = new Collection($this->_em, $assoc->getTargetEntityName(), $actualValue);
|
||||
//$coll->_takeSnapshot();
|
||||
$class->getReflectionProperty($propName)->setValue($entity, $coll);
|
||||
$actualData[$propName] = $coll;
|
||||
}
|
||||
}
|
||||
//$this->_handleAssociationValueChanged($assoc, $actualValue);
|
||||
} else {
|
||||
$entityIsDirty = true;
|
||||
}
|
||||
|
@ -344,7 +381,7 @@ class UnitOfWork
|
|||
}
|
||||
}
|
||||
|
||||
// Look for changes in associations
|
||||
// Look for changes in associations of the entity
|
||||
if ($state == self::STATE_MANAGED) {
|
||||
foreach ($class->getAssociationMappings() as $assoc) {
|
||||
$val = $actualData[$assoc->getSourceFieldName()];
|
||||
|
@ -359,10 +396,7 @@ class UnitOfWork
|
|||
}
|
||||
|
||||
/**
|
||||
* Handles the case during changeset computation where an association value
|
||||
* has changed. For a to-one association this means a new associated instance
|
||||
* has been set. For a to-many association this means a new associated collection/array
|
||||
* of entities has been set.
|
||||
* Computes the changes of an association.
|
||||
*
|
||||
* @param <type> $assoc
|
||||
* @param <type> $value
|
||||
|
@ -397,6 +431,7 @@ class UnitOfWork
|
|||
foreach ($targetClass->getReflectionProperties() as $name => $refProp) {
|
||||
$data[$name] = $refProp->getValue($entry);
|
||||
}
|
||||
|
||||
$oid = spl_object_hash($entry);
|
||||
$this->_newEntities[$oid] = $entry;
|
||||
$this->_entityChangeSets[$oid] = $data;
|
||||
|
@ -407,6 +442,13 @@ class UnitOfWork
|
|||
// MANAGED associated entities are already taken into account
|
||||
// during changeset calculation anyway, since they are in the identity map.
|
||||
}
|
||||
|
||||
if ($value instanceof PersistentCollection && $value->isDirty()) {
|
||||
if ($assoc->isOwningSide()) {
|
||||
$this->_collectionUpdates[] = $value;
|
||||
}
|
||||
$this->_visitedCollections[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -421,7 +463,7 @@ class UnitOfWork
|
|||
// statement reuse and maybe bulk operations in the persister.
|
||||
// Same for update/delete.
|
||||
$className = $class->getClassName();
|
||||
$persister = $this->_em->getEntityPersister($className);
|
||||
$persister = $this->getEntityPersister($className);
|
||||
foreach ($this->_newEntities as $entity) {
|
||||
if (get_class($entity) == $className) {
|
||||
$returnVal = $persister->insert($entity);
|
||||
|
@ -439,6 +481,11 @@ class UnitOfWork
|
|||
}
|
||||
}
|
||||
|
||||
private function _executeCollectionUpdate($collectionToUpdate)
|
||||
{
|
||||
//...
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes all entity updates for entities of the specified type.
|
||||
*
|
||||
|
@ -447,7 +494,7 @@ class UnitOfWork
|
|||
private function _executeUpdates($class)
|
||||
{
|
||||
$className = $class->getClassName();
|
||||
$persister = $this->_em->getEntityPersister($className);
|
||||
$persister = $this->getEntityPersister($className);
|
||||
foreach ($this->_dirtyEntities as $entity) {
|
||||
if (get_class($entity) == $className) {
|
||||
$persister->update($entity);
|
||||
|
@ -463,7 +510,7 @@ class UnitOfWork
|
|||
private function _executeDeletions($class)
|
||||
{
|
||||
$className = $class->getClassName();
|
||||
$persister = $this->_em->getEntityPersister($className);
|
||||
$persister = $this->getEntityPersister($className);
|
||||
foreach ($this->_deletedEntities as $entity) {
|
||||
if (get_class($entity) == $className) {
|
||||
$persister->delete($entity);
|
||||
|
@ -1055,34 +1102,34 @@ class UnitOfWork
|
|||
$this->_commitOrderCalculator->clear();
|
||||
}
|
||||
|
||||
public function scheduleCollectionUpdate(Collection $coll)
|
||||
public function scheduleCollectionUpdate(PersistentCollection $coll)
|
||||
{
|
||||
$this->_collectionUpdates[] = $coll;
|
||||
}
|
||||
|
||||
public function isCollectionScheduledForUpdate(Collection $coll)
|
||||
public function isCollectionScheduledForUpdate(PersistentCollection $coll)
|
||||
{
|
||||
//...
|
||||
}
|
||||
|
||||
public function scheduleCollectionDeletion(Collection $coll)
|
||||
public function scheduleCollectionDeletion(PersistentCollection $coll)
|
||||
{
|
||||
//TODO: if $coll is already scheduled for recreation ... what to do?
|
||||
// Just remove $coll from the scheduled recreations?
|
||||
$this->_collectionDeletions[] = $coll;
|
||||
}
|
||||
|
||||
public function isCollectionScheduledForDeletion(Collection $coll)
|
||||
public function isCollectionScheduledForDeletion(PersistentCollection $coll)
|
||||
{
|
||||
//...
|
||||
}
|
||||
|
||||
public function scheduleCollectionRecreation(Collection $coll)
|
||||
public function scheduleCollectionRecreation(PersistentCollection $coll)
|
||||
{
|
||||
$this->_collectionRecreations[] = $coll;
|
||||
}
|
||||
|
||||
public function isCollectionScheduledForRecreation(Collection $coll)
|
||||
public function isCollectionScheduledForRecreation(PersistentCollection $coll)
|
||||
{
|
||||
//...
|
||||
}
|
||||
|
@ -1219,21 +1266,6 @@ class UnitOfWork
|
|||
$this->_originalEntityData[$oid][$property] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL:
|
||||
* For hydration purposes only.
|
||||
*
|
||||
* Adds a managed collection to the UnitOfWork. On commit time, the UnitOfWork
|
||||
* checks all these managed collections for modifications and then initiates
|
||||
* the appropriate database synchronization.
|
||||
*
|
||||
* @param Doctrine\ORM\Collection $coll
|
||||
*/
|
||||
/*public function addManagedCollection(Collection $coll)
|
||||
{
|
||||
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Gets the identifier of an entity.
|
||||
* The returned value is always an array of identifier values. If the entity
|
||||
|
@ -1278,6 +1310,42 @@ class UnitOfWork
|
|||
foreach ($this->_identityMap as $entitySet) $count += count($entitySet);
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the EntityPersister for an Entity.
|
||||
*
|
||||
* This is usually not of interest for users, mainly for internal use.
|
||||
*
|
||||
* @param string $entityName The name of the Entity.
|
||||
* @return Doctrine\ORM\Persister\AbstractEntityPersister
|
||||
*/
|
||||
public function getEntityPersister($entityName)
|
||||
{
|
||||
if ( ! isset($this->_persisters[$entityName])) {
|
||||
$class = $this->_em->getClassMetadata($entityName);
|
||||
if ($class->isInheritanceTypeJoined()) {
|
||||
$persister = new \Doctrine\ORM\Persisters\JoinedSubclassPersister($this->_em, $class);
|
||||
} else {
|
||||
$persister = new \Doctrine\ORM\Persisters\StandardEntityPersister($this->_em, $class);
|
||||
}
|
||||
$this->_persisters[$entityName] = $persister;
|
||||
}
|
||||
return $this->_persisters[$entityName];
|
||||
}
|
||||
|
||||
public function getCollectionPersister($association)
|
||||
{
|
||||
$type = get_class($association);
|
||||
if ( ! isset($this->_collectionPersisters[$type])) {
|
||||
if ($association instanceof \Doctrine\ORM\Mapping\OneToManyMapping) {
|
||||
$persister = new \Doctrine\ORM\Persisters\OneToManyPersister($this->_em);
|
||||
} else if ($association instanceof \Doctrine\ORM\Mapping\ManyToManyMapping) {
|
||||
$persister = new \Doctrine\ORM\Persisters\ManyToManyPersister($this->_em);
|
||||
}
|
||||
$this->_collectionPersisters[$type] = $persister;
|
||||
}
|
||||
return $this->_collectionPersisters[$type];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -7,18 +7,8 @@ namespace Doctrine\Tests\Mocks;
|
|||
*/
|
||||
class EntityManagerMock extends \Doctrine\ORM\EntityManager
|
||||
{
|
||||
private $_persisterMock;
|
||||
private $_uowMock;
|
||||
private $_idGenerators = array();
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getEntityPersister($entityName)
|
||||
{
|
||||
return isset($this->_persisterMock[$entityName]) ?
|
||||
$this->_persisterMock[$entityName] : parent::getEntityPersister($entityName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
|
@ -39,18 +29,6 @@ class EntityManagerMock extends \Doctrine\ORM\EntityManager
|
|||
{
|
||||
$this->_uowMock = $uow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a (mock) persister for an entity class that will be returned when
|
||||
* getEntityPersister() is invoked for that class.
|
||||
*
|
||||
* @param <type> $entityName
|
||||
* @param <type> $persister
|
||||
*/
|
||||
public function setEntityPersister($entityName, $persister)
|
||||
{
|
||||
$this->_persisterMock[$entityName] = $persister;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock factory method to create an EntityManager.
|
||||
|
|
|
@ -9,6 +9,16 @@ namespace Doctrine\Tests\Mocks;
|
|||
*/
|
||||
class UnitOfWorkMock extends \Doctrine\ORM\UnitOfWork {
|
||||
private $_mockDataChangeSets = array();
|
||||
private $_persisterMock;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getEntityPersister($entityName)
|
||||
{
|
||||
return isset($this->_persisterMock[$entityName]) ?
|
||||
$this->_persisterMock[$entityName] : parent::getEntityPersister($entityName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <type> $entity
|
||||
|
@ -22,6 +32,18 @@ class UnitOfWorkMock extends \Doctrine\ORM\UnitOfWork {
|
|||
|
||||
/* MOCK API */
|
||||
|
||||
/**
|
||||
* Sets a (mock) persister for an entity class that will be returned when
|
||||
* getEntityPersister() is invoked for that class.
|
||||
*
|
||||
* @param <type> $entityName
|
||||
* @param <type> $persister
|
||||
*/
|
||||
public function setEntityPersister($entityName, $persister)
|
||||
{
|
||||
$this->_persisterMock[$entityName] = $persister;
|
||||
}
|
||||
|
||||
public function setDataChangeSet($entity, array $mockChangeSet) {
|
||||
$this->_mockDataChangeSets[spl_object_hash($entity)] = $mockChangeSet;
|
||||
}
|
||||
|
|
42
tests/Doctrine/Tests/Models/CMS/CmsAddress.php
Normal file
42
tests/Doctrine/Tests/Models/CMS/CmsAddress.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
namespace Doctrine\Tests\Models\CMS;
|
||||
|
||||
/**
|
||||
* Description of CmsAddress
|
||||
*
|
||||
* @author robo
|
||||
* @DoctrineEntity(tableName="cms_addresses")
|
||||
*/
|
||||
class CmsAddress
|
||||
{
|
||||
/**
|
||||
* @DoctrineColumn(type="integer")
|
||||
* @DoctrineId
|
||||
* @DoctrineIdGenerator("auto")
|
||||
*/
|
||||
public $id;
|
||||
/**
|
||||
* @DoctrineColumn(type="varchar", length=50)
|
||||
*/
|
||||
public $country;
|
||||
/**
|
||||
* @DoctrineColumn(type="varchar", length=50)
|
||||
*/
|
||||
public $zip;
|
||||
/**
|
||||
* @DoctrineColumn(type="varchar", length=50)
|
||||
*/
|
||||
public $city;
|
||||
/**
|
||||
* @DoctrineOneToOne(
|
||||
targetEntity="Doctrine\Tests\Models\CMS\CmsUser",
|
||||
joinColumns={"user_id" = "id"})
|
||||
*/
|
||||
public $user;
|
||||
}
|
||||
|
|
@ -34,11 +34,16 @@ class CmsUser
|
|||
* @DoctrineOneToMany(targetEntity="Doctrine\Tests\Models\CMS\CmsArticle", mappedBy="user")
|
||||
*/
|
||||
public $articles;
|
||||
/**
|
||||
* @DoctrineOneToOne(targetEntity="Doctrine\Tests\Models\CMS\CmsAddress", mappedBy="user",
|
||||
cascade={"save"})
|
||||
*/
|
||||
public $address;
|
||||
|
||||
/**
|
||||
* Adds a phonenumber to the user.
|
||||
*
|
||||
* @param <type> $phone
|
||||
* @param CmsPhonenumber $phone
|
||||
*/
|
||||
public function addPhonenumber(CmsPhonenumber $phone) {
|
||||
$this->phonenumbers[] = $phone;
|
||||
|
|
|
@ -50,8 +50,8 @@ class EntityPersisterTest extends \Doctrine\Tests\OrmTestCase
|
|||
$user->avatar = new ForumAvatar();
|
||||
|
||||
$this->_uowMock->setDataChangeSet($user, array(
|
||||
'username' => array('' => 'romanb'),
|
||||
'avatar' => array('' => $user->avatar)));
|
||||
'username' => array('', 'romanb'),
|
||||
'avatar' => array('', $user->avatar)));
|
||||
|
||||
|
||||
//insert
|
||||
|
|
|
@ -5,6 +5,9 @@ namespace Doctrine\Tests\ORM\Functional;
|
|||
use Doctrine\ORM\Export\ClassExporter;
|
||||
use Doctrine\Tests\Models\CMS\CmsUser;
|
||||
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
|
||||
use Doctrine\Tests\Models\CMS\CmsAddress;
|
||||
use Doctrine\Tests\Models\Forum\ForumUser;
|
||||
use Doctrine\Tests\Models\Forum\ForumAvatar;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
|
@ -15,18 +18,21 @@ require_once __DIR__ . '/../../TestInit.php';
|
|||
*/
|
||||
class BasicCRUDTest extends \Doctrine\Tests\OrmFunctionalTestCase {
|
||||
|
||||
public function testSingleEntityCRUD() {
|
||||
public function testBasicUnitsOfWorkWithOneToManyAssociation() {
|
||||
$em = $this->_em;
|
||||
|
||||
$exporter = new ClassExporter($this->_em);
|
||||
$exporter->exportClasses(array(
|
||||
$this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser'),
|
||||
$this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsPhonenumber')
|
||||
$this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsPhonenumber'),
|
||||
$this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress')
|
||||
));
|
||||
|
||||
// Create
|
||||
$user = new CmsUser;
|
||||
$user->name = 'romanb';
|
||||
$user->name = 'Roman';
|
||||
$user->username = 'romanb';
|
||||
$user->status = 'developer';
|
||||
$em->save($user);
|
||||
$this->assertTrue(is_numeric($user->id));
|
||||
$this->assertTrue($em->contains($user));
|
||||
|
@ -42,7 +48,7 @@ class BasicCRUDTest extends \Doctrine\Tests\OrmFunctionalTestCase {
|
|||
$em->flush();
|
||||
$this->assertTrue($em->contains($ph));
|
||||
$this->assertTrue($em->contains($user));
|
||||
$this->assertTrue($user->phonenumbers instanceof \Doctrine\ORM\Collection);
|
||||
$this->assertTrue($user->phonenumbers instanceof \Doctrine\ORM\PersistentCollection);
|
||||
|
||||
// Update name
|
||||
$user->name = 'guilherme';
|
||||
|
@ -67,14 +73,57 @@ class BasicCRUDTest extends \Doctrine\Tests\OrmFunctionalTestCase {
|
|||
$this->assertFalse($em->getUnitOfWork()->isRegisteredRemoved($ph2));
|
||||
}
|
||||
|
||||
/*public function testMore() {
|
||||
public function testOneToManyAssociationModification() {
|
||||
$user = new CmsUser;
|
||||
$user->name = 'Roman';
|
||||
$user->username = 'romanb';
|
||||
$user->status = 'developer';
|
||||
|
||||
$ph = new CmsPhonenumber;
|
||||
$ph->phonenumber = 123456;
|
||||
$ph1 = new CmsPhonenumber;
|
||||
$ph1->phonenumber = "0301234";
|
||||
$ph2 = new CmsPhonenumber;
|
||||
$ph2->phonenumber = "987654321";
|
||||
|
||||
$this->_em->save($ph);
|
||||
$user->addPhonenumber($ph1);
|
||||
$user->addPhonenumber($ph2);
|
||||
|
||||
$this->_em->save($user);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertTrue($user->phonenumbers instanceof \Doctrine\ORM\PersistentCollection);
|
||||
|
||||
// Remove the first element from the collection
|
||||
unset($user->phonenumbers[0]);
|
||||
$ph1->user = null; // owning side!
|
||||
|
||||
$this->_em->flush();
|
||||
}*/
|
||||
|
||||
$this->assertEquals(1, count($user->phonenumbers));
|
||||
$this->assertNull($ph1->user);
|
||||
}
|
||||
|
||||
public function testBasicOneToOne()
|
||||
{
|
||||
$user = new CmsUser;
|
||||
$user->name = 'Roman';
|
||||
$user->username = 'romanb';
|
||||
$user->status = 'developer';
|
||||
|
||||
$address = new CmsAddress;
|
||||
$address->country = 'Germany';
|
||||
$address->city = 'Berlin';
|
||||
$address->zip = '12345';
|
||||
|
||||
$user->address = $address; // inverse side
|
||||
$address->user = $user; // owning side!
|
||||
|
||||
$this->_em->save($user);
|
||||
$this->_em->flush();
|
||||
|
||||
// Check that the foreign key has been set
|
||||
$userId = $this->_em->getConnection()->execute("SELECT user_id FROM cms_addresses WHERE id=?",
|
||||
array($address->id))->fetchColumn();
|
||||
$this->assertTrue(is_numeric($userId));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -128,11 +128,11 @@ class ObjectHydratorTest extends HydrationTest
|
|||
$this->assertTrue(is_array($result[1]));
|
||||
|
||||
$this->assertTrue($result[0][0] instanceof \Doctrine\Tests\Models\CMS\CmsUser);
|
||||
$this->assertTrue($result[0][0]->phonenumbers instanceof \Doctrine\ORM\Collection);
|
||||
$this->assertTrue($result[0][0]->phonenumbers instanceof \Doctrine\ORM\PersistentCollection);
|
||||
$this->assertTrue($result[0][0]->phonenumbers[0] instanceof \Doctrine\Tests\Models\CMS\CmsPhonenumber);
|
||||
$this->assertTrue($result[0][0]->phonenumbers[1] instanceof \Doctrine\Tests\Models\CMS\CmsPhonenumber);
|
||||
$this->assertTrue($result[1][0] instanceof \Doctrine\Tests\Models\CMS\CmsUser);
|
||||
$this->assertTrue($result[1][0]->phonenumbers instanceof \Doctrine\ORM\Collection);
|
||||
$this->assertTrue($result[1][0]->phonenumbers instanceof \Doctrine\ORM\PersistentCollection);
|
||||
|
||||
// first user => 2 phonenumbers
|
||||
$this->assertEquals(2, count($result[0][0]->phonenumbers));
|
||||
|
@ -284,7 +284,7 @@ class ObjectHydratorTest extends HydrationTest
|
|||
|
||||
$this->assertTrue($result[0]['1'] instanceof \Doctrine\Tests\Models\CMS\CmsUser);
|
||||
$this->assertTrue($result[1]['2'] instanceof \Doctrine\Tests\Models\CMS\CmsUser);
|
||||
$this->assertTrue($result[0]['1']->phonenumbers instanceof \Doctrine\ORM\Collection);
|
||||
$this->assertTrue($result[0]['1']->phonenumbers instanceof \Doctrine\ORM\PersistentCollection);
|
||||
// first user => 2 phonenumbers. notice the custom indexing by user id
|
||||
$this->assertEquals(2, count($result[0]['1']->phonenumbers));
|
||||
// second user => 1 phonenumber. notice the custom indexing by user id
|
||||
|
@ -403,14 +403,14 @@ class ObjectHydratorTest extends HydrationTest
|
|||
$this->assertTrue(is_array($result[1]));
|
||||
|
||||
$this->assertTrue($result[0][0] instanceof \Doctrine\Tests\Models\CMS\CmsUser);
|
||||
$this->assertTrue($result[0][0]->phonenumbers instanceof \Doctrine\ORM\Collection);
|
||||
$this->assertTrue($result[0][0]->phonenumbers instanceof \Doctrine\ORM\PersistentCollection);
|
||||
$this->assertTrue($result[0][0]->phonenumbers[0] instanceof \Doctrine\Tests\Models\CMS\CmsPhonenumber);
|
||||
$this->assertTrue($result[0][0]->phonenumbers[1] instanceof \Doctrine\Tests\Models\CMS\CmsPhonenumber);
|
||||
$this->assertTrue($result[0][0]->articles instanceof \Doctrine\ORM\Collection);
|
||||
$this->assertTrue($result[0][0]->articles instanceof \Doctrine\ORM\PersistentCollection);
|
||||
$this->assertTrue($result[0][0]->articles[0] instanceof \Doctrine\Tests\Models\CMS\CmsArticle);
|
||||
$this->assertTrue($result[0][0]->articles[1] instanceof \Doctrine\Tests\Models\CMS\CmsArticle);
|
||||
$this->assertTrue($result[1][0] instanceof \Doctrine\Tests\Models\CMS\CmsUser);
|
||||
$this->assertTrue($result[1][0]->phonenumbers instanceof \Doctrine\ORM\Collection);
|
||||
$this->assertTrue($result[1][0]->phonenumbers instanceof \Doctrine\ORM\PersistentCollection);
|
||||
$this->assertTrue($result[1][0]->phonenumbers[0] instanceof \Doctrine\Tests\Models\CMS\CmsPhonenumber);
|
||||
$this->assertTrue($result[1][0]->articles[0] instanceof \Doctrine\Tests\Models\CMS\CmsArticle);
|
||||
$this->assertTrue($result[1][0]->articles[1] instanceof \Doctrine\Tests\Models\CMS\CmsArticle);
|
||||
|
@ -549,26 +549,26 @@ class ObjectHydratorTest extends HydrationTest
|
|||
$this->assertTrue($result[0][0] instanceof \Doctrine\Tests\Models\CMS\CmsUser);
|
||||
$this->assertTrue($result[1][0] instanceof \Doctrine\Tests\Models\CMS\CmsUser);
|
||||
// phonenumbers
|
||||
$this->assertTrue($result[0][0]->phonenumbers instanceof \Doctrine\ORM\Collection);
|
||||
$this->assertTrue($result[0][0]->phonenumbers instanceof \Doctrine\ORM\PersistentCollection);
|
||||
$this->assertTrue($result[0][0]->phonenumbers[0] instanceof \Doctrine\Tests\Models\CMS\CmsPhonenumber);
|
||||
$this->assertTrue($result[0][0]->phonenumbers[1] instanceof \Doctrine\Tests\Models\CMS\CmsPhonenumber);
|
||||
$this->assertTrue($result[1][0]->phonenumbers instanceof \Doctrine\ORM\Collection);
|
||||
$this->assertTrue($result[1][0]->phonenumbers instanceof \Doctrine\ORM\PersistentCollection);
|
||||
$this->assertTrue($result[1][0]->phonenumbers[0] instanceof \Doctrine\Tests\Models\CMS\CmsPhonenumber);
|
||||
// articles
|
||||
$this->assertTrue($result[0][0]->articles instanceof \Doctrine\ORM\Collection);
|
||||
$this->assertTrue($result[0][0]->articles instanceof \Doctrine\ORM\PersistentCollection);
|
||||
$this->assertTrue($result[0][0]->articles[0] instanceof \Doctrine\Tests\Models\CMS\CmsArticle);
|
||||
$this->assertTrue($result[0][0]->articles[1] instanceof \Doctrine\Tests\Models\CMS\CmsArticle);
|
||||
$this->assertTrue($result[1][0]->articles[0] instanceof \Doctrine\Tests\Models\CMS\CmsArticle);
|
||||
$this->assertTrue($result[1][0]->articles[1] instanceof \Doctrine\Tests\Models\CMS\CmsArticle);
|
||||
// article comments
|
||||
$this->assertTrue($result[0][0]->articles[0]->comments instanceof \Doctrine\ORM\Collection);
|
||||
$this->assertTrue($result[0][0]->articles[0]->comments instanceof \Doctrine\ORM\PersistentCollection);
|
||||
$this->assertTrue($result[0][0]->articles[0]->comments[0] instanceof \Doctrine\Tests\Models\CMS\CmsComment);
|
||||
// empty comment collections
|
||||
$this->assertTrue($result[0][0]->articles[1]->comments instanceof \Doctrine\ORM\Collection);
|
||||
$this->assertTrue($result[0][0]->articles[1]->comments instanceof \Doctrine\ORM\PersistentCollection);
|
||||
$this->assertEquals(0, count($result[0][0]->articles[1]->comments));
|
||||
$this->assertTrue($result[1][0]->articles[0]->comments instanceof \Doctrine\ORM\Collection);
|
||||
$this->assertTrue($result[1][0]->articles[0]->comments instanceof \Doctrine\ORM\PersistentCollection);
|
||||
$this->assertEquals(0, count($result[1][0]->articles[0]->comments));
|
||||
$this->assertTrue($result[1][0]->articles[1]->comments instanceof \Doctrine\ORM\Collection);
|
||||
$this->assertTrue($result[1][0]->articles[1]->comments instanceof \Doctrine\ORM\PersistentCollection);
|
||||
$this->assertEquals(0, count($result[1][0]->articles[1]->comments));
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ class UnitOfWorkTest extends \Doctrine\Tests\OrmTestCase
|
|||
{
|
||||
// Setup fake persister and id generator for identity generation
|
||||
$userPersister = new EntityPersisterMock($this->_emMock, $this->_emMock->getClassMetadata("Doctrine\Tests\Models\Forum\ForumUser"));
|
||||
$this->_emMock->setEntityPersister('Doctrine\Tests\Models\Forum\ForumUser', $userPersister);
|
||||
$this->_unitOfWork->setEntityPersister('Doctrine\Tests\Models\Forum\ForumUser', $userPersister);
|
||||
$idGeneratorMock = new IdentityIdGeneratorMock($this->_emMock);
|
||||
$this->_emMock->setIdGenerator('Doctrine\Tests\Models\Forum\ForumUser', $idGeneratorMock);
|
||||
$userPersister->setMockIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_IDENTITY);
|
||||
|
@ -99,13 +99,13 @@ class UnitOfWorkTest extends \Doctrine\Tests\OrmTestCase
|
|||
// Setup fake persister and id generator for identity generation
|
||||
//ForumUser
|
||||
$userPersister = new EntityPersisterMock($this->_emMock, $this->_emMock->getClassMetadata("Doctrine\Tests\Models\Forum\ForumUser"));
|
||||
$this->_emMock->setEntityPersister('Doctrine\Tests\Models\Forum\ForumUser', $userPersister);
|
||||
$this->_unitOfWork->setEntityPersister('Doctrine\Tests\Models\Forum\ForumUser', $userPersister);
|
||||
$userIdGeneratorMock = new IdentityIdGeneratorMock($this->_emMock);
|
||||
$this->_emMock->setIdGenerator('Doctrine\Tests\Models\Forum\ForumUser', $userIdGeneratorMock);
|
||||
$userPersister->setMockIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_IDENTITY);
|
||||
// ForumAvatar
|
||||
$avatarPersister = new EntityPersisterMock($this->_emMock, $this->_emMock->getClassMetadata("Doctrine\Tests\Models\Forum\ForumAvatar"));
|
||||
$this->_emMock->setEntityPersister('Doctrine\Tests\Models\Forum\ForumAvatar', $avatarPersister);
|
||||
$this->_unitOfWork->setEntityPersister('Doctrine\Tests\Models\Forum\ForumAvatar', $avatarPersister);
|
||||
$avatarIdGeneratorMock = new IdentityIdGeneratorMock($this->_emMock);
|
||||
$this->_emMock->setIdGenerator('Doctrine\Tests\Models\Forum\ForumAvatar', $avatarIdGeneratorMock);
|
||||
$avatarPersister->setMockIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_IDENTITY);
|
||||
|
@ -129,7 +129,7 @@ class UnitOfWorkTest extends \Doctrine\Tests\OrmTestCase
|
|||
$this->assertEquals(0, count($avatarPersister->getDeletes()));
|
||||
}
|
||||
|
||||
public function testComputeEntityChangeSets()
|
||||
/*public function testComputeEntityChangeSets()
|
||||
{
|
||||
// We need an ID generator for ForumAvatar, because we attach a NEW ForumAvatar
|
||||
// to a (faked) MANAGED instance. During changeset computation this will result
|
||||
|
@ -176,7 +176,7 @@ class UnitOfWorkTest extends \Doctrine\Tests\OrmTestCase
|
|||
$this->assertTrue(isset($user2ChangeSet['username']));
|
||||
$this->assertEquals(array('jon' => 'jwage'), $user2ChangeSet['username']);
|
||||
}
|
||||
|
||||
*/
|
||||
/*
|
||||
public function testSavingSingleEntityWithSequenceIdGeneratorSchedulesInsert()
|
||||
{
|
||||
|
|
|
@ -111,7 +111,7 @@ class OrmFunctionalTestCase extends OrmTestCase
|
|||
protected function setUp()
|
||||
{
|
||||
if ( ! isset($this->sharedFixture['conn'])) {
|
||||
echo " --- CREATE CONNECTION ----";
|
||||
echo PHP_EOL . " --- CREATE CONNECTION ----" . PHP_EOL;
|
||||
$this->sharedFixture['conn'] = TestUtil::getConnection();
|
||||
}
|
||||
if ( ! $this->_em) {
|
||||
|
|
Loading…
Add table
Reference in a new issue