Browse Source

refactored the active property of Connection and Transaction.

refactored Transaction.
tags/2.0.0-beta
Qiang Xue 12 years ago
parent
commit
736d30684e
  1. 38
      framework/db/Connection.php
  2. 59
      framework/db/Transaction.php
  3. 2
      tests/unit/MysqlTestCase.php
  4. 8
      tests/unit/framework/db/ConnectionTest.php

38
framework/db/Connection.php

@ -19,7 +19,7 @@ use yii\db\Exception;
* of the [[PDO PHP extension]](http://www.php.net/manual/en/ref.pdo.php). * of the [[PDO PHP extension]](http://www.php.net/manual/en/ref.pdo.php).
* *
* To establish a DB connection, set [[dsn]], [[username]] and [[password]], and then * To establish a DB connection, set [[dsn]], [[username]] and [[password]], and then
* call [[open]] or set [[active]] to be true. * call [[open()]] to be true.
* *
* The following example shows how to create a Connection instance and establish * The following example shows how to create a Connection instance and establish
* the DB connection: * the DB connection:
@ -30,7 +30,7 @@ use yii\db\Exception;
* 'username' => $username, * 'username' => $username,
* 'password' => $password, * 'password' => $password,
* )); * ));
* $connection->active = true; // same as: $connection->open(); * $connection->open();
* ~~~ * ~~~
* *
* After the DB connection is established, one can execute SQL statements like the following: * After the DB connection is established, one can execute SQL statements like the following:
@ -60,12 +60,12 @@ use yii\db\Exception;
* ~~~ * ~~~
* $transaction = $connection->beginTransaction(); * $transaction = $connection->beginTransaction();
* try { * try {
* $connection->createCommand($sql1)->execute(); * $connection->createCommand($sql1)->execute();
* $connection->createCommand($sql2)->execute(); * $connection->createCommand($sql2)->execute();
* // ... executing other SQL statements ... * // ... executing other SQL statements ...
* $transaction->commit(); * $transaction->commit();
* } catch(Exception $e) { * } catch(Exception $e) {
* $transaction->rollBack(); * $transaction->rollBack();
* } * }
* ~~~ * ~~~
* *
@ -86,7 +86,7 @@ use yii\db\Exception;
* ) * )
* ~~~ * ~~~
* *
* @property boolean $active Whether the DB connection is established. * @property boolean $isActive Whether the DB connection is established. This property is read-only.
* @property Transaction $currentTransaction The currently active transaction. Null if no active transaction. * @property Transaction $currentTransaction The currently active transaction. Null if no active transaction.
* @property Driver $driver The database driver for the current connection. * @property Driver $driver The database driver for the current connection.
* @property QueryBuilder $queryBuilder The query builder. * @property QueryBuilder $queryBuilder The query builder.
@ -290,22 +290,12 @@ class Connection extends \yii\base\ApplicationComponent
* Returns a value indicating whether the DB connection is established. * Returns a value indicating whether the DB connection is established.
* @return boolean whether the DB connection is established * @return boolean whether the DB connection is established
*/ */
public function getActive() public function getIsActive()
{ {
return $this->pdo !== null; return $this->pdo !== null;
} }
/** /**
* Opens or closes the DB connection.
* @param boolean $value whether to open or close the DB connection
* @throws Exception if there is any error when establishing the connection
*/
public function setActive($value)
{
$value ? $this->open() : $this->close();
}
/**
* Turns on query caching. * Turns on query caching.
* This method is provided as a shortcut to setting two properties that are related * This method is provided as a shortcut to setting two properties that are related
* with query caching: [[queryCacheDuration]] and [[queryCacheDependency]]. * with query caching: [[queryCacheDuration]] and [[queryCacheDependency]].
@ -433,7 +423,7 @@ class Connection extends \yii\base\ApplicationComponent
*/ */
public function getCurrentTransaction() public function getCurrentTransaction()
{ {
if ($this->_transaction !== null && $this->_transaction->active) { if ($this->_transaction !== null && $this->_transaction->isActive) {
return $this->_transaction; return $this->_transaction;
} else { } else {
return null; return null;
@ -446,10 +436,12 @@ class Connection extends \yii\base\ApplicationComponent
*/ */
public function beginTransaction() public function beginTransaction()
{ {
\Yii::trace('Starting transaction', __CLASS__);
$this->open(); $this->open();
$this->pdo->beginTransaction(); $this->_transaction = new Transaction(array(
return $this->_transaction = new Transaction($this); 'connection' => $this,
));
$this->_transaction->begin();
return $this->_transaction;
} }
/** /**

59
framework/db/Transaction.php

@ -10,6 +10,7 @@
namespace yii\db; namespace yii\db;
use yii\db\Exception; use yii\db\Exception;
use yii\base\BadConfigException;
/** /**
* Transaction represents a DB transaction. * Transaction represents a DB transaction.
@ -22,41 +23,57 @@ use yii\db\Exception;
* ~~~ * ~~~
* $transaction = $connection->beginTransaction(); * $transaction = $connection->beginTransaction();
* try { * try {
* $connection->createCommand($sql1)->execute(); * $connection->createCommand($sql1)->execute();
* $connection->createCommand($sql2)->execute(); * $connection->createCommand($sql2)->execute();
* //.... other SQL executions * //.... other SQL executions
* $transaction->commit(); * $transaction->commit();
* } catch(Exception $e) { * } catch(Exception $e) {
* $transaction->rollBack(); * $transaction->rollBack();
* } * }
* ~~~ * ~~~
* *
* @property boolean $isActive Whether the transaction is active. This property is read-only.
*
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
class Transaction extends \yii\base\Object class Transaction extends \yii\base\Object
{ {
/** /**
* @var Connection the database connection that this transaction is associated with.
*/
public $connection;
/**
* @var boolean whether this transaction is active. Only an active transaction * @var boolean whether this transaction is active. Only an active transaction
* can [[commit()]] or [[rollBack()]]. This property is set true when the transaction is started. * can [[commit()]] or [[rollBack()]]. This property is set true when the transaction is started.
*/ */
public $active; private $_active = false;
/** /**
* @var Connection the database connection that this transaction is associated with. * Returns a value indicating whether this transaction is active.
* @return boolean whether this transaction is active. Only an active transaction
* can [[commit()]] or [[rollBack()]].
*/ */
public $connection; public function getIsActive()
{
return $this->_active;
}
/** /**
* Constructor. * Begins a transaction.
* @param Connection $connection the connection associated with this transaction * @throws BadConfigException if [[connection]] is null
* @param array $config name-value pairs that will be used to initialize the object properties
* @see Connection::beginTransaction
*/ */
public function __construct($connection, $config = array()) public function begin()
{ {
$this->active = true; if (!$this->_active) {
$this->connection = $connection; if ($this->connection === null) {
parent::__construct($config); throw new BadConfigException('Transaction::connection must be set.');
}
\Yii::trace('Starting transaction', __CLASS__);
$this->connection->open();
$this->connection->pdo->beginTransaction();
$this->_active = true;
}
} }
/** /**
@ -65,10 +82,10 @@ class Transaction extends \yii\base\Object
*/ */
public function commit() public function commit()
{ {
if ($this->active && $this->connection->getActive()) { if ($this->_active && $this->connection && $this->connection->isActive) {
\Yii::trace('Committing transaction', __CLASS__); \Yii::trace('Committing transaction', __CLASS__);
$this->connection->pdo->commit(); $this->connection->pdo->commit();
$this->active = false; $this->_active = false;
} else { } else {
throw new Exception('Failed to commit transaction: transaction was inactive.'); throw new Exception('Failed to commit transaction: transaction was inactive.');
} }
@ -80,10 +97,10 @@ class Transaction extends \yii\base\Object
*/ */
public function rollback() public function rollback()
{ {
if ($this->active && $this->connection->getActive()) { if ($this->_active && $this->connection && $this->connection->isActive) {
\Yii::trace('Rolling back transaction', __CLASS__); \Yii::trace('Rolling back transaction', __CLASS__);
$this->connection->pdo->rollBack(); $this->connection->pdo->commit();
$this->active = false; $this->_active = false;
} else { } else {
throw new Exception('Failed to roll back transaction: transaction was inactive.'); throw new Exception('Failed to roll back transaction: transaction was inactive.');
} }

2
tests/unit/MysqlTestCase.php

@ -23,7 +23,7 @@ class MysqlTestCase extends TestCase
$db->username = $params['username']; $db->username = $params['username'];
$db->password = $params['password']; $db->password = $params['password'];
if ($reset) { if ($reset) {
$db->active = true; $db->open();
$lines = explode(';', file_get_contents($params['fixture'])); $lines = explode(';', file_get_contents($params['fixture']));
foreach ($lines as $line) { foreach ($lines as $line) {
if (trim($line) !== '') { if (trim($line) !== '') {

8
tests/unit/framework/db/ConnectionTest.php

@ -20,15 +20,15 @@ class ConnectionTest extends \yiiunit\MysqlTestCase
{ {
$connection = $this->getConnection(false); $connection = $this->getConnection(false);
$this->assertFalse($connection->active); $this->assertFalse($connection->isActive);
$this->assertEquals(null, $connection->pdo); $this->assertEquals(null, $connection->pdo);
$connection->open(); $connection->open();
$this->assertTrue($connection->active); $this->assertTrue($connection->isActive);
$this->assertTrue($connection->pdo instanceof \PDO); $this->assertTrue($connection->pdo instanceof \PDO);
$connection->close(); $connection->close();
$this->assertFalse($connection->active); $this->assertFalse($connection->isActive);
$this->assertEquals(null, $connection->pdo); $this->assertEquals(null, $connection->pdo);
$connection = new Connection; $connection = new Connection;
@ -41,7 +41,7 @@ class ConnectionTest extends \yiiunit\MysqlTestCase
{ {
$connection = $this->getConnection(false); $connection = $this->getConnection(false);
$this->assertEquals('mysql', $connection->driverName); $this->assertEquals('mysql', $connection->driverName);
$this->assertFalse($connection->active); $this->assertFalse($connection->isActive);
} }
function testQuoteValue() function testQuoteValue()

Loading…
Cancel
Save