more tests and first basic update/delete
This commit is contained in:
parent
b6e385d243
commit
73ad0ac454
@ -443,9 +443,9 @@ class Doctrine_ORM_EntityManager
|
||||
/**
|
||||
* Deletes the persistent state of the given entity.
|
||||
*
|
||||
* @param Doctrine\ORM\Entity $entity
|
||||
* @param object $entity
|
||||
*/
|
||||
public function delete(Doctrine_ORM_Entity $entity)
|
||||
public function delete($entity)
|
||||
{
|
||||
$this->_errorIfNotActiveOrClosed();
|
||||
$this->_unitOfWork->delete($entity);
|
||||
|
@ -80,6 +80,23 @@ class Doctrine_ORM_Export_ClassExporter
|
||||
$columns[$mapping['columnName']] = $column;
|
||||
}
|
||||
|
||||
foreach ($class->getAssociationMappings() as $mapping) {
|
||||
if ($mapping->isOneToOne() && $mapping->isOwningSide()) {
|
||||
foreach ($mapping->getSourceToTargetKeyColumns() as $sourceColumn => $targetColumn) {
|
||||
$column = array();
|
||||
$column['name'] = $sourceColumn;
|
||||
$column['type'] = $this->_em->getClassMetadata($mapping->getTargetEntityName())
|
||||
->getTypeOfColumn($targetColumn);
|
||||
$columns[$sourceColumn] = $column;
|
||||
}
|
||||
} else if ($mapping->isOneToMany() && $mapping->usesJoinTable()) {
|
||||
//... create join table, one-many through join table supported later
|
||||
throw new Doctrine_Exception("Not yet implemented.");
|
||||
} else if ($mapping->isManyToMany() && $mapping->isOwningSide()) {
|
||||
//... create join table
|
||||
}
|
||||
}
|
||||
|
||||
$this->_sm->createTable($class->getTableName(), $columns, $options);
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,6 @@
|
||||
*
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @since 2.0
|
||||
* @todo Rename to AssociationMapping.
|
||||
*/
|
||||
abstract class Doctrine_ORM_Mapping_AssociationMapping
|
||||
{
|
||||
@ -362,6 +361,11 @@ abstract class Doctrine_ORM_Mapping_AssociationMapping
|
||||
return false;
|
||||
}
|
||||
|
||||
public function usesJoinTable()
|
||||
{
|
||||
return (bool)$this->_joinTable;
|
||||
}
|
||||
|
||||
abstract public function lazyLoadFor($entity, $entityManager);
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,7 @@ class Doctrine_ORM_Mapping_Driver_AnnotationDriver {
|
||||
} else if ($oneToManyAnnot = $property->getAnnotation('DoctrineOneToMany')) {
|
||||
$mapping['mappedBy'] = $oneToManyAnnot->mappedBy;
|
||||
$mapping['targetEntity'] = $oneToManyAnnot->targetEntity;
|
||||
$mapping['cascade'] = $oneToManyAnnot->cascade;
|
||||
$metadata->mapOneToMany($mapping);
|
||||
} else if ($manyToOneAnnot = $property->getAnnotation('DoctrineManyToOne')) {
|
||||
$mapping['joinColumns'] = $manyToOneAnnot->joinColumns;
|
||||
|
@ -100,11 +100,17 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister
|
||||
/**
|
||||
* Updates an entity.
|
||||
*
|
||||
* @param Doctrine\ORM\Entity $entity The entity to update.
|
||||
* @param object $entity The entity to update.
|
||||
* @return void
|
||||
*/
|
||||
public function update(Doctrine_ORM_Entity $entity)
|
||||
public function update($entity)
|
||||
{
|
||||
$updateData = array();
|
||||
$this->_prepareData($entity, $updateData);
|
||||
$id = array_combine($this->_classMetadata->getIdentifierFieldNames(),
|
||||
$this->_em->getUnitOfWork()->getEntityIdentifier($entity));
|
||||
$this->_conn->update($this->_classMetadata->getTableName(), $updateData, $id);
|
||||
|
||||
/*$dataChangeSet = $entity->_getDataChangeSet();
|
||||
$referenceChangeSet = $entity->_getReferenceChangeSet();
|
||||
|
||||
@ -126,12 +132,14 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister
|
||||
/**
|
||||
* Deletes an entity.
|
||||
*
|
||||
* @param Doctrine\ORM\Entity $entity The entity to delete.
|
||||
* @param object $entity The entity to delete.
|
||||
* @return void
|
||||
*/
|
||||
public function delete(Doctrine_ORM_Entity $entity)
|
||||
public function delete($entity)
|
||||
{
|
||||
//TODO: perform delete
|
||||
$id = array_combine($this->_classMetadata->getIdentifierFieldNames(),
|
||||
$this->_em->getUnitOfWork()->getEntityIdentifier($entity));
|
||||
$this->_conn->delete($this->_classMetadata->getTableName(), $id);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -232,7 +240,7 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister
|
||||
*/
|
||||
protected function _prepareData($entity, array &$result, $isInsert = false)
|
||||
{
|
||||
foreach ($this->_em->getUnitOfWork()->getDataChangeSet($entity) as $field => $change) {
|
||||
foreach ($this->_em->getUnitOfWork()->getEntityChangeSet($entity) as $field => $change) {
|
||||
if (is_array($change)) {
|
||||
list ($oldVal, $newVal) = each($change);
|
||||
} else {
|
||||
@ -244,16 +252,21 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister
|
||||
$columnName = $this->_classMetadata->getColumnName($field);
|
||||
|
||||
if ($this->_classMetadata->hasAssociation($field)) {
|
||||
$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());
|
||||
$result[$sourceColumn] = $otherClass->getReflectionProperty(
|
||||
$otherClass->getFieldName($targetColumn))->getValue($newVal);
|
||||
if ($newVal !== null) {
|
||||
$assocMapping = $this->_classMetadata->getAssociationMapping($field);
|
||||
if ( ! $assocMapping->isOneToOne() || $assocMapping->isInverseSide()) {
|
||||
//echo "NOT TO-ONE OR INVERSE!";
|
||||
continue;
|
||||
}
|
||||
//echo "HERE!!!";
|
||||
foreach ($assocMapping->getSourceToTargetKeyColumns() as $sourceColumn => $targetColumn) {
|
||||
//TODO: throw exc if field not set
|
||||
$otherClass = $this->_em->getClassMetadata($assocMapping->getTargetEntityName());
|
||||
$result[$sourceColumn] = $otherClass->getReflectionProperty(
|
||||
$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;
|
||||
|
@ -60,7 +60,7 @@ class Doctrine_ORM_UnitOfWork
|
||||
* @todo Not sure this is a good idea. It is a problematic solution because
|
||||
* it hides the original state while the locked state is active.
|
||||
*/
|
||||
const STATE_LOCKED = 6;
|
||||
//const STATE_LOCKED = 6;
|
||||
|
||||
/**
|
||||
* A detached Entity is an instance with a persistent identity that is not
|
||||
@ -109,7 +109,7 @@ class Doctrine_ORM_UnitOfWork
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_dataChangeSets = array();
|
||||
protected $_entityChangeSets = array();
|
||||
|
||||
/**
|
||||
* The states of entities in this UnitOfWork.
|
||||
@ -167,7 +167,7 @@ class Doctrine_ORM_UnitOfWork
|
||||
protected $_collectionUpdates = array();
|
||||
|
||||
/**
|
||||
* The EntityManager the UnitOfWork belongs to.
|
||||
* The EntityManager that "owns" this UnitOfWork instance.
|
||||
*
|
||||
* @var Doctrine\ORM\EntityManager
|
||||
*/
|
||||
@ -182,8 +182,7 @@ class Doctrine_ORM_UnitOfWork
|
||||
protected $_commitOrderCalculator;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Creates a new UnitOfWork.
|
||||
* Initializes a new UnitOfWork instance, bound to the given EntityManager.
|
||||
*
|
||||
* @param Doctrine\ORM\EntityManager $em
|
||||
*/
|
||||
@ -203,7 +202,7 @@ class Doctrine_ORM_UnitOfWork
|
||||
public function commit()
|
||||
{
|
||||
// Compute changes in managed entities
|
||||
$this->computeDataChangeSet();
|
||||
$this->computeEntityChangeSets();
|
||||
|
||||
if (empty($this->_newEntities) &&
|
||||
empty($this->_deletedEntities) &&
|
||||
@ -238,42 +237,38 @@ class Doctrine_ORM_UnitOfWork
|
||||
$this->_newEntities = array();
|
||||
$this->_dirtyEntities = array();
|
||||
$this->_deletedEntities = array();
|
||||
$this->_dataChangeSets = array();
|
||||
$this->_entityChangeSets = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data changeset for an entity.
|
||||
* Gets the changeset for an entity.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDataChangeSet($entity)
|
||||
public function getEntityChangeSet($entity)
|
||||
{
|
||||
$oid = spl_object_hash($entity);
|
||||
if (isset($this->_dataChangeSets[$oid])) {
|
||||
return $this->_dataChangeSets[$oid];
|
||||
if (isset($this->_entityChangeSets[$oid])) {
|
||||
return $this->_entityChangeSets[$oid];
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes all the changes that have been done to entities in the identity map
|
||||
* since the last commit and stores these changes in _dataChangeSet temporarily
|
||||
* for access by the persisters, until the UoW commit is finished.
|
||||
* Computes all the changes that have been done to entities
|
||||
* since the last commit and stores these changes in the _entityChangeSet map
|
||||
* 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.
|
||||
*/
|
||||
public function computeDataChangeSet(array $entities = null)
|
||||
public function computeEntityChangeSets(array $entities = null)
|
||||
{
|
||||
$entitySet = array();
|
||||
if ( ! is_null($entities)) {
|
||||
foreach ($entities as $entity) {
|
||||
$className = get_class($entity);
|
||||
if ( ! isset($entitySet[$className])) {
|
||||
$entitySet[$className] = array();
|
||||
}
|
||||
$entitySet[$className][] = $entity;
|
||||
$entitySet[get_class($entity)][] = $entity;
|
||||
}
|
||||
} else {
|
||||
$entitySet = $this->_identityMap;
|
||||
@ -294,23 +289,42 @@ class Doctrine_ORM_UnitOfWork
|
||||
$actualData[$name] = $refProp->getValue($entity);
|
||||
}
|
||||
|
||||
if ($state == self::STATE_NEW) {
|
||||
$this->_dataChangeSets[$oid] = $actualData;
|
||||
if ( ! isset($this->_originalEntityData[$oid])) {
|
||||
// Entity is either NEW or MANAGED but not yet fully persisted
|
||||
// (only has an id). These result in an INSERT.
|
||||
$this->_entityChangeSets[$oid] = $actualData;
|
||||
$this->_originalEntityData[$oid] = $actualData;
|
||||
} else {
|
||||
// Entity is "fully" MANAGED: it was already fully persisted before
|
||||
// and we have a copy of the original data
|
||||
$originalData = $this->_originalEntityData[$oid];
|
||||
$changeSet = array();
|
||||
$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);
|
||||
} else if ($orgValue != $actualValue || (is_null($orgValue) xor is_null($actualValue))) {
|
||||
$changeSet[$propName] = array($orgValue => $actualValue);
|
||||
}
|
||||
|
||||
if (isset($changeSet[$propName])) {
|
||||
if ($class->hasAssociation($propName)) {
|
||||
$assoc = $class->getAssociationMapping($propName);
|
||||
if ($assoc->isOneToOne() && $assoc->isOwningSide()) {
|
||||
$entityIsDirty = true;
|
||||
}
|
||||
$this->_handleAssociationValueChanged($assoc, $actualValue);
|
||||
} else {
|
||||
$entityIsDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($changeSet) {
|
||||
$this->_dirtyEntities[$oid] = $entity;
|
||||
$this->_dataChangeSets[$oid] = $changeSet;
|
||||
if ($entityIsDirty) {
|
||||
$this->_dirtyEntities[$oid] = $entity;
|
||||
}
|
||||
$this->_entityChangeSets[$oid] = $changeSet;
|
||||
$this->_originalEntityData[$oid] = $actualData;
|
||||
}
|
||||
}
|
||||
@ -319,6 +333,58 @@ class Doctrine_ORM_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.
|
||||
*
|
||||
* @param <type> $assoc
|
||||
* @param <type> $value
|
||||
*/
|
||||
private function _handleAssociationValueChanged($assoc, $value)
|
||||
{
|
||||
if ($assoc->isOneToOne()) {
|
||||
$value = array($value);
|
||||
}
|
||||
|
||||
$targetClass = $this->_em->getClassMetadata($assoc->getTargetEntityName());
|
||||
foreach ($value as $entry) {
|
||||
$state = $this->getEntityState($entry);
|
||||
$oid = spl_object_hash($entry);
|
||||
if ($state == self::STATE_NEW) {
|
||||
// Get identifier, if possible (not post-insert)
|
||||
$idGen = $this->_em->getIdGenerator($targetClass->getClassName());
|
||||
if ( ! $idGen->isPostInsertGenerator()) {
|
||||
$idValue = $idGen->generate($entry);
|
||||
$this->_entityStates[$oid] = self::STATE_MANAGED;
|
||||
if ( ! $idGen instanceof Doctrine_ORM_Id_Assigned) {
|
||||
$this->_entityIdentifiers[$oid] = array($idValue);
|
||||
$targetClass->getSingleIdReflectionProperty()->setValue($entry, $idValue);
|
||||
} else {
|
||||
$this->_entityIdentifiers[$oid] = $idValue;
|
||||
}
|
||||
$this->addToIdentityMap($entry);
|
||||
}
|
||||
|
||||
// NEW entities are INSERTed within the current unit of work.
|
||||
$data = array();
|
||||
foreach ($targetClass->getReflectionProperties() as $name => $refProp) {
|
||||
$data[$name] = $refProp->getValue($entry);
|
||||
}
|
||||
$oid = spl_object_hash($entry);
|
||||
$this->_newEntities[$oid] = $entry;
|
||||
$this->_entityChangeSets[$oid] = $data;
|
||||
$this->_originalEntityData[$oid] = $data;
|
||||
} else if ($state == self::STATE_DELETED) {
|
||||
throw new Doctrine_Exception("Deleted entity in collection detected during flush.");
|
||||
}
|
||||
// MANAGED associated entities are already taken into account
|
||||
// during changeset calculation anyway, since they are in the identity map.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes all entity insertions for entities of the specified type.
|
||||
*
|
||||
@ -355,11 +421,10 @@ class Doctrine_ORM_UnitOfWork
|
||||
*/
|
||||
private function _executeUpdates($class)
|
||||
{
|
||||
try { throw new Exception(); } catch (Exception $e) { echo $e->getTraceAsString(); }
|
||||
$className = $class->getClassName();
|
||||
$persister = $this->_em->getEntityPersister($className);
|
||||
foreach ($this->_dirtyEntities as $entity) {
|
||||
if ($entity->getClass()->getClassName() == $className) {
|
||||
if (get_class($entity) == $className) {
|
||||
$persister->update($entity);
|
||||
}
|
||||
}
|
||||
@ -375,7 +440,7 @@ class Doctrine_ORM_UnitOfWork
|
||||
$className = $class->getClassName();
|
||||
$persister = $this->_em->getEntityPersister($className);
|
||||
foreach ($this->_deletedEntities as $entity) {
|
||||
if ($entity->getClass()->getClassName() == $className) {
|
||||
if (get_class($entity) == $className) {
|
||||
$persister->delete($entity);
|
||||
}
|
||||
}
|
||||
@ -454,13 +519,13 @@ class Doctrine_ORM_UnitOfWork
|
||||
$oid = spl_object_hash($entity);
|
||||
|
||||
if (isset($this->_dirtyEntities[$oid])) {
|
||||
throw new Doctrine_Connection_Exception("Dirty object can't be registered as new.");
|
||||
throw new Doctrine_Exception("Dirty object can't be registered as new.");
|
||||
}
|
||||
if (isset($this->_deletedEntities[$oid])) {
|
||||
throw new Doctrine_Connection_Exception("Removed object can't be registered as new.");
|
||||
throw new Doctrine_Exception("Removed object can't be registered as new.");
|
||||
}
|
||||
if (isset($this->_newEntities[$oid])) {
|
||||
throw new Doctrine_Connection_Exception("Object already registered as new. Can't register twice.");
|
||||
throw new Doctrine_Exception("Object already registered as new. Can't register twice.");
|
||||
}
|
||||
|
||||
$this->_newEntities[$oid] = $entity;
|
||||
@ -783,14 +848,14 @@ class Doctrine_ORM_UnitOfWork
|
||||
if ( ! empty($insertNow)) {
|
||||
// We have no choice. This means that there are new entities
|
||||
// with an IDENTITY column key generation strategy.
|
||||
$this->computeDataChangeSet($insertNow);
|
||||
$this->computeEntityChangeSets($insertNow);
|
||||
$commitOrder = $this->_getCommitOrder($insertNow);
|
||||
foreach ($commitOrder as $class) {
|
||||
$this->_executeInserts($class);
|
||||
}
|
||||
// remove them from _newEntities and _dataChangeSets
|
||||
// remove them from _newEntities and _entityChangeSets
|
||||
$this->_newEntities = array_diff_key($this->_newEntities, $insertNow);
|
||||
$this->_dataChangeSets = array_diff_key($this->_dataChangeSets, $insertNow);
|
||||
$this->_entityChangeSets = array_diff_key($this->_entityChangeSets, $insertNow);
|
||||
}
|
||||
}
|
||||
|
||||
@ -799,7 +864,7 @@ class Doctrine_ORM_UnitOfWork
|
||||
* This method is internally called during save() cascades as it tracks
|
||||
* the already visited entities to prevent infinite recursions.
|
||||
*
|
||||
* @param Doctrine\ORM\Entity $entity The entity to save.
|
||||
* @param object $entity The entity to save.
|
||||
* @param array $visited The already visited entities.
|
||||
*/
|
||||
private function _doSave($entity, array &$visited, array &$insertNow)
|
||||
@ -822,10 +887,12 @@ class Doctrine_ORM_UnitOfWork
|
||||
$insertNow[$oid] = $entity;
|
||||
} else {
|
||||
$idValue = $idGen->generate($entity);
|
||||
$this->_entityIdentifiers[$oid] = array($idValue);
|
||||
$this->_entityStates[$oid] = self::STATE_MANAGED;
|
||||
if ( ! $idGen instanceof Doctrine_ORM_Id_Assigned) {
|
||||
$this->_entityIdentifiers[$oid] = array($idValue);
|
||||
$class->getSingleIdReflectionProperty()->setValue($entity, $idValue);
|
||||
} else {
|
||||
$this->_entityIdentifiers[$oid] = $idValue;
|
||||
}
|
||||
}
|
||||
$this->registerNew($entity);
|
||||
@ -835,7 +902,7 @@ class Doctrine_ORM_UnitOfWork
|
||||
throw new Doctrine_Exception("Behavior of save() for a detached entity "
|
||||
. "is not yet defined.");
|
||||
case self::STATE_DELETED:
|
||||
// $entity becomes managed again
|
||||
// entity becomes managed again
|
||||
if ($this->isRegisteredRemoved($entity)) {
|
||||
//TODO: better a method for this?
|
||||
unset($this->_deletedEntities[$oid]);
|
||||
@ -855,11 +922,12 @@ class Doctrine_ORM_UnitOfWork
|
||||
/**
|
||||
* Deletes an entity as part of the current unit of work.
|
||||
*
|
||||
* @param Doctrine_ORM_Entity $entity
|
||||
* @param object $entity
|
||||
*/
|
||||
public function delete($entity)
|
||||
{
|
||||
$this->_doDelete($entity, array());
|
||||
$visited = array();
|
||||
$this->_doDelete($entity, $visited);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -911,8 +979,8 @@ class Doctrine_ORM_UnitOfWork
|
||||
}
|
||||
$relatedEntities = $class->getReflectionProperty($assocMapping->getSourceFieldName())
|
||||
->getValue($entity);
|
||||
if ($relatedEntities instanceof Doctrine_ORM_Collection &&
|
||||
count($relatedEntities) > 0) {
|
||||
if (($relatedEntities instanceof Doctrine_ORM_Collection || is_array($relatedEntities))
|
||||
&& count($relatedEntities) > 0) {
|
||||
foreach ($relatedEntities as $relatedEntity) {
|
||||
$this->_doSave($relatedEntity, $visited, $insertNow);
|
||||
}
|
||||
@ -1151,6 +1219,9 @@ class Doctrine_ORM_UnitOfWork
|
||||
|
||||
/**
|
||||
* Gets the identifier of an entity.
|
||||
* The returned value is always an array of identifier values. If the entity
|
||||
* has a composite primary key then the identifier values are in the same
|
||||
* order as the identifier field names as returned by ClassMetadata#getIdentifierFieldNames().
|
||||
*
|
||||
* @param object $entity
|
||||
* @return array The identifier values.
|
||||
|
@ -8,14 +8,14 @@ require_once 'lib/DoctrineTestInit.php';
|
||||
* @author robo
|
||||
*/
|
||||
class Orm_Functional_BasicCRUDTest extends Doctrine_OrmFunctionalTestCase {
|
||||
public function testFoo() {
|
||||
public function testSingleEntityCRUD() {
|
||||
$em = $this->_getEntityManager();
|
||||
|
||||
$exporter = new Doctrine_ORM_Export_ClassExporter($em);
|
||||
$exporter->exportClasses(array(
|
||||
$em->getClassMetadata('CmsUser'),
|
||||
$em->getClassMetadata('CmsPhonenumber')
|
||||
));
|
||||
$em->getClassMetadata('CmsUser'),
|
||||
$em->getClassMetadata('CmsPhonenumber')
|
||||
));
|
||||
|
||||
// Create
|
||||
$user = new CmsUser;
|
||||
@ -24,25 +24,33 @@ class Orm_Functional_BasicCRUDTest extends Doctrine_OrmFunctionalTestCase {
|
||||
$this->assertTrue(is_numeric($user->id));
|
||||
$this->assertTrue($em->contains($user));
|
||||
|
||||
$user2 = new CmsUser;
|
||||
$user2->name = 'jwage';
|
||||
$em->save($user2);
|
||||
$this->assertTrue(is_numeric($user2->id));
|
||||
$this->assertTrue($em->contains($user2));
|
||||
|
||||
// Read
|
||||
$user3 = $em->find('CmsUser', $user->id);
|
||||
$this->assertTrue($user === $user3);
|
||||
|
||||
$user4 = $em->find('CmsUser', $user2->id);
|
||||
$this->assertTrue($user2 === $user4);
|
||||
$user2 = $em->find('CmsUser', $user->id);
|
||||
$this->assertTrue($user === $user2);
|
||||
|
||||
// Add a phonenumber
|
||||
$ph = new CmsPhonenumber;
|
||||
$ph->phonenumber = "12345";
|
||||
$user->addPhonenumber($ph);
|
||||
$em->flush();
|
||||
$this->assertTrue($em->contains($ph));
|
||||
$this->assertTrue($em->contains($user));
|
||||
|
||||
$user->phonenumbers[] = $ph;
|
||||
// Update
|
||||
$user->name = 'guilherme';
|
||||
$em->flush();
|
||||
$this->assertEquals('guilherme', $user->name);
|
||||
|
||||
//var_dump($em->getUnitOfWork())
|
||||
// Delete
|
||||
$em->delete($user);
|
||||
$this->assertTrue($em->getUnitOfWork()->isRegisteredRemoved($user));
|
||||
$em->flush();
|
||||
$this->assertFalse($em->getUnitOfWork()->isRegisteredRemoved($user));
|
||||
|
||||
}
|
||||
|
||||
public function testMore() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,15 +119,21 @@ class Orm_UnitOfWorkTest extends Doctrine_OrmTestCase
|
||||
$this->assertEquals(0, count($avatarPersister->getDeletes()));
|
||||
}
|
||||
|
||||
public function testComputeDataChangeSet()
|
||||
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
|
||||
// in the UnitOfWork requesting the Id generator of ForumAvatar.
|
||||
$avatarIdGeneratorMock = new Doctrine_IdentityIdGeneratorMock($this->_emMock);
|
||||
$this->_emMock->setIdGenerator('ForumAvatar', $avatarIdGeneratorMock);
|
||||
|
||||
$user1 = new ForumUser();
|
||||
$user1->id = 1;
|
||||
$user1->username = "romanb";
|
||||
$user1->avatar = new ForumAvatar();
|
||||
// Fake managed state
|
||||
$this->_unitOfWork->setEntityState($user1, Doctrine_ORM_UnitOfWork::STATE_MANAGED);
|
||||
|
||||
|
||||
$user2 = new ForumUser();
|
||||
$user2->id = 2;
|
||||
$user2->username = "jwage";
|
||||
@ -143,10 +149,10 @@ class Orm_UnitOfWorkTest extends Doctrine_OrmTestCase
|
||||
));
|
||||
|
||||
// Go
|
||||
$this->_unitOfWork->computeDataChangeSet(array($user1, $user2));
|
||||
$this->_unitOfWork->computeEntityChangeSets(array($user1, $user2));
|
||||
|
||||
// Verify
|
||||
$user1ChangeSet = $this->_unitOfWork->getDataChangeSet($user1);
|
||||
$user1ChangeSet = $this->_unitOfWork->getEntityChangeSet($user1);
|
||||
$this->assertTrue(is_array($user1ChangeSet));
|
||||
$this->assertEquals(2, count($user1ChangeSet));
|
||||
$this->assertTrue(isset($user1ChangeSet['username']));
|
||||
@ -154,7 +160,7 @@ class Orm_UnitOfWorkTest extends Doctrine_OrmTestCase
|
||||
$this->assertTrue(isset($user1ChangeSet['avatar']));
|
||||
$this->assertSame(array(null => $user1->avatar), $user1ChangeSet['avatar']);
|
||||
|
||||
$user2ChangeSet = $this->_unitOfWork->getDataChangeSet($user2);
|
||||
$user2ChangeSet = $this->_unitOfWork->getEntityChangeSet($user2);
|
||||
$this->assertTrue(is_array($user2ChangeSet));
|
||||
$this->assertEquals(1, count($user2ChangeSet));
|
||||
$this->assertTrue(isset($user2ChangeSet['username']));
|
||||
|
@ -81,6 +81,7 @@ class Doctrine_EntityManagerMock extends Doctrine_ORM_EntityManager
|
||||
$this->_idGenerators[$className] = $generator;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
public function getIdGenerator($className)
|
||||
{
|
||||
if (isset($this->_idGenerators[$className])) {
|
||||
|
@ -14,10 +14,10 @@ class Doctrine_UnitOfWorkMock extends Doctrine_ORM_UnitOfWork {
|
||||
* @param <type> $entity
|
||||
* @override
|
||||
*/
|
||||
public function getDataChangeSet($entity) {
|
||||
public function getEntityChangeSet($entity) {
|
||||
$oid = spl_object_hash($entity);
|
||||
return isset($this->_mockDataChangeSets[$oid]) ?
|
||||
$this->_mockDataChangeSets[$oid] : parent::getDataChangeSet($entity);
|
||||
$this->_mockDataChangeSets[$oid] : parent::getEntityChangeSet($entity);
|
||||
}
|
||||
|
||||
/* MOCK API */
|
||||
|
@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @DoctrineEntity
|
||||
*/
|
||||
class CmsPhonenumber implements Doctrine_ORM_Entity
|
||||
class CmsPhonenumber
|
||||
{
|
||||
/**
|
||||
* @DoctrineColumn(type="varchar", length=50)
|
||||
@ -14,4 +14,9 @@ class CmsPhonenumber implements Doctrine_ORM_Entity
|
||||
* @DoctrineManyToOne(targetEntity="CmsUser", joinColumns={"user_id" = "id"})
|
||||
*/
|
||||
public $user;
|
||||
|
||||
public function setUser(CmsUser $user) {
|
||||
$this->user = $user;
|
||||
$user->addPhonenumber($this);
|
||||
}
|
||||
}
|
||||
|
@ -33,4 +33,14 @@ class CmsUser
|
||||
* @DoctrineOneToMany(targetEntity="CmsArticle", mappedBy="user")
|
||||
*/
|
||||
public $articles;
|
||||
|
||||
/**
|
||||
* Adds a phonenumber to the user.
|
||||
*
|
||||
* @param <type> $phone
|
||||
*/
|
||||
public function addPhonenumber(CmsPhonenumber $phone) {
|
||||
$this->phonenumbers[] = $phone;
|
||||
$phone->user = $this;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user