[2.0] Finishing optimistic locking with timestamp support
This commit is contained in:
parent
25be43c314
commit
05d5fe4954
@ -1742,6 +1742,29 @@ final class ClassMetadata
|
|||||||
$this->sequenceGeneratorDefinition = $definition;
|
$this->sequenceGeneratorDefinition = $definition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the version field mapping used for versioning. Sets the default
|
||||||
|
* value to use depending on the column type
|
||||||
|
*
|
||||||
|
* @param array $mapping The version field mapping array
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setVersionMapping(array &$mapping)
|
||||||
|
{
|
||||||
|
$this->isVersioned = true;
|
||||||
|
$this->versionField = $mapping['fieldName'];
|
||||||
|
|
||||||
|
if ( ! isset($mapping['default'])) {
|
||||||
|
if ($mapping['type'] == 'integer') {
|
||||||
|
$mapping['default'] = 1;
|
||||||
|
} else if ($mapping['type'] == 'datetime') {
|
||||||
|
$mapping['default'] = 'CURRENT_TIMESTAMP';
|
||||||
|
} else {
|
||||||
|
throw DoctrineException::unsupportedOptimisticLockingType($mapping['type']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether this class is versioned for optimistic locking.
|
* Checks whether this class is versioned for optimistic locking.
|
||||||
*
|
*
|
||||||
|
@ -179,15 +179,7 @@ class AnnotationDriver implements Driver
|
|||||||
$metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' . $generatedValueAnnot->strategy));
|
$metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' . $generatedValueAnnot->strategy));
|
||||||
}
|
}
|
||||||
if ($versionAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Version')) {
|
if ($versionAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Version')) {
|
||||||
$metadata->setVersioned(true);
|
$metadata->setVersionMapping($mapping);
|
||||||
$metadata->setVersionField($mapping['fieldName']);
|
|
||||||
|
|
||||||
if ( ! isset($mapping['default'])) {
|
|
||||||
// TODO: When we have timestamp optimistic locking
|
|
||||||
// we'll have to figure out a better way to do this?
|
|
||||||
// Can we set the default value to be NOW() ?
|
|
||||||
$mapping['default'] = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$metadata->mapField($mapping);
|
$metadata->mapField($mapping);
|
||||||
|
|
||||||
|
@ -90,6 +90,9 @@ class XmlDriver extends AbstractFileDriver
|
|||||||
if (isset($fieldMapping['scale'])) {
|
if (isset($fieldMapping['scale'])) {
|
||||||
$mapping['scale'] = (int)$fieldMapping['scale'];
|
$mapping['scale'] = (int)$fieldMapping['scale'];
|
||||||
}
|
}
|
||||||
|
if (isset($fieldMapping['version']) && $fieldMapping['version']) {
|
||||||
|
$metadata->setVersionMapping($mapping);
|
||||||
|
}
|
||||||
$metadata->mapField($mapping);
|
$metadata->mapField($mapping);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,9 @@ class YamlDriver extends AbstractFileDriver
|
|||||||
if (isset($fieldMapping['length'])) {
|
if (isset($fieldMapping['length'])) {
|
||||||
$mapping['length'] = $fieldMapping['length'];
|
$mapping['length'] = $fieldMapping['length'];
|
||||||
}
|
}
|
||||||
|
if (isset($fieldMapping['version']) && $fieldMapping['version']) {
|
||||||
|
$metadata->setVersionMapping($mapping);
|
||||||
|
}
|
||||||
$metadata->mapField($mapping);
|
$metadata->mapField($mapping);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,9 +233,16 @@ class StandardEntityPersister
|
|||||||
|
|
||||||
if ($isVersioned = $this->_class->isVersioned) {
|
if ($isVersioned = $this->_class->isVersioned) {
|
||||||
$versionField = $this->_class->versionField;
|
$versionField = $this->_class->versionField;
|
||||||
$where[$this->_class->fieldNames[$versionField]] = $entity->version;
|
$versionFieldType = $this->_class->getTypeOfField($versionField);
|
||||||
|
$where[$this->_class->fieldNames[$versionField]] = Type::getType(
|
||||||
|
$this->_class->fieldMappings[$versionField]['type']
|
||||||
|
)->convertToDatabaseValue($entity->version, $this->_platform);
|
||||||
$versionFieldColumnName = $this->_class->getQuotedColumnName($versionField, $this->_platform);
|
$versionFieldColumnName = $this->_class->getQuotedColumnName($versionField, $this->_platform);
|
||||||
$set[] = $versionFieldColumnName . ' = ' . $versionFieldColumnName . ' + 1';
|
if ($versionFieldType == 'integer') {
|
||||||
|
$set[] = $versionFieldColumnName . ' = ' . $versionFieldColumnName . ' + 1';
|
||||||
|
} else if ($versionFieldType == 'datetime') {
|
||||||
|
$set[] = $versionFieldColumnName . ' = CURRENT_TIMESTAMP';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$params = array_merge(array_values($data), array_values($where));
|
$params = array_merge(array_values($data), array_values($where));
|
||||||
|
@ -24,7 +24,8 @@ class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
$this->_schemaTool->createSchema(array(
|
$this->_schemaTool->createSchema(array(
|
||||||
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Locking\OptimisticJoinedParent'),
|
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Locking\OptimisticJoinedParent'),
|
||||||
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Locking\OptimisticJoinedChild'),
|
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Locking\OptimisticJoinedChild'),
|
||||||
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Locking\OptimisticStandard')
|
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Locking\OptimisticStandard'),
|
||||||
|
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Locking\OptimisticTimestamp')
|
||||||
));
|
));
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
// Swallow all exceptions. We do not test the schema tool here.
|
// Swallow all exceptions. We do not test the schema tool here.
|
||||||
@ -119,6 +120,33 @@ class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
$test->name = 'WHATT???';
|
$test->name = 'WHATT???';
|
||||||
$this->_em->flush();
|
$this->_em->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testOptimisticTimestampSetsDefaultValue()
|
||||||
|
{
|
||||||
|
$test = new OptimisticTimestamp();
|
||||||
|
$test->name = 'Testing';
|
||||||
|
$this->_em->persist($test);
|
||||||
|
$this->_em->flush();
|
||||||
|
|
||||||
|
$this->assertTrue(strtotime($test->version) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException Doctrine\ORM\OptimisticLockException
|
||||||
|
*/
|
||||||
|
public function testOptimisticTimestampFailureThrowsException()
|
||||||
|
{
|
||||||
|
$q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticTimestamp t WHERE t.name = :name');
|
||||||
|
$q->setParameter('name', 'Testing');
|
||||||
|
$test = $q->getSingleResult();
|
||||||
|
|
||||||
|
// Manually increment the version datetime column
|
||||||
|
$this->_conn->execute('UPDATE optimistic_timestamp SET version = ? WHERE id = ?', array(date('Y-m-d H:i:s', strtotime($test->version->format('Y-m-d H:i:s')) + 3600), $test->id));
|
||||||
|
|
||||||
|
// Try and update the record and it should throw an exception
|
||||||
|
$test->name = 'Testing again';
|
||||||
|
$this->_em->flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -180,4 +208,27 @@ class OptimisticStandard
|
|||||||
* @Version @Column(type="integer")
|
* @Version @Column(type="integer")
|
||||||
*/
|
*/
|
||||||
public $version;
|
public $version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Entity
|
||||||
|
* @Table(name="optimistic_timestamp")
|
||||||
|
*/
|
||||||
|
class OptimisticTimestamp
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @Id @Column(type="integer")
|
||||||
|
* @GeneratedValue(strategy="AUTO")
|
||||||
|
*/
|
||||||
|
public $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Column(type="string", length=255)
|
||||||
|
*/
|
||||||
|
public $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Version @Column(type="datetime")
|
||||||
|
*/
|
||||||
|
public $version;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user