Commit 20858236 authored by jwage's avatar jwage

[2.0] A few fixes and clean up to the Optimistic Locking implementation.

parent cc3ea569
...@@ -58,6 +58,26 @@ class JoinedSubclassPersister extends StandardEntityPersister ...@@ -58,6 +58,26 @@ class JoinedSubclassPersister extends StandardEntityPersister
} }
} }
/**
* This function finds the ClassMetadata instance in a inheritance hierarchy
* that is responsible for enabling versioning.
*
* @return mixed $versionedClass ClassMetadata instance or false if versioning is not enabled
*/
private function _getVersionedClassMetadata()
{
if ($isVersioned = $this->_class->isVersioned) {
if (isset($this->_class->fieldMappings[$this->_class->versionField]['inherited'])) {
$definingClassName = $this->_class->fieldMappings[$this->_class->versionField]['inherited'];
$versionedClass = $this->_em->getClassMetadata($definingClassName);
} else {
$versionedClass = $this->_class;
}
return $versionedClass;
}
return false;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
* *
...@@ -95,12 +115,7 @@ class JoinedSubclassPersister extends StandardEntityPersister ...@@ -95,12 +115,7 @@ class JoinedSubclassPersister extends StandardEntityPersister
} }
if ($isVersioned = $this->_class->isVersioned) { if ($isVersioned = $this->_class->isVersioned) {
if (isset($this->_class->fieldMappings[$this->_class->versionField]['inherited'])) { $versionedClass = $this->_getVersionedClassMetadata();
$definingClassName = $this->_class->fieldMappings[$this->_class->versionField]['inherited'];
$versionedClass = $this->_em->getClassMetadata($definingClassName);
} else {
$versionedClass = $this->_class;
}
} }
$postInsertIds = array(); $postInsertIds = array();
...@@ -204,8 +219,22 @@ class JoinedSubclassPersister extends StandardEntityPersister ...@@ -204,8 +219,22 @@ class JoinedSubclassPersister extends StandardEntityPersister
$this->_em->getUnitOfWork()->getEntityIdentifier($entity) $this->_em->getUnitOfWork()->getEntityIdentifier($entity)
); );
if ($isVersioned = $this->_class->isVersioned) {
$versionedClass = $this->_getVersionedClassMetadata();
$versionedTable = $versionedClass->primaryTable['name'];
}
if ($updateData) {
foreach ($updateData as $tableName => $data) { foreach ($updateData as $tableName => $data) {
$this->_doUpdate($entity, $tableName, $updateData[$tableName], $id); if ($isVersioned && $versionedTable == $tableName) {
$this->_doUpdate($entity, $tableName, $data, $id);
} else {
$this->_conn->update($tableName, $data, $id);
}
}
if ($isVersioned && ! isset($updateData[$versionedTable])) {
$this->_doUpdate($entity, $versionedTable, array(), $id);
}
} }
} }
......
...@@ -182,6 +182,13 @@ class StandardEntityPersister ...@@ -182,6 +182,13 @@ class StandardEntityPersister
return $postInsertIds; return $postInsertIds;
} }
/**
* This function retrieves the default version value which was created
* by the DBMS INSERT statement. The value is assigned back in to the
* $entity versionField property.
*
* @return void
*/
protected function _assignDefaultVersionValue($class, $entity, $id) protected function _assignDefaultVersionValue($class, $entity, $id)
{ {
$versionField = $this->_class->getVersionField(); $versionField = $this->_class->getVersionField();
...@@ -222,6 +229,16 @@ class StandardEntityPersister ...@@ -222,6 +229,16 @@ class StandardEntityPersister
} }
} }
/**
* Perform UPDATE statement for an entity. This function has support for
* optimistic locking if the entities ClassMetadata has versioning enabled.
*
* @param object $entity The entity object being updated
* @param string $tableName The name of the table being updated
* @param array $data The array of data to set
* @param array $where The condition used to update
* @return void
*/
protected function _doUpdate($entity, $tableName, $data, $where) protected function _doUpdate($entity, $tableName, $data, $where)
{ {
$set = array(); $set = array();
...@@ -229,7 +246,7 @@ class StandardEntityPersister ...@@ -229,7 +246,7 @@ class StandardEntityPersister
$set[] = $this->_conn->quoteIdentifier($columnName) . ' = ?'; $set[] = $this->_conn->quoteIdentifier($columnName) . ' = ?';
} }
if ($versioned = $this->_class->isVersioned()) { if ($isVersioned = $this->_class->isVersioned()) {
$versionField = $this->_class->getVersionField(); $versionField = $this->_class->getVersionField();
$identifier = $this->_class->getIdentifier(); $identifier = $this->_class->getIdentifier();
$versionFieldColumnName = $this->_class->getColumnName($versionField); $versionFieldColumnName = $this->_class->getColumnName($versionField);
...@@ -237,6 +254,7 @@ class StandardEntityPersister ...@@ -237,6 +254,7 @@ class StandardEntityPersister
$set[] = $this->_conn->quoteIdentifier($versionFieldColumnName) . ' = ' . $set[] = $this->_conn->quoteIdentifier($versionFieldColumnName) . ' = ' .
$this->_conn->quoteIdentifier($versionFieldColumnName) . ' + 1'; $this->_conn->quoteIdentifier($versionFieldColumnName) . ' + 1';
} }
$params = array_merge(array_values($data), array_values($where)); $params = array_merge(array_values($data), array_values($where));
$sql = 'UPDATE ' . $this->_conn->quoteIdentifier($tableName) $sql = 'UPDATE ' . $this->_conn->quoteIdentifier($tableName)
...@@ -246,7 +264,7 @@ class StandardEntityPersister ...@@ -246,7 +264,7 @@ class StandardEntityPersister
$result = $this->_conn->exec($sql, $params); $result = $this->_conn->exec($sql, $params);
if ($versioned && ! $result) { if ($isVersioned && ! $result) {
throw \Doctrine\ORM\OptimisticLockException::optimisticLockFailed(); throw \Doctrine\ORM\OptimisticLockException::optimisticLockFailed();
} }
} }
......
...@@ -34,10 +34,40 @@ class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase ...@@ -34,10 +34,40 @@ class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->_conn = $this->_em->getConnection(); $this->_conn = $this->_em->getConnection();
} }
public function testJoinedInsertSetsInitialVersionValue() public function testJoinedChildInsertSetsInitialVersionValue()
{
$test = new OptimisticJoinedChild();
$test->name = 'child';
$test->whatever = 'whatever';
$this->_em->save($test);
$this->_em->flush();
$this->assertEquals(1, $test->version);
}
/**
* @expectedException Doctrine\ORM\OptimisticLockException
*/
public function testJoinedChildFailureThrowsException()
{
$q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Locking\OptimisticJoinedChild t WHERE t.name = :name');
$q->setParameter('name', 'child');
$test = $q->getSingleResult();
// Manually update/increment the version so we can try and save the same
// $test and make sure the exception is thrown saying the record was
// changed or updated since you read it
$this->_conn->execute('UPDATE optimistic_joined_parent SET version = ? WHERE id = ?', array(2, $test->id));
// Now lets change a property and try and save it again
$test->whatever = 'ok';
$this->_em->flush();
}
public function testJoinedParentInsertSetsInitialVersionValue()
{ {
$test = new OptimisticJoinedParent(); $test = new OptimisticJoinedParent();
$test->name = 'test'; $test->name = 'parent';
$this->_em->save($test); $this->_em->save($test);
$this->_em->flush(); $this->_em->flush();
...@@ -47,10 +77,10 @@ class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase ...@@ -47,10 +77,10 @@ class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase
/** /**
* @expectedException Doctrine\ORM\OptimisticLockException * @expectedException Doctrine\ORM\OptimisticLockException
*/ */
public function testJoinedFailureThrowsException() public function testJoinedParentFailureThrowsException()
{ {
$q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Locking\OptimisticJoinedParent t WHERE t.name = :name'); $q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Locking\OptimisticJoinedParent t WHERE t.name = :name');
$q->setParameter('name', 'test'); $q->setParameter('name', 'parent');
$test = $q->getSingleResult(); $test = $q->getSingleResult();
// Manually update/increment the version so we can try and save the same // Manually update/increment the version so we can try and save the same
...@@ -130,7 +160,7 @@ class OptimisticJoinedChild extends OptimisticJoinedParent ...@@ -130,7 +160,7 @@ class OptimisticJoinedChild extends OptimisticJoinedParent
/** /**
* @Column(type="string", length=255) * @Column(type="string", length=255)
*/ */
public $name; public $whatever;
} }
/** /**
......
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