From 37220ee8c6e66253a2aa5abbcd03aad0189e0796 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Fri, 10 Feb 2012 14:17:43 -0500 Subject: [PATCH] ... --- framework/db/ar/ActiveFinder.php | 8 ++- framework/db/ar/ActiveRecord.php | 14 +++- framework/db/dao/Command.php | 4 ++ framework/db/dao/QueryBuilder.php | 17 ++--- tests/unit/data/ar/Item.php | 17 +++++ tests/unit/data/ar/OrderItem.php | 23 ++++++ tests/unit/framework/db/ar/ActiveRecordTest.php | 94 ++++++++++++++++++++++++- 7 files changed, 161 insertions(+), 16 deletions(-) create mode 100644 tests/unit/data/ar/Item.php create mode 100644 tests/unit/data/ar/OrderItem.php diff --git a/framework/db/ar/ActiveFinder.php b/framework/db/ar/ActiveFinder.php index f651fea..ba8d30d 100644 --- a/framework/db/ar/ActiveFinder.php +++ b/framework/db/ar/ActiveFinder.php @@ -30,6 +30,8 @@ use yii\db\Exception; * todo: scope * todo: test via option * + * @property integer $count + * * @author Qiang Xue * @since 2.0 */ @@ -86,6 +88,10 @@ class ActiveFinder extends \yii\base\Object implements \IteratorAggregate, \Arra return $this->records; } + /** + * @param boolean $limitOne + * @return null|ActiveRecord + */ public function one($limitOne = true) { if ($this->records === null) { @@ -737,7 +743,7 @@ class ActiveFinder extends \yii\base\Object implements \IteratorAggregate, \Arra $command = $this->getDbConnection()->createCommand($this->sql); $command->bindValues($this->query->params); } -echo $command->sql; + $rows = $command->queryAll(); if (!empty($this->with)) { diff --git a/framework/db/ar/ActiveRecord.php b/framework/db/ar/ActiveRecord.php index 6324811..29f0a88 100644 --- a/framework/db/ar/ActiveRecord.php +++ b/framework/db/ar/ActiveRecord.php @@ -545,9 +545,17 @@ abstract class ActiveRecord extends Model } $names = array_flip($names); $attributes = array(); - foreach ($this->_attributes as $name => $value) { - if (isset($names[$name]) && (!array_key_exists($name, $this->_oldAttributes) || $value !== $this->_oldAttributes[$name])) { - $attributes[$name] = $value; + if (empty($this->_oldAttributes)) { + foreach ($this->_attributes as $name => $value) { + if (isset($names[$name])) { + $attributes[$name] = $value; + } + } + } else { + foreach ($this->_attributes as $name => $value) { + if (isset($names[$name]) && (!array_key_exists($name, $this->_oldAttributes) || $value !== $this->_oldAttributes[$name])) { + $attributes[$name] = $value; + } } } return $attributes; diff --git a/framework/db/dao/Command.php b/framework/db/dao/Command.php index 4e3e897..6da71fb 100644 --- a/framework/db/dao/Command.php +++ b/framework/db/dao/Command.php @@ -233,6 +233,8 @@ class Command extends \yii\base\Component $paramLog = "\nParameters: " . var_export($this->_params, true); } +echo "Executing SQL: {$sql}{$paramLog}" . "\n\n"; + \Yii::trace("Executing SQL: {$sql}{$paramLog}", __CLASS__); try { @@ -366,6 +368,8 @@ class Command extends \yii\base\Component $paramLog = "\nParameters: " . var_export($this->_params, true); } +echo "Executing SQL: {$sql}{$paramLog}" . "\n\n"; + \Yii::trace("Querying SQL: {$sql}{$paramLog}", __CLASS__); if ($db->queryCachingCount > 0 && $db->queryCachingDuration >= 0 && $method !== '') { diff --git a/framework/db/dao/QueryBuilder.php b/framework/db/dao/QueryBuilder.php index 4e03c62..cb03a4a 100644 --- a/framework/db/dao/QueryBuilder.php +++ b/framework/db/dao/QueryBuilder.php @@ -94,24 +94,22 @@ class QueryBuilder extends \yii\base\Object * For example, * * ~~~ - * $params = array(); * $sql = $queryBuilder->insert('tbl_user', array( * 'name' => 'Sam', * 'age' => 30, - * ), $params); + * )); * ~~~ * * @param string $table the table that new rows will be inserted into. * @param array $columns the column data (name=>value) to be inserted into the table. - * @param array $params the parameters to be bound to the query. This method will modify - * this parameter by appending new parameters to be bound to the query. * @return integer number of rows affected by the execution. */ - public function insert($table, $columns, &$params = array()) + public function insert($table, $columns) { $names = array(); $placeholders = array(); $count = 0; + $params = array(); foreach ($columns as $name => $value) { $names[] = $this->quoteColumnName($name); if ($value instanceof Expression) { @@ -150,11 +148,10 @@ class QueryBuilder extends \yii\base\Object * @param array $columns the column data (name=>value) to be updated. * @param mixed $condition the condition that will be put in the WHERE part. Please * refer to [[Query::where()]] on how to specify condition. - * @param array $params the parameters to be bound to the query. This method will modify - * this parameter by appending new parameters to be bound to the query. + * @param array $params the parameters to be bound to the query. * @return integer number of rows affected by the execution. */ - public function update($table, $columns, $condition = '', &$params = array()) + public function update($table, $columns, $condition = '', $params = array()) { $lines = array(); $count = 0; @@ -528,7 +525,7 @@ class QueryBuilder extends \yii\base\Object } } } - return '(' . implode(') AND (', $parts) . ')'; + return count($parts) === 1 ? $parts[0] : '(' . implode(') AND (', $parts) . ')'; } private function buildAndCondition($operator, $operands) @@ -745,7 +742,7 @@ class QueryBuilder extends \yii\base\Object } } - return implode("\n", $joins); + return implode($this->separator, $joins); } /** diff --git a/tests/unit/data/ar/Item.php b/tests/unit/data/ar/Item.php new file mode 100644 index 0000000..b56c1c8 --- /dev/null +++ b/tests/unit/data/ar/Item.php @@ -0,0 +1,17 @@ + array( + 'on' => '@.order_id = ?.id', + ), + 'item:Item' => array( + 'on' => '@.item_id = ?.id', + ), + ); + } +} \ No newline at end of file diff --git a/tests/unit/framework/db/ar/ActiveRecordTest.php b/tests/unit/framework/db/ar/ActiveRecordTest.php index f344c4f..c0a7175 100644 --- a/tests/unit/framework/db/ar/ActiveRecordTest.php +++ b/tests/unit/framework/db/ar/ActiveRecordTest.php @@ -3,9 +3,10 @@ namespace yiiunit\framework\db\ar; use yii\db\dao\Query; -use yii\db\ar\ActiveQuery; +use yii\db\ar\ActiveFinder; use yiiunit\data\ar\ActiveRecord; use yiiunit\data\ar\Customer; +use yiiunit\data\ar\OrderItem; class ActiveRecordTest extends \yiiunit\MysqlTestCase { @@ -14,11 +15,100 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase ActiveRecord::$db = $this->getConnection(); } + public function testInsert() + { + $customer = new Customer; + $customer->email = 'user4@example.com'; + $customer->name = 'user4'; + $customer->address = 'address4'; + + $this->assertNull($customer->id); + $this->assertTrue($customer->isNewRecord); + + $customer->save(); + + $this->assertEquals(4, $customer->id); + $this->assertFalse($customer->isNewRecord); + } + + public function testUpdate() + { + // save + $customer = Customer::find(2)->one(); + $this->assertTrue($customer instanceof Customer); + $this->assertEquals('user2', $customer->name); + $this->assertFalse($customer->isNewRecord); + $customer->name = 'user2x'; + $customer->save(); + $this->assertEquals('user2x', $customer->name); + $customer2 = Customer::find(2)->one(); + $this->assertEquals('user2x', $customer2->name); + + // saveAttributes + $customer = Customer::find(1)->one(); + $this->assertEquals('user1', $customer->name); + $this->assertEquals('address1', $customer->address); + $customer->saveAttributes(array( + 'name' => 'user1x', + 'address' => 'address1x', + )); + $this->assertEquals('user1x', $customer->name); + $this->assertEquals('address1x', $customer->address); + $customer = Customer::find(1)->one(); + $this->assertEquals('user1x', $customer->name); + $this->assertEquals('address1x', $customer->address); + + // saveCounters + $pk = array('order_id' => 2, 'item_id' => 4); + $orderItem = OrderItem::find($pk)->one(); + $this->assertEquals(1, $orderItem->quantity); + $orderItem->saveCounters(array('quantity' => -1)); + $this->assertEquals(0, $orderItem->quantity); + $orderItem = OrderItem::find($pk)->one(); + $this->assertEquals(0, $orderItem->quantity); + + // updateAll + $customer = Customer::find(3)->one(); + $this->assertEquals('user3', $customer->name); + Customer::updateAll(array( + 'name' => 'temp', + ), array('id' => 3)); + $customer = Customer::find(3)->one(); + $this->assertEquals('temp', $customer->name); + + // updateCounters + $pk = array('order_id' => 1, 'item_id' => 2); + $orderItem = OrderItem::find($pk)->one(); + $this->assertEquals(2, $orderItem->quantity); + OrderItem::updateCounters(array( + 'quantity' => 3, + ), $pk); + $orderItem = OrderItem::find($pk)->one(); + $this->assertEquals(5, $orderItem->quantity); + } + + public function testDelete() + { + $post=Post2::model()->findByPk(1); + $this->assertTrue($post->delete()); + $this->assertNull(Post2::model()->findByPk(1)); + + $this->assertTrue(Post2::model()->findByPk(2) instanceof Post2); + $this->assertTrue(Post2::model()->findByPk(3) instanceof Post2); + $this->assertEquals(2,Post2::model()->deleteByPk(array(2,3))); + $this->assertNull(Post2::model()->findByPk(2)); + $this->assertNull(Post2::model()->findByPk(3)); + + $this->assertTrue(Post2::model()->findByPk(5) instanceof Post2); + $this->assertEquals(1,Post2::model()->deleteAll('id=5')); + $this->assertNull(Post2::model()->findByPk(5)); + } + public function testFind() { // find one $result = Customer::find(); - $this->assertTrue($result instanceof ActiveQuery); + $this->assertTrue($result instanceof ActiveFinder); $customer = $result->one(); $this->assertTrue($customer instanceof Customer); $this->assertEquals(1, $result->count);