3 namespace Doctrine\Tests\ORM\Functional\Locking;
5 use Doctrine\ORM\Mapping\ClassMetadata;
6 use Doctrine\ORM\OptimisticLockException;
7 use Doctrine\Common\EventManager;
8 use Doctrine\ORM\Mapping\ClassMetadataFactory;
9 use Doctrine\Tests\TestUtil;
11 require_once __DIR__ . '/../../../TestInit.php';
13 class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase
15 protected function setUp()
20 $this->_schemaTool->createSchema(array(
21 $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Locking\OptimisticJoinedParent'),
22 $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Locking\OptimisticJoinedChild'),
23 $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Locking\OptimisticStandard'),
24 $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Locking\OptimisticTimestamp')
26 } catch (\Exception $e) {
27 // Swallow all exceptions. We do not test the schema tool here.
29 $this->_conn = $this->_em->getConnection();
32 public function testJoinedChildInsertSetsInitialVersionValue()
34 $test = new OptimisticJoinedChild();
35 $test->name = 'child';
36 $test->whatever = 'whatever';
37 $this->_em->persist($test);
40 $this->assertEquals(1, $test->version);
46 * @depends testJoinedChildInsertSetsInitialVersionValue
48 public function testJoinedChildFailureThrowsException(OptimisticJoinedChild $child)
50 $q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticJoinedChild t WHERE t.id = :id');
51 $q->setParameter('id', $child->id);
52 $test = $q->getSingleResult();
54 // Manually update/increment the version so we can try and save the same
55 // $test and make sure the exception is thrown saying the record was
56 // changed or updated since you read it
57 $this->_conn->executeQuery('UPDATE optimistic_joined_parent SET version = ? WHERE id = ?', array(2, $test->id));
59 // Now lets change a property and try and save it again
60 $test->whatever = 'ok';
63 } catch (OptimisticLockException $e) {
64 $this->assertSame($test, $e->getEntity());
68 public function testJoinedParentInsertSetsInitialVersionValue()
70 $test = new OptimisticJoinedParent();
71 $test->name = 'parent';
72 $this->_em->persist($test);
75 $this->assertEquals(1, $test->version);
81 * @depends testJoinedParentInsertSetsInitialVersionValue
83 public function testJoinedParentFailureThrowsException(OptimisticJoinedParent $parent)
85 $q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticJoinedParent t WHERE t.id = :id');
86 $q->setParameter('id', $parent->id);
87 $test = $q->getSingleResult();
89 // Manually update/increment the version so we can try and save the same
90 // $test and make sure the exception is thrown saying the record was
91 // changed or updated since you read it
92 $this->_conn->executeQuery('UPDATE optimistic_joined_parent SET version = ? WHERE id = ?', array(2, $test->id));
94 // Now lets change a property and try and save it again
95 $test->name = 'WHATT???';
98 } catch (OptimisticLockException $e) {
99 $this->assertSame($test, $e->getEntity());
103 public function testMultipleFlushesDoIncrementalUpdates()
105 $test = new OptimisticStandard();
107 for ($i = 0; $i < 5; $i++) {
108 $test->name = 'test' . $i;
109 $this->_em->persist($test);
112 $this->assertInternalType('int', $test->getVersion());
113 $this->assertEquals($i + 1, $test->getVersion());
117 public function testStandardInsertSetsInitialVersionValue()
119 $test = new OptimisticStandard();
120 $test->name = 'test';
121 $this->_em->persist($test);
124 $this->assertInternalType('int', $test->getVersion());
125 $this->assertEquals(1, $test->getVersion());
131 * @depends testStandardInsertSetsInitialVersionValue
133 public function testStandardFailureThrowsException(OptimisticStandard $entity)
135 $q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticStandard t WHERE t.id = :id');
136 $q->setParameter('id', $entity->id);
137 $test = $q->getSingleResult();
139 // Manually update/increment the version so we can try and save the same
140 // $test and make sure the exception is thrown saying the record was
141 // changed or updated since you read it
142 $this->_conn->executeQuery('UPDATE optimistic_standard SET version = ? WHERE id = ?', array(2, $test->id));
144 // Now lets change a property and try and save it again
145 $test->name = 'WHATT???';
148 } catch (OptimisticLockException $e) {
149 $this->assertSame($test, $e->getEntity());
153 public function testOptimisticTimestampSetsDefaultValue()
155 $test = new OptimisticTimestamp();
156 $test->name = 'Testing';
158 $this->assertNull($test->version, "Pre-Condition");
160 $this->_em->persist($test);
163 $this->assertInstanceOf('DateTime', $test->version);
169 * @depends testOptimisticTimestampSetsDefaultValue
171 public function testOptimisticTimestampFailureThrowsException(OptimisticTimestamp $entity)
173 $q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticTimestamp t WHERE t.id = :id');
174 $q->setParameter('id', $entity->id);
175 $test = $q->getSingleResult();
177 $this->assertInstanceOf('DateTime', $test->version);
179 // Manually increment the version datetime column
180 $format = $this->_em->getConnection()->getDatabasePlatform()->getDateTimeFormatString();
181 $this->_conn->executeQuery('UPDATE optimistic_timestamp SET version = ? WHERE id = ?', array(date($format, strtotime($test->version->format($format)) + 3600), $test->id));
183 // Try and update the record and it should throw an exception
184 $test->name = 'Testing again';
187 } catch (OptimisticLockException $e) {
188 $this->assertSame($test, $e->getEntity());
195 * @Table(name="optimistic_joined_parent")
196 * @InheritanceType("JOINED")
197 * @DiscriminatorColumn(name="discr", type="string")
198 * @DiscriminatorMap({"parent" = "OptimisticJoinedParent", "child" = "OptimisticJoinedChild"})
200 class OptimisticJoinedParent
203 * @Id @Column(type="integer")
204 * @GeneratedValue(strategy="AUTO")
209 * @Column(type="string", length=255)
214 * @Version @Column(type="integer")
221 * @Table(name="optimistic_joined_child")
223 class OptimisticJoinedChild extends OptimisticJoinedParent
226 * @Column(type="string", length=255)
233 * @Table(name="optimistic_standard")
235 class OptimisticStandard
238 * @Id @Column(type="integer")
239 * @GeneratedValue(strategy="AUTO")
244 * @Column(type="string", length=255)
249 * @Version @Column(type="integer")
253 function getVersion() {return $this->version;}
258 * @Table(name="optimistic_timestamp")
260 class OptimisticTimestamp
263 * @Id @Column(type="integer")
264 * @GeneratedValue(strategy="AUTO")
269 * @Column(type="string", length=255)
274 * @Version @Column(type="datetime")