OptimisticTest.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. <?php
  2. namespace Doctrine\Tests\ORM\Functional\Locking;
  3. use Doctrine\ORM\Mapping\ClassMetadata;
  4. use Doctrine\ORM\OptimisticLockException;
  5. use Doctrine\Common\EventManager;
  6. use Doctrine\ORM\Mapping\ClassMetadataFactory;
  7. use Doctrine\Tests\TestUtil;
  8. require_once __DIR__ . '/../../../TestInit.php';
  9. class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase
  10. {
  11. protected function setUp()
  12. {
  13. parent::setUp();
  14. try {
  15. $this->_schemaTool->createSchema(array(
  16. $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Locking\OptimisticJoinedParent'),
  17. $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Locking\OptimisticJoinedChild'),
  18. $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Locking\OptimisticStandard'),
  19. $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Locking\OptimisticTimestamp')
  20. ));
  21. } catch (\Exception $e) {
  22. // Swallow all exceptions. We do not test the schema tool here.
  23. }
  24. $this->_conn = $this->_em->getConnection();
  25. }
  26. public function testJoinedChildInsertSetsInitialVersionValue()
  27. {
  28. $test = new OptimisticJoinedChild();
  29. $test->name = 'child';
  30. $test->whatever = 'whatever';
  31. $this->_em->persist($test);
  32. $this->_em->flush();
  33. $this->assertEquals(1, $test->version);
  34. return $test;
  35. }
  36. /**
  37. * @depends testJoinedChildInsertSetsInitialVersionValue
  38. */
  39. public function testJoinedChildFailureThrowsException(OptimisticJoinedChild $child)
  40. {
  41. $q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticJoinedChild t WHERE t.id = :id');
  42. $q->setParameter('id', $child->id);
  43. $test = $q->getSingleResult();
  44. // Manually update/increment the version so we can try and save the same
  45. // $test and make sure the exception is thrown saying the record was
  46. // changed or updated since you read it
  47. $this->_conn->executeQuery('UPDATE optimistic_joined_parent SET version = ? WHERE id = ?', array(2, $test->id));
  48. // Now lets change a property and try and save it again
  49. $test->whatever = 'ok';
  50. try {
  51. $this->_em->flush();
  52. } catch (OptimisticLockException $e) {
  53. $this->assertSame($test, $e->getEntity());
  54. }
  55. }
  56. public function testJoinedParentInsertSetsInitialVersionValue()
  57. {
  58. $test = new OptimisticJoinedParent();
  59. $test->name = 'parent';
  60. $this->_em->persist($test);
  61. $this->_em->flush();
  62. $this->assertEquals(1, $test->version);
  63. return $test;
  64. }
  65. /**
  66. * @depends testJoinedParentInsertSetsInitialVersionValue
  67. */
  68. public function testJoinedParentFailureThrowsException(OptimisticJoinedParent $parent)
  69. {
  70. $q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticJoinedParent t WHERE t.id = :id');
  71. $q->setParameter('id', $parent->id);
  72. $test = $q->getSingleResult();
  73. // Manually update/increment the version so we can try and save the same
  74. // $test and make sure the exception is thrown saying the record was
  75. // changed or updated since you read it
  76. $this->_conn->executeQuery('UPDATE optimistic_joined_parent SET version = ? WHERE id = ?', array(2, $test->id));
  77. // Now lets change a property and try and save it again
  78. $test->name = 'WHATT???';
  79. try {
  80. $this->_em->flush();
  81. } catch (OptimisticLockException $e) {
  82. $this->assertSame($test, $e->getEntity());
  83. }
  84. }
  85. public function testMultipleFlushesDoIncrementalUpdates()
  86. {
  87. $test = new OptimisticStandard();
  88. for ($i = 0; $i < 5; $i++) {
  89. $test->name = 'test' . $i;
  90. $this->_em->persist($test);
  91. $this->_em->flush();
  92. $this->assertInternalType('int', $test->getVersion());
  93. $this->assertEquals($i + 1, $test->getVersion());
  94. }
  95. }
  96. public function testStandardInsertSetsInitialVersionValue()
  97. {
  98. $test = new OptimisticStandard();
  99. $test->name = 'test';
  100. $this->_em->persist($test);
  101. $this->_em->flush();
  102. $this->assertInternalType('int', $test->getVersion());
  103. $this->assertEquals(1, $test->getVersion());
  104. return $test;
  105. }
  106. /**
  107. * @depends testStandardInsertSetsInitialVersionValue
  108. */
  109. public function testStandardFailureThrowsException(OptimisticStandard $entity)
  110. {
  111. $q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticStandard t WHERE t.id = :id');
  112. $q->setParameter('id', $entity->id);
  113. $test = $q->getSingleResult();
  114. // Manually update/increment the version so we can try and save the same
  115. // $test and make sure the exception is thrown saying the record was
  116. // changed or updated since you read it
  117. $this->_conn->executeQuery('UPDATE optimistic_standard SET version = ? WHERE id = ?', array(2, $test->id));
  118. // Now lets change a property and try and save it again
  119. $test->name = 'WHATT???';
  120. try {
  121. $this->_em->flush();
  122. } catch (OptimisticLockException $e) {
  123. $this->assertSame($test, $e->getEntity());
  124. }
  125. }
  126. public function testOptimisticTimestampSetsDefaultValue()
  127. {
  128. $test = new OptimisticTimestamp();
  129. $test->name = 'Testing';
  130. $this->assertNull($test->version, "Pre-Condition");
  131. $this->_em->persist($test);
  132. $this->_em->flush();
  133. $this->assertInstanceOf('DateTime', $test->version);
  134. return $test;
  135. }
  136. /**
  137. * @depends testOptimisticTimestampSetsDefaultValue
  138. */
  139. public function testOptimisticTimestampFailureThrowsException(OptimisticTimestamp $entity)
  140. {
  141. $q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticTimestamp t WHERE t.id = :id');
  142. $q->setParameter('id', $entity->id);
  143. $test = $q->getSingleResult();
  144. $this->assertInstanceOf('DateTime', $test->version);
  145. // Manually increment the version datetime column
  146. $format = $this->_em->getConnection()->getDatabasePlatform()->getDateTimeFormatString();
  147. $this->_conn->executeQuery('UPDATE optimistic_timestamp SET version = ? WHERE id = ?', array(date($format, strtotime($test->version->format($format)) + 3600), $test->id));
  148. // Try and update the record and it should throw an exception
  149. $test->name = 'Testing again';
  150. try {
  151. $this->_em->flush();
  152. } catch (OptimisticLockException $e) {
  153. $this->assertSame($test, $e->getEntity());
  154. }
  155. }
  156. }
  157. /**
  158. * @Entity
  159. * @Table(name="optimistic_joined_parent")
  160. * @InheritanceType("JOINED")
  161. * @DiscriminatorColumn(name="discr", type="string")
  162. * @DiscriminatorMap({"parent" = "OptimisticJoinedParent", "child" = "OptimisticJoinedChild"})
  163. */
  164. class OptimisticJoinedParent
  165. {
  166. /**
  167. * @Id @Column(type="integer")
  168. * @GeneratedValue(strategy="AUTO")
  169. */
  170. public $id;
  171. /**
  172. * @Column(type="string", length=255)
  173. */
  174. public $name;
  175. /**
  176. * @Version @Column(type="integer")
  177. */
  178. public $version;
  179. }
  180. /**
  181. * @Entity
  182. * @Table(name="optimistic_joined_child")
  183. */
  184. class OptimisticJoinedChild extends OptimisticJoinedParent
  185. {
  186. /**
  187. * @Column(type="string", length=255)
  188. */
  189. public $whatever;
  190. }
  191. /**
  192. * @Entity
  193. * @Table(name="optimistic_standard")
  194. */
  195. class OptimisticStandard
  196. {
  197. /**
  198. * @Id @Column(type="integer")
  199. * @GeneratedValue(strategy="AUTO")
  200. */
  201. public $id;
  202. /**
  203. * @Column(type="string", length=255)
  204. */
  205. public $name;
  206. /**
  207. * @Version @Column(type="integer")
  208. */
  209. private $version;
  210. function getVersion() {return $this->version;}
  211. }
  212. /**
  213. * @Entity
  214. * @Table(name="optimistic_timestamp")
  215. */
  216. class OptimisticTimestamp
  217. {
  218. /**
  219. * @Id @Column(type="integer")
  220. * @GeneratedValue(strategy="AUTO")
  221. */
  222. public $id;
  223. /**
  224. * @Column(type="string", length=255)
  225. */
  226. public $name;
  227. /**
  228. * @Version @Column(type="datetime")
  229. */
  230. public $version;
  231. }