From 736d30684ec2ead718c435b56696ff6d110164ea Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Tue, 15 Jan 2013 19:13:39 -0500 Subject: [PATCH] refactored the active property of Connection and Transaction. refactored Transaction. --- framework/db/Connection.php | 38 ++++++++----------- framework/db/Transaction.php | 59 +++++++++++++++++++----------- tests/unit/MysqlTestCase.php | 2 +- tests/unit/framework/db/ConnectionTest.php | 8 ++-- 4 files changed, 58 insertions(+), 49 deletions(-) diff --git a/framework/db/Connection.php b/framework/db/Connection.php index 0b04b2a..13a9a77 100644 --- a/framework/db/Connection.php +++ b/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). * * 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 DB connection: @@ -30,7 +30,7 @@ use yii\db\Exception; * 'username' => $username, * '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: @@ -60,12 +60,12 @@ use yii\db\Exception; * ~~~ * $transaction = $connection->beginTransaction(); * try { - * $connection->createCommand($sql1)->execute(); - * $connection->createCommand($sql2)->execute(); - * // ... executing other SQL statements ... - * $transaction->commit(); + * $connection->createCommand($sql1)->execute(); + * $connection->createCommand($sql2)->execute(); + * // ... executing other SQL statements ... + * $transaction->commit(); * } 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 Driver $driver The database driver for the current connection. * @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. * @return boolean whether the DB connection is established */ - public function getActive() + public function getIsActive() { 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. * This method is provided as a shortcut to setting two properties that are related * with query caching: [[queryCacheDuration]] and [[queryCacheDependency]]. @@ -433,7 +423,7 @@ class Connection extends \yii\base\ApplicationComponent */ public function getCurrentTransaction() { - if ($this->_transaction !== null && $this->_transaction->active) { + if ($this->_transaction !== null && $this->_transaction->isActive) { return $this->_transaction; } else { return null; @@ -446,10 +436,12 @@ class Connection extends \yii\base\ApplicationComponent */ public function beginTransaction() { - \Yii::trace('Starting transaction', __CLASS__); $this->open(); - $this->pdo->beginTransaction(); - return $this->_transaction = new Transaction($this); + $this->_transaction = new Transaction(array( + 'connection' => $this, + )); + $this->_transaction->begin(); + return $this->_transaction; } /** diff --git a/framework/db/Transaction.php b/framework/db/Transaction.php index 5f134f0..fc9867a 100644 --- a/framework/db/Transaction.php +++ b/framework/db/Transaction.php @@ -10,6 +10,7 @@ namespace yii\db; use yii\db\Exception; +use yii\base\BadConfigException; /** * Transaction represents a DB transaction. @@ -22,41 +23,57 @@ use yii\db\Exception; * ~~~ * $transaction = $connection->beginTransaction(); * try { - * $connection->createCommand($sql1)->execute(); - * $connection->createCommand($sql2)->execute(); - * //.... other SQL executions - * $transaction->commit(); + * $connection->createCommand($sql1)->execute(); + * $connection->createCommand($sql2)->execute(); + * //.... other SQL executions + * $transaction->commit(); * } catch(Exception $e) { - * $transaction->rollBack(); + * $transaction->rollBack(); * } * ~~~ * + * @property boolean $isActive Whether the transaction is active. This property is read-only. + * * @author Qiang Xue * @since 2.0 */ 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 * 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. - * @param Connection $connection the connection associated with this transaction - * @param array $config name-value pairs that will be used to initialize the object properties - * @see Connection::beginTransaction + * Begins a transaction. + * @throws BadConfigException if [[connection]] is null */ - public function __construct($connection, $config = array()) + public function begin() { - $this->active = true; - $this->connection = $connection; - parent::__construct($config); + if (!$this->_active) { + if ($this->connection === null) { + 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() { - if ($this->active && $this->connection->getActive()) { + if ($this->_active && $this->connection && $this->connection->isActive) { \Yii::trace('Committing transaction', __CLASS__); $this->connection->pdo->commit(); - $this->active = false; + $this->_active = false; } else { throw new Exception('Failed to commit transaction: transaction was inactive.'); } @@ -80,10 +97,10 @@ class Transaction extends \yii\base\Object */ public function rollback() { - if ($this->active && $this->connection->getActive()) { + if ($this->_active && $this->connection && $this->connection->isActive) { \Yii::trace('Rolling back transaction', __CLASS__); - $this->connection->pdo->rollBack(); - $this->active = false; + $this->connection->pdo->commit(); + $this->_active = false; } else { throw new Exception('Failed to roll back transaction: transaction was inactive.'); } diff --git a/tests/unit/MysqlTestCase.php b/tests/unit/MysqlTestCase.php index 5fe7dbd..d62f95e 100644 --- a/tests/unit/MysqlTestCase.php +++ b/tests/unit/MysqlTestCase.php @@ -23,7 +23,7 @@ class MysqlTestCase extends TestCase $db->username = $params['username']; $db->password = $params['password']; if ($reset) { - $db->active = true; + $db->open(); $lines = explode(';', file_get_contents($params['fixture'])); foreach ($lines as $line) { if (trim($line) !== '') { diff --git a/tests/unit/framework/db/ConnectionTest.php b/tests/unit/framework/db/ConnectionTest.php index 907dda6..64f93be 100644 --- a/tests/unit/framework/db/ConnectionTest.php +++ b/tests/unit/framework/db/ConnectionTest.php @@ -20,15 +20,15 @@ class ConnectionTest extends \yiiunit\MysqlTestCase { $connection = $this->getConnection(false); - $this->assertFalse($connection->active); + $this->assertFalse($connection->isActive); $this->assertEquals(null, $connection->pdo); $connection->open(); - $this->assertTrue($connection->active); + $this->assertTrue($connection->isActive); $this->assertTrue($connection->pdo instanceof \PDO); $connection->close(); - $this->assertFalse($connection->active); + $this->assertFalse($connection->isActive); $this->assertEquals(null, $connection->pdo); $connection = new Connection; @@ -41,7 +41,7 @@ class ConnectionTest extends \yiiunit\MysqlTestCase { $connection = $this->getConnection(false); $this->assertEquals('mysql', $connection->driverName); - $this->assertFalse($connection->active); + $this->assertFalse($connection->isActive); } function testQuoteValue()