From aa5887fec783ec82de193066299d11cbeed5aae4 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Thu, 28 May 2015 17:55:53 +0200 Subject: [PATCH] added missing use statement to fix #8572 - added unit tests for timestamp behavior and insert with expression - fixed issue #8572 close #8596 --- framework/db/mysql/QueryBuilder.php | 3 +- framework/db/oci/QueryBuilder.php | 1 + .../behaviors/TimestampBehaviorTest.php | 83 +++++++++++++++++-- tests/framework/db/CommandTest.php | 52 +++++++++++- 4 files changed, 132 insertions(+), 7 deletions(-) diff --git a/framework/db/mysql/QueryBuilder.php b/framework/db/mysql/QueryBuilder.php index 14f946d7a2..c045473a2b 100644 --- a/framework/db/mysql/QueryBuilder.php +++ b/framework/db/mysql/QueryBuilder.php @@ -7,8 +7,9 @@ namespace yii\db\mysql; -use yii\db\Exception; use yii\base\InvalidParamException; +use yii\db\Exception; +use yii\db\Expression; /** * QueryBuilder is the query builder for MySQL databases. diff --git a/framework/db/oci/QueryBuilder.php b/framework/db/oci/QueryBuilder.php index ff1f1afdbd..334c9a0f5d 100644 --- a/framework/db/oci/QueryBuilder.php +++ b/framework/db/oci/QueryBuilder.php @@ -10,6 +10,7 @@ namespace yii\db\oci; use yii\base\InvalidParamException; use yii\db\Connection; use yii\db\Exception; +use yii\db\Expression; /** * QueryBuilder is the query builder for Oracle databases. diff --git a/tests/framework/behaviors/TimestampBehaviorTest.php b/tests/framework/behaviors/TimestampBehaviorTest.php index 40d6886406..5f158ba5ae 100644 --- a/tests/framework/behaviors/TimestampBehaviorTest.php +++ b/tests/framework/behaviors/TimestampBehaviorTest.php @@ -3,6 +3,7 @@ namespace yiiunit\framework\behaviors; use Yii; +use yii\db\Expression; use yiiunit\TestCase; use yii\db\Connection; use yii\db\ActiveRecord; @@ -41,10 +42,17 @@ class TimestampBehaviorTest extends TestCase $columns = [ 'id' => 'pk', - 'created_at' => 'integer', + 'created_at' => 'integer NOT NULL', 'updated_at' => 'integer', ]; Yii::$app->getDb()->createCommand()->createTable('test_auto_timestamp', $columns)->execute(); + + $columns = [ + 'id' => 'pk', + 'created_at' => 'string NOT NULL', + 'updated_at' => 'string', + ]; + Yii::$app->getDb()->createCommand()->createTable('test_auto_timestamp_string', $columns)->execute(); } public function tearDown() @@ -59,6 +67,9 @@ class TimestampBehaviorTest extends TestCase { $currentTime = time(); + ActiveRecordTimestamp::$behaviors = [ + TimestampBehavior::className(), + ]; $model = new ActiveRecordTimestamp(); $model->save(false); @@ -73,6 +84,9 @@ class TimestampBehaviorTest extends TestCase { $currentTime = time(); + ActiveRecordTimestamp::$behaviors = [ + TimestampBehavior::className(), + ]; $model = new ActiveRecordTimestamp(); $model->save(false); @@ -85,6 +99,64 @@ class TimestampBehaviorTest extends TestCase $this->assertEquals($enforcedTime, $model->created_at, 'Create time has been set on update!'); $this->assertTrue($model->updated_at >= $currentTime, 'Update time has NOT been set on update!'); } + + public function expressionProvider() + { + return [ + [function() { return '2015-01-01'; }, '2015-01-01'], + [new Expression("strftime('%Y')"), date('Y')], + ]; + } + + /** + * @dataProvider expressionProvider + */ + public function testNewRecordExpression($expression, $expected) + { + ActiveRecordTimestamp::$tableName = 'test_auto_timestamp_string'; + ActiveRecordTimestamp::$behaviors = [ + 'timestamp' => [ + 'class' => TimestampBehavior::className(), + 'value' => $expression, + ], + ]; + $model = new ActiveRecordTimestamp(); + $model->save(false); + if ($expression instanceof Expression) { + $this->assertInstanceOf(Expression::className(), $model->created_at); + $this->assertInstanceOf(Expression::className(), $model->updated_at); + $model->refresh(); + } + $this->assertEquals($expected, $model->created_at); + $this->assertEquals($expected, $model->updated_at); + } + + /** + * @depends testNewRecord + */ + public function testUpdateRecordExpression() + { + ActiveRecordTimestamp::$tableName = 'test_auto_timestamp_string'; + ActiveRecordTimestamp::$behaviors = [ + 'timestamp' => [ + 'class' => TimestampBehavior::className(), + 'value' => new Expression("strftime('%Y')"), + ], + ]; + $model = new ActiveRecordTimestamp(); + $model->save(false); + + $enforcedTime = date('Y') - 1; + + $model->created_at = $enforcedTime; + $model->updated_at = $enforcedTime; + $model->save(false); + $this->assertEquals($enforcedTime, $model->created_at, 'Create time has been set on update!'); + $this->assertInstanceOf(Expression::className(), $model->updated_at); + $model->refresh(); + $this->assertEquals($enforcedTime, $model->created_at, 'Create time has been set on update!'); + $this->assertEquals(date('Y'), $model->updated_at); + } } /** @@ -96,15 +168,16 @@ class TimestampBehaviorTest extends TestCase */ class ActiveRecordTimestamp extends ActiveRecord { + public static $behaviors; + public static $tableName = 'test_auto_timestamp'; + public function behaviors() { - return [ - TimestampBehavior::className(), - ]; + return static::$behaviors; } public static function tableName() { - return 'test_auto_timestamp'; + return static::$tableName; } } diff --git a/tests/framework/db/CommandTest.php b/tests/framework/db/CommandTest.php index fdf8e55d42..bd04817c25 100644 --- a/tests/framework/db/CommandTest.php +++ b/tests/framework/db/CommandTest.php @@ -5,6 +5,7 @@ namespace yiiunit\framework\db; use yii\caching\FileCache; use yii\db\Connection; use yii\db\DataReader; +use yii\db\Expression; /** * @group db @@ -258,11 +259,60 @@ SQL; $this->assertEquals(2, $command->execute()); } - /* public function testInsert() { + $db = $this->getConnection(); + $db->createCommand('DELETE FROM {{customer}};')->execute(); + + $command = $db->createCommand(); + $command->insert( + '{{customer}}', + [ + 'email' => 't1@example.com', + 'name' => 'test', + 'address' => 'test address', + ] + )->execute(); + $this->assertEquals(1, $db->createCommand('SELECT COUNT(*) FROM {{customer}};')->queryScalar()); + $record = $db->createCommand('SELECT email, name, address FROM {{customer}};')->queryOne(); + $this->assertEquals([ + 'email' => 't1@example.com', + 'name' => 'test', + 'address' => 'test address', + ], $record); } + public function testInsertExpression() + { + $db = $this->getConnection(); + $db->createCommand('DELETE FROM {{order_with_null_fk}};')->execute(); + + switch($this->driverName){ + case 'pgsql': $expression = "EXTRACT(YEAR FROM TIMESTAMP 'now')"; break; + case 'cubrid': + case 'mysql': $expression = "YEAR(NOW())"; break; + default: + case 'sqlite': $expression = "strftime('%Y')"; break; + } + + $command = $db->createCommand(); + $command->insert( + '{{order_with_null_fk}}', + [ + 'created_at' => new Expression($expression), + 'total' => 1, + ] + )->execute(); + $this->assertEquals(1, $db->createCommand('SELECT COUNT(*) FROM {{order_with_null_fk}};')->queryScalar()); + $record = $db->createCommand('SELECT created_at FROM {{order_with_null_fk}};')->queryOne(); + $this->assertEquals([ + 'created_at' => date('Y'), + ], $record); + } + + + + /* public function testUpdate() { }