Removed EntityTransaction until it has a real purpose. Added the affected entity to OptimisticLockException. Updated functional optimistic locking tests accordingly.
This commit is contained in:
parent
d0325d7048
commit
f619a15a63
@ -1,4 +1,21 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\DBAL;
|
||||
|
||||
@ -51,5 +68,5 @@ interface Driver
|
||||
* @param Doctrine\DBAL\Connection $conn
|
||||
* @return string $database
|
||||
*/
|
||||
public function getDatabase(\Doctrine\DBAL\Connection $conn);
|
||||
public function getDatabase(Connection $conn);
|
||||
}
|
@ -34,7 +34,7 @@ interface Connection
|
||||
function quote($input, $type=\PDO::PARAM_STR);
|
||||
function exec($statement);
|
||||
function lastInsertId($name = null);
|
||||
function beginTransaction();
|
||||
function beginTransaction();
|
||||
function commit();
|
||||
function rollBack();
|
||||
function errorCode();
|
||||
|
@ -1,7 +1,5 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
@ -25,13 +23,10 @@ use Doctrine\DBAL\Driver,
|
||||
Doctrine\DBAL\Connection;
|
||||
|
||||
/**
|
||||
* IBM Db2 Driver
|
||||
* IBM DB2 Driver
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.com
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class DB2Driver implements Driver
|
||||
{
|
||||
|
@ -1,7 +1,5 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
|
@ -1,7 +1,5 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
|
@ -1,7 +1,5 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
|
@ -102,13 +102,6 @@ class EntityManager
|
||||
*/
|
||||
private $_closed = false;
|
||||
|
||||
/**
|
||||
* The ORM Entity Transaction.
|
||||
*
|
||||
* @var Doctrine\ORM\EntityTransaction
|
||||
*/
|
||||
protected $_transaction;
|
||||
|
||||
/**
|
||||
* Creates a new EntityManager that operates on the given database connection
|
||||
* and uses the given Configuration and EventManager implementations.
|
||||
@ -129,7 +122,6 @@ class EntityManager
|
||||
$config->getProxyDir(),
|
||||
$config->getProxyNamespace(),
|
||||
$config->getAutoGenerateProxyClasses());
|
||||
$this->_transaction = new EntityTransaction($this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -152,26 +144,17 @@ class EntityManager
|
||||
return $this->_metadataFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ORM Transaction instance.
|
||||
*
|
||||
* @return Doctrine\ORM\EntityTransaction
|
||||
*/
|
||||
public function getTransaction()
|
||||
{
|
||||
return $this->_transaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an ExpressionBuilder used for object-oriented construction of query expressions.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* [php]
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder();
|
||||
* $expr = $em->getExpressionBuilder();
|
||||
* $qb->select('u')->from('User', 'u')
|
||||
* ->where($expr->orX($expr->eq('u.id', 1), $expr->eq('u.id', 2)));
|
||||
* </code>
|
||||
*
|
||||
* @return ExpressionBuilder
|
||||
*/
|
||||
@ -185,29 +168,32 @@ class EntityManager
|
||||
|
||||
/**
|
||||
* Starts a transaction on the underlying database connection.
|
||||
*
|
||||
* @deprecated Use {@link getConnection}.beginTransaction().
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
$this->getTransaction()->begin();
|
||||
$this->_conn->beginTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits a transaction on the underlying database connection.
|
||||
*
|
||||
* @deprecated Use {@link getConnection}.commit().
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
$this->getTransaction()->commit();
|
||||
$this->_conn->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a rollback on the underlying database connection and closes the
|
||||
* EntityManager as it may now be in a corrupted state.
|
||||
* Performs a rollback on the underlying database connection.
|
||||
*
|
||||
* @return boolean TRUE on success, FALSE on failure
|
||||
* @deprecated Use {@link getConnection}.rollback().
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
return $this->getTransaction()->rollback();
|
||||
$this->_conn->rollback();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -288,6 +274,9 @@ class EntityManager
|
||||
* Flushes all changes to objects that have been queued up to now to the database.
|
||||
* This effectively synchronizes the in-memory state of managed objects with the
|
||||
* database.
|
||||
*
|
||||
* @throws Doctrine\ORM\OptimisticLockException If a version check on an entity that
|
||||
* makes use of optimistic locking fails.
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
|
@ -1,163 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
use Doctrine\DBAL\Transaction;
|
||||
|
||||
/**
|
||||
* The Transaction class is the central access point to ORM Transaction functionality.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
final class EntityTransaction
|
||||
{
|
||||
/**
|
||||
* The wrapped ORM EntityManager.
|
||||
*
|
||||
* @var Doctrine\ORM\EntityManager
|
||||
*/
|
||||
private $_em;
|
||||
|
||||
/**
|
||||
* The database connection used by the EntityManager.
|
||||
*
|
||||
* @var Doctrine\DBAL\Connection
|
||||
*/
|
||||
private $_conn;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Transaction $transaction
|
||||
*/
|
||||
public function __construct(EntityManager $em)
|
||||
{
|
||||
$this->_em = $em;
|
||||
$this->_conn = $em->getConnection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a transaction is currently active.
|
||||
*
|
||||
* @return boolean TRUE if a transaction is currently active, FALSE otherwise.
|
||||
*/
|
||||
public function isTransactionActive()
|
||||
{
|
||||
return $this->_conn->isTransactionActive();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the transaction isolation level.
|
||||
*
|
||||
* @param integer $level The level to set.
|
||||
*/
|
||||
public function setTransactionIsolation($level)
|
||||
{
|
||||
return $this->_conn->setTransactionIsolation($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currently active transaction isolation level.
|
||||
*
|
||||
* @return integer The current transaction isolation level.
|
||||
*/
|
||||
public function getTransactionIsolation()
|
||||
{
|
||||
return $this->_conn->getTransactionIsolation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current transaction nesting level.
|
||||
*
|
||||
* @return integer The nesting level. A value of 0 means there's no active transaction.
|
||||
*/
|
||||
public function getTransactionNestingLevel()
|
||||
{
|
||||
return $this->_conn->getTransactionNestingLevel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a transaction by suspending auto-commit mode.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function begin()
|
||||
{
|
||||
$this->_conn->beginTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits the current transaction.
|
||||
*
|
||||
* @return void
|
||||
* @throws Doctrine\DBAL\ConnectionException If the commit failed due to no active transaction or
|
||||
* because the transaction was marked for rollback only.
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
$this->_conn->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel any database changes done during the current transaction.
|
||||
*
|
||||
* this method can be listened with onPreTransactionRollback and onTransactionRollback
|
||||
* event listener methods
|
||||
*
|
||||
* @return boolean TRUE on success, FALSE on failure
|
||||
* @throws Doctrine\DBAL\ConnectionException If the rollback operation failed.
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
$this->_em->close();
|
||||
return $this->_conn->rollback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the current transaction so that the only possible
|
||||
* outcome for the transaction to be rolled back.
|
||||
*
|
||||
* @throws Doctrine\DBAL\ConnectionException If no transaction is active.
|
||||
*/
|
||||
public function setRollbackOnly()
|
||||
{
|
||||
$this->_conn->setRollbackOnly();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the current transaction is marked for rollback only.
|
||||
*
|
||||
* @return boolean
|
||||
* @throws Doctrine\DBAL\ConnectionException If no transaction is active.
|
||||
*/
|
||||
public function isRollbackOnly()
|
||||
{
|
||||
return $this->_conn->isRollbackOnly();
|
||||
}
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Base exception class for all ORM exceptions.
|
||||
*
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @since 2.0
|
||||
*/
|
||||
class ORMException extends \Exception
|
||||
class ORMException extends Exception
|
||||
{
|
||||
public static function missingMappingDriverImpl()
|
||||
{
|
||||
|
@ -20,15 +20,33 @@
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
/**
|
||||
* OptimisticLockException
|
||||
* An OptimisticLockException is thrown when a version check on an object
|
||||
* that uses optimistic locking through a version field fails.
|
||||
*
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @since 2.0
|
||||
*/
|
||||
class OptimisticLockException extends ORMException
|
||||
{
|
||||
public static function lockFailed()
|
||||
private $entity;
|
||||
|
||||
public function __construct($msg, $entity)
|
||||
{
|
||||
return new self("The optimistic lock failed.");
|
||||
$this->entity = $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the entity that caused the exception.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function getEntity()
|
||||
{
|
||||
return $this->entity;
|
||||
}
|
||||
|
||||
public static function lockFailed($entity)
|
||||
{
|
||||
return new self("The optimistic lock on an entity failed.", $entity);
|
||||
}
|
||||
}
|
@ -330,7 +330,7 @@ class BasicEntityPersister
|
||||
$result = $this->_conn->executeUpdate($sql, $params, $types);
|
||||
|
||||
if ($this->_class->isVersioned && ! $result) {
|
||||
throw OptimisticLockException::lockFailed();
|
||||
throw OptimisticLockException::lockFailed($entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,8 @@
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection,
|
||||
use Exception,
|
||||
Doctrine\Common\Collections\ArrayCollection,
|
||||
Doctrine\Common\Collections\Collection,
|
||||
Doctrine\Common\NotifyPropertyChanged,
|
||||
Doctrine\Common\PropertyChangedListener,
|
||||
@ -276,18 +277,17 @@ class UnitOfWork implements PropertyChangedListener
|
||||
|
||||
// Now we need a commit order to maintain referential integrity
|
||||
$commitOrder = $this->_getCommitOrder();
|
||||
|
||||
$tx = $this->_em->getTransaction();
|
||||
|
||||
try {
|
||||
$tx->begin();
|
||||
|
||||
$conn = $this->_em->getConnection();
|
||||
|
||||
$conn->beginTransaction();
|
||||
try {
|
||||
if ($this->_entityInsertions) {
|
||||
foreach ($commitOrder as $class) {
|
||||
$this->_executeInserts($class);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($this->_entityUpdates) {
|
||||
foreach ($commitOrder as $class) {
|
||||
$this->_executeUpdates($class);
|
||||
@ -317,11 +317,10 @@ class UnitOfWork implements PropertyChangedListener
|
||||
}
|
||||
}
|
||||
|
||||
$tx->commit();
|
||||
} catch (\Exception $e) {
|
||||
$tx->setRollbackOnly();
|
||||
$tx->rollback();
|
||||
|
||||
$conn->commit();
|
||||
} catch (Exception $e) {
|
||||
$this->_em->close();
|
||||
$conn->rollback();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
@ -1289,6 +1288,8 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*
|
||||
* @param object $entity
|
||||
* @return object The managed copy of the entity.
|
||||
* @throws OptimisticLockException If the entity uses optimistic locking through a version
|
||||
* attribute and the version check against the managed copy fails.
|
||||
*/
|
||||
public function merge($entity)
|
||||
{
|
||||
@ -1315,7 +1316,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
throw new \InvalidArgumentException('New entity detected during merge.'
|
||||
. ' Persist the new entity before merging.');
|
||||
}
|
||||
|
||||
|
||||
// MANAGED entities are ignored by the merge operation
|
||||
if ($this->getEntityState($entity, self::STATE_DETACHED) == self::STATE_MANAGED) {
|
||||
$managedCopy = $entity;
|
||||
@ -1343,7 +1344,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$entityVersion = $class->reflFields[$class->versionField]->getValue($entity);
|
||||
// Throw exception if versions dont match.
|
||||
if ($managedCopyVersion != $entityVersion) {
|
||||
throw OptimisticLockException::lockFailed();
|
||||
throw OptimisticLockException::lockFailed($entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ class ConnectionTest extends \Doctrine\Tests\DbalFunctionalTestCase
|
||||
$this->assertEquals(1, $this->_conn->getTransactionNestingLevel());
|
||||
//no rethrow
|
||||
}
|
||||
$this->assertTrue($this->_conn->getRollbackOnly());
|
||||
$this->assertTrue($this->_conn->isRollbackOnly());
|
||||
|
||||
$this->_conn->commit(); // should throw exception
|
||||
$this->fail('Transaction commit after failed nested transaction should fail.');
|
||||
|
@ -84,6 +84,44 @@ class DetachedEntityTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$phonenumbers = $user->getPhonenumbers();
|
||||
$this->assertTrue($this->_em->contains($phonenumbers[0]));
|
||||
$this->assertTrue($this->_em->contains($phonenumbers[1]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-518
|
||||
*/
|
||||
/*public function testMergeDetachedEntityWithNewlyPersistentOneToOneAssoc()
|
||||
{
|
||||
//$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
|
||||
// Create a detached user
|
||||
$user = new CmsUser;
|
||||
$user->name = 'Roman';
|
||||
$user->username = 'romanb';
|
||||
$user->status = 'dev';
|
||||
$this->_em->persist($user);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
//$address = new CmsAddress;
|
||||
//$address->city = 'Berlin';
|
||||
//$address->country = 'Germany';
|
||||
//$address->street = 'Sesamestreet';
|
||||
//$address->zip = 12345;
|
||||
//$address->setUser($user);
|
||||
|
||||
$phone = new CmsPhonenumber();
|
||||
$phone->phonenumber = '12345';
|
||||
|
||||
$user2 = $this->_em->merge($user);
|
||||
|
||||
$user2->addPhonenumber($phone);
|
||||
$this->_em->persist($phone);
|
||||
|
||||
//$address->setUser($user2);
|
||||
//$this->_em->persist($address);
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertEquals(1,1);
|
||||
}*/
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace Doctrine\Tests\ORM\Functional\Locking;
|
||||
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\OptimisticLockException;
|
||||
use Doctrine\Common\EventManager;
|
||||
use Doctrine\ORM\Mapping\ClassMetadataFactory;
|
||||
use Doctrine\Tests\TestUtil;
|
||||
@ -37,15 +38,17 @@ class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertEquals(1, $test->version);
|
||||
|
||||
return $test;
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Doctrine\ORM\OptimisticLockException
|
||||
* @depends testJoinedChildInsertSetsInitialVersionValue
|
||||
*/
|
||||
public function testJoinedChildFailureThrowsException()
|
||||
public function testJoinedChildFailureThrowsException(OptimisticJoinedChild $child)
|
||||
{
|
||||
$q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticJoinedChild t WHERE t.name = :name');
|
||||
$q->setParameter('name', 'child');
|
||||
$q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticJoinedChild t WHERE t.id = :id');
|
||||
$q->setParameter('id', $child->id);
|
||||
$test = $q->getSingleResult();
|
||||
|
||||
// Manually update/increment the version so we can try and save the same
|
||||
@ -55,7 +58,11 @@ class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
|
||||
// Now lets change a property and try and save it again
|
||||
$test->whatever = 'ok';
|
||||
$this->_em->flush();
|
||||
try {
|
||||
$this->_em->flush();
|
||||
} catch (OptimisticLockException $e) {
|
||||
$this->assertSame($test, $e->getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
public function testJoinedParentInsertSetsInitialVersionValue()
|
||||
@ -66,15 +73,17 @@ class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertEquals(1, $test->version);
|
||||
|
||||
return $test;
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Doctrine\ORM\OptimisticLockException
|
||||
* @depends testJoinedParentInsertSetsInitialVersionValue
|
||||
*/
|
||||
public function testJoinedParentFailureThrowsException()
|
||||
public function testJoinedParentFailureThrowsException(OptimisticJoinedParent $parent)
|
||||
{
|
||||
$q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticJoinedParent t WHERE t.name = :name');
|
||||
$q->setParameter('name', 'parent');
|
||||
$q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticJoinedParent t WHERE t.id = :id');
|
||||
$q->setParameter('id', $parent->id);
|
||||
$test = $q->getSingleResult();
|
||||
|
||||
// Manually update/increment the version so we can try and save the same
|
||||
@ -84,7 +93,11 @@ class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
|
||||
// Now lets change a property and try and save it again
|
||||
$test->name = 'WHATT???';
|
||||
$this->_em->flush();
|
||||
try {
|
||||
$this->_em->flush();
|
||||
} catch (OptimisticLockException $e) {
|
||||
$this->assertSame($test, $e->getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
public function testStandardInsertSetsInitialVersionValue()
|
||||
@ -95,15 +108,17 @@ class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertEquals(1, $test->getVersion());
|
||||
|
||||
return $test;
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Doctrine\ORM\OptimisticLockException
|
||||
* @depends testStandardInsertSetsInitialVersionValue
|
||||
*/
|
||||
public function testStandardFailureThrowsException()
|
||||
public function testStandardFailureThrowsException(OptimisticStandard $entity)
|
||||
{
|
||||
$q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticStandard t WHERE t.name = :name');
|
||||
$q->setParameter('name', 'test');
|
||||
$q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticStandard t WHERE t.id = :id');
|
||||
$q->setParameter('id', $entity->id);
|
||||
$test = $q->getSingleResult();
|
||||
|
||||
// Manually update/increment the version so we can try and save the same
|
||||
@ -113,7 +128,11 @@ class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
|
||||
// Now lets change a property and try and save it again
|
||||
$test->name = 'WHATT???';
|
||||
$this->_em->flush();
|
||||
try {
|
||||
$this->_em->flush();
|
||||
} catch (OptimisticLockException $e) {
|
||||
$this->assertSame($test, $e->getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
public function testOptimisticTimestampSetsDefaultValue()
|
||||
@ -124,15 +143,17 @@ class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertTrue(strtotime($test->version) > 0);
|
||||
|
||||
return $test;
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Doctrine\ORM\OptimisticLockException
|
||||
* @depends testOptimisticTimestampSetsDefaultValue
|
||||
*/
|
||||
public function testOptimisticTimestampFailureThrowsException()
|
||||
public function testOptimisticTimestampFailureThrowsException(OptimisticTimestamp $entity)
|
||||
{
|
||||
$q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticTimestamp t WHERE t.name = :name');
|
||||
$q->setParameter('name', 'Testing');
|
||||
$q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticTimestamp t WHERE t.id = :id');
|
||||
$q->setParameter('id', $entity->id);
|
||||
$test = $q->getSingleResult();
|
||||
|
||||
$this->assertType('DateTime', $test->version);
|
||||
@ -143,7 +164,11 @@ class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
|
||||
// Try and update the record and it should throw an exception
|
||||
$test->name = 'Testing again';
|
||||
$this->_em->flush();
|
||||
try {
|
||||
$this->_em->flush();
|
||||
} catch (OptimisticLockException $e) {
|
||||
$this->assertSame($test, $e->getEntity());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user