From 4f95fcd91f32f3b6c3722173dc4c8ce4af3179cc Mon Sep 17 00:00:00 2001 From: Carsten Brandt <mail@cebe.cc> Date: Wed, 25 Jun 2014 03:09:28 +0200 Subject: [PATCH] added unit tests for schema detection fixed some issues with schema detection --- framework/db/ColumnSchema.php | 2 ++ framework/db/cubrid/Schema.php | 11 ++++++----- framework/db/mysql/Schema.php | 13 +++++++++---- framework/db/sqlite/Schema.php | 13 ++++++++----- framework/views/errorHandler/exception.php | 1 + tests/unit/data/cubrid.sql | 253 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------ tests/unit/data/mysql.sql | 8 +++++--- tests/unit/data/postgres.sql | 3 ++- tests/unit/data/sqlite.sql | 3 ++- tests/unit/framework/db/ConnectionTest.php | 62 +++++++++++++++++++++++++++++++------------------------------- tests/unit/framework/db/SchemaTest.php | 207 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/unit/framework/db/cubrid/CubridSchemaTest.php | 34 ++++++++++++++++++++++++++++++++++ tests/unit/framework/db/pgsql/PostgreSQLConnectionTest.php | 38 +++++++++++++++++++------------------- tests/unit/framework/db/pgsql/PostgreSQLQueryTest.php | 16 ++++++++++++++++ tests/unit/framework/db/pgsql/PostgreSQLSchemaTest.php | 33 +++++++++++++++++++++++++++++++++ tests/unit/framework/db/sqlite/SqliteConnectionTest.php | 16 ++++++++-------- tests/unit/framework/db/sqlite/SqliteSchemaTest.php | 19 +++++++++++++++++++ 17 files changed, 529 insertions(+), 203 deletions(-) create mode 100644 tests/unit/framework/db/pgsql/PostgreSQLQueryTest.php create mode 100644 tests/unit/framework/db/pgsql/PostgreSQLSchemaTest.php diff --git a/framework/db/ColumnSchema.php b/framework/db/ColumnSchema.php index e1898e2..a9efcbf 100644 --- a/framework/db/ColumnSchema.php +++ b/framework/db/ColumnSchema.php @@ -99,6 +99,8 @@ class ColumnSchema extends Object return (integer) $value; case 'boolean': return (boolean) $value; + case 'double': + return (double) $value; } return $value; diff --git a/framework/db/cubrid/Schema.php b/framework/db/cubrid/Schema.php index 61c13e5..3a5d231 100644 --- a/framework/db/cubrid/Schema.php +++ b/framework/db/cubrid/Schema.php @@ -200,18 +200,19 @@ class Schema extends \yii\db\Schema $column->isPrimaryKey = false; // primary key will be set by loadTableSchema() later $column->autoIncrement = stripos($info['Extra'], 'auto_increment') !== false; - $column->dbType = strtolower($info['Type']); + $column->dbType = $info['Type']; $column->unsigned = strpos($column->dbType, 'unsigned') !== false; $column->type = self::TYPE_STRING; - if (preg_match('/^([\w ]+)(?:\(([^\)]+)\))?/', $column->dbType, $matches)) { - $type = $matches[1]; + if (preg_match('/^([\w ]+)(?:\(([^\)]+)\))?$/', $column->dbType, $matches)) { + $type = strtolower($matches[1]); + $column->dbType = $type . (isset($matches[2]) ? "({$matches[2]})" : ''); if (isset($this->typeMap[$type])) { $column->type = $this->typeMap[$type]; } if (!empty($matches[2])) { if ($type === 'enum') { - $values = explode(',', $matches[2]); + $values = preg_split('/\s*,\s*/', $matches[2]); foreach ($values as $i => $value) { $values[$i] = trim($value, "'"); } @@ -232,7 +233,7 @@ class Schema extends \yii\db\Schema return $column; } - if ($column->type === 'timestamp' && $info['Default'] === 'CURRENT_TIMESTAMP' || + if ($column->type === 'timestamp' && $info['Default'] === 'SYS_TIMESTAMP' || $column->type === 'datetime' && $info['Default'] === 'SYS_DATETIME' || $column->type === 'date' && $info['Default'] === 'SYS_DATE' || $column->type === 'time' && $info['Default'] === 'SYS_TIME' diff --git a/framework/db/mysql/Schema.php b/framework/db/mysql/Schema.php index b7a7a26..8b7c30a 100644 --- a/framework/db/mysql/Schema.php +++ b/framework/db/mysql/Schema.php @@ -7,6 +7,7 @@ namespace yii\db\mysql; +use yii\db\Expression; use yii\db\TableSchema; use yii\db\ColumnSchema; @@ -132,11 +133,11 @@ class Schema extends \yii\db\Schema $column->comment = $info['Comment']; $column->dbType = $info['Type']; - $column->unsigned = strpos($column->dbType, 'unsigned') !== false; + $column->unsigned = stripos($column->dbType, 'unsigned') !== false; $column->type = self::TYPE_STRING; if (preg_match('/^(\w+)(?:\(([^\)]+)\))?/', $column->dbType, $matches)) { - $type = $matches[1]; + $type = strtolower($matches[1]); if (isset($this->typeMap[$type])) { $column->type = $this->typeMap[$type]; } @@ -168,8 +169,12 @@ class Schema extends \yii\db\Schema $column->phpType = $this->getColumnPhpType($column); - if (!$column->isPrimaryKey && ($column->type !== 'timestamp' || $info['Default'] !== 'CURRENT_TIMESTAMP')) { - $column->defaultValue = $column->typecast($info['Default']); + if (!$column->isPrimaryKey) { + if ($column->type === 'timestamp' && $info['Default'] === 'CURRENT_TIMESTAMP') { + $column->defaultValue = new Expression('CURRENT_TIMESTAMP'); + } else { + $column->defaultValue = $column->typecast($info['Default']); + } } return $column; diff --git a/framework/db/sqlite/Schema.php b/framework/db/sqlite/Schema.php index eecdfc3..e2f2f33 100644 --- a/framework/db/sqlite/Schema.php +++ b/framework/db/sqlite/Schema.php @@ -8,6 +8,7 @@ namespace yii\db\sqlite; use yii\base\NotSupportedException; +use yii\db\Expression; use yii\db\TableSchema; use yii\db\ColumnSchema; use yii\db\Transaction; @@ -211,7 +212,7 @@ class Schema extends \yii\db\Schema $column->allowNull = !$info['notnull']; $column->isPrimaryKey = $info['pk'] != 0; - $column->dbType = $info['type']; + $column->dbType = strtolower($info['type']); $column->unsigned = strpos($column->dbType, 'unsigned') !== false; $column->type = self::TYPE_STRING; @@ -241,11 +242,13 @@ class Schema extends \yii\db\Schema $column->phpType = $this->getColumnPhpType($column); if (!$column->isPrimaryKey) { - $value = trim($info['dflt_value'], "'\""); - if ($column->type === 'string') { - $column->defaultValue = $value; + if ($info['dflt_value'] === 'null' || $info['dflt_value'] === '' || $info['dflt_value'] === null) { + $column->defaultValue = null; + } elseif ($column->type === 'timestamp' && $info['dflt_value'] === 'CURRENT_TIMESTAMP') { + $column->defaultValue = new Expression('CURRENT_TIMESTAMP'); } else { - $column->defaultValue = $column->typecast(strcasecmp($value, 'null') ? $value : null); + $value = trim($info['dflt_value'], "'\""); + $column->defaultValue = $column->typecast($value); } } diff --git a/framework/views/errorHandler/exception.php b/framework/views/errorHandler/exception.php index 7007272..36cb15f 100644 --- a/framework/views/errorHandler/exception.php +++ b/framework/views/errorHandler/exception.php @@ -1,4 +1,5 @@ <?php +/* @var $this \yii\web\View */ /* @var $exception \Exception */ /* @var $handler \yii\web\ErrorHandler */ ?> diff --git a/tests/unit/data/cubrid.sql b/tests/unit/data/cubrid.sql index ee7c618..3e31333 100644 --- a/tests/unit/data/cubrid.sql +++ b/tests/unit/data/cubrid.sql @@ -3,158 +3,159 @@ * The database setup in config.php is required to perform then relevant tests: */ -DROP TABLE IF EXISTS `composite_fk`; -DROP TABLE IF EXISTS `order_item`; -DROP TABLE IF EXISTS `order_item_with_null_fk`; -DROP TABLE IF EXISTS `item`; -DROP TABLE IF EXISTS `order`; -DROP TABLE IF EXISTS `order_with_null_fk`; -DROP TABLE IF EXISTS `category`; -DROP TABLE IF EXISTS `customer`; -DROP TABLE IF EXISTS `profile`; -DROP TABLE IF EXISTS `null_values`; -DROP TABLE IF EXISTS `type`; -DROP TABLE IF EXISTS `constraints`; - -CREATE TABLE `constraints` +DROP TABLE IF EXISTS "composite_fk"; +DROP TABLE IF EXISTS "order_item"; +DROP TABLE IF EXISTS "order_item_with_null_fk"; +DROP TABLE IF EXISTS "item"; +DROP TABLE IF EXISTS "order"; +DROP TABLE IF EXISTS "order_with_null_fk"; +DROP TABLE IF EXISTS "category"; +DROP TABLE IF EXISTS "customer"; +DROP TABLE IF EXISTS "profile"; +DROP TABLE IF EXISTS "null_values"; +DROP TABLE IF EXISTS "type"; +DROP TABLE IF EXISTS "constraints"; + +CREATE TABLE "constraints" ( - `id` integer not null, - `field1` varchar(255) + "id" integer not null, + "field1" varchar(255) ); -CREATE TABLE `profile` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `description` varchar(128) NOT NULL, - PRIMARY KEY (`id`) +CREATE TABLE "profile" ( + "id" int(11) NOT NULL AUTO_INCREMENT, + "description" varchar(128) NOT NULL, + PRIMARY KEY ("id") ); -CREATE TABLE `customer` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `email` varchar(128) NOT NULL, - `name` varchar(128), - `address` string, - `status` int (11) DEFAULT 0, - `profile_id` int(11), - PRIMARY KEY (`id`) +CREATE TABLE "customer" ( + "id" int(11) NOT NULL AUTO_INCREMENT, + "email" varchar(128) NOT NULL, + "name" varchar(128), + "address" string, + "status" int (11) DEFAULT 0, + "profile_id" int(11), + PRIMARY KEY ("id") ); -CREATE TABLE `category` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(128) NOT NULL, - PRIMARY KEY (`id`) +CREATE TABLE "category" ( + "id" int(11) NOT NULL AUTO_INCREMENT, + "name" varchar(128) NOT NULL, + PRIMARY KEY ("id") ); -CREATE TABLE `item` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(128) NOT NULL, - `category_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - CONSTRAINT `FK_item_category_id` FOREIGN KEY (`category_id`) REFERENCES `category` (`id`) ON DELETE CASCADE +CREATE TABLE "item" ( + "id" int(11) NOT NULL AUTO_INCREMENT, + "name" varchar(128) NOT NULL, + "category_id" int(11) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "FK_item_category_id" FOREIGN KEY ("category_id") REFERENCES "category" ("id") ON DELETE CASCADE ); -CREATE TABLE `order` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `customer_id` int(11) NOT NULL, - `created_at` int(11) NOT NULL, - `total` decimal(10,0) NOT NULL, - PRIMARY KEY (`id`), - CONSTRAINT `FK_order_customer_id` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`id`) ON DELETE CASCADE +CREATE TABLE "order" ( + "id" int(11) NOT NULL AUTO_INCREMENT, + "customer_id" int(11) NOT NULL, + "created_at" int(11) NOT NULL, + "total" decimal(10,0) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "FK_order_customer_id" FOREIGN KEY ("customer_id") REFERENCES "customer" ("id") ON DELETE CASCADE ); -CREATE TABLE `order_with_null_fk` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `customer_id` int(11), - `created_at` int(11) NOT NULL, - `total` decimal(10,0) NOT NULL, - PRIMARY KEY (`id`) +CREATE TABLE "order_with_null_fk" ( + "id" int(11) NOT NULL AUTO_INCREMENT, + "customer_id" int(11), + "created_at" int(11) NOT NULL, + "total" decimal(10,0) NOT NULL, + PRIMARY KEY ("id") ); -CREATE TABLE `order_item` ( - `order_id` int(11) NOT NULL, - `item_id` int(11) NOT NULL, - `quantity` int(11) NOT NULL, - `subtotal` decimal(10,0) NOT NULL, - PRIMARY KEY (`order_id`,`item_id`), - CONSTRAINT `FK_order_item_order_id` FOREIGN KEY (`order_id`) REFERENCES `order` (`id`) ON DELETE CASCADE, - CONSTRAINT `FK_order_item_item_id` FOREIGN KEY (`item_id`) REFERENCES `item` (`id`) ON DELETE CASCADE +CREATE TABLE "order_item" ( + "order_id" int(11) NOT NULL, + "item_id" int(11) NOT NULL, + "quantity" int(11) NOT NULL, + "subtotal" decimal(10,0) NOT NULL, + PRIMARY KEY ("order_id","item_id"), + CONSTRAINT "FK_order_item_order_id" FOREIGN KEY ("order_id") REFERENCES "order" ("id") ON DELETE CASCADE, + CONSTRAINT "FK_order_item_item_id" FOREIGN KEY ("item_id") REFERENCES "item" ("id") ON DELETE CASCADE ); -CREATE TABLE `order_item_with_null_fk` ( - `order_id` int(11), - `item_id` int(11), - `quantity` int(11) NOT NULL, - `subtotal` decimal(10,0) NOT NULL +CREATE TABLE "order_item_with_null_fk" ( + "order_id" int(11), + "item_id" int(11), + "quantity" int(11) NOT NULL, + "subtotal" decimal(10,0) NOT NULL ); CREATE TABLE null_values ( - `id` INT(11) NOT NULL AUTO_INCREMENT, - `var1` INT NULL, - `var2` INT NULL, - `var3` INT DEFAULT NULL, - `stringcol` VARCHAR (32) DEFAULT NULL, + "id" INT(11) NOT NULL AUTO_INCREMENT, + "var1" INT NULL, + "var2" INT NULL, + "var3" INT DEFAULT NULL, + "stringcol" VARCHAR (32) DEFAULT NULL, PRIMARY KEY (id) ); -CREATE TABLE `type` ( - `int_col` int(11) NOT NULL, - `int_col2` int(11) DEFAULT '1', - `char_col` char(100) NOT NULL, - `char_col2` varchar(100) DEFAULT 'something', - `char_col3` string, - `enum_col` enum('a', 'b'), - `float_col` double NOT NULL, - `float_col2` double DEFAULT '1.23', - `blob_col` blob, - `numeric_col` decimal(5,2) DEFAULT '33.22', - `time` timestamp NOT NULL DEFAULT '2002-01-01 00:00:00', - `bool_col` tinyint NOT NULL, - `bool_col2` tinyint DEFAULT '1' +CREATE TABLE "type" ( + "int_col" int(11) NOT NULL, + "int_col2" int(11) DEFAULT '1', + "char_col" char(100) NOT NULL, + "char_col2" varchar(100) DEFAULT 'something', + "char_col3" string, + "enum_col" enum('a','B'), + "float_col" double NOT NULL, + "float_col2" double DEFAULT '1.23', + "blob_col" blob, + "numeric_col" decimal(5,2) DEFAULT '33.22', + "time" timestamp NOT NULL DEFAULT '2002-01-01 00:00:00', + "bool_col" tinyint NOT NULL, + "bool_col2" tinyint DEFAULT '1', + "ts_default" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); -CREATE TABLE `composite_fk` ( - `id` int(11) NOT NULL, - `order_id` int(11) NOT NULL, - `item_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - CONSTRAINT `FK_composite_fk_order_item` FOREIGN KEY (`order_id`,`item_id`) REFERENCES `order_item` (`order_id`,`item_id`) ON DELETE CASCADE +CREATE TABLE "composite_fk" ( + "id" int(11) NOT NULL, + "order_id" int(11) NOT NULL, + "item_id" int(11) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "FK_composite_fk_order_item" FOREIGN KEY ("order_id","item_id") REFERENCES "order_item" ("order_id","item_id") ON DELETE CASCADE ); -INSERT INTO `profile` (description) VALUES ('profile customer 1'); -INSERT INTO `profile` (description) VALUES ('profile customer 3'); - -INSERT INTO `customer` (email, name, address, status, profile_id) VALUES ('user1@example.com', 'user1', 'address1', 1, 1); -INSERT INTO `customer` (email, name, address, status) VALUES ('user2@example.com', 'user2', 'address2', 1); -INSERT INTO `customer` (email, name, address, status, profile_id) VALUES ('user3@example.com', 'user3', 'address3', 2, 2); - -INSERT INTO `category` (name) VALUES ('Books'); -INSERT INTO `category` (name) VALUES ('Movies'); - -INSERT INTO `item` (name, category_id) VALUES ('Agile Web Application Development with Yii1.1 and PHP5', 1); -INSERT INTO `item` (name, category_id) VALUES ('Yii 1.1 Application Development Cookbook', 1); -INSERT INTO `item` (name, category_id) VALUES ('Ice Age', 2); -INSERT INTO `item` (name, category_id) VALUES ('Toy Story', 2); -INSERT INTO `item` (name, category_id) VALUES ('Cars', 2); - -INSERT INTO `order` (customer_id, created_at, total) VALUES (1, 1325282384, 110.0); -INSERT INTO `order` (customer_id, created_at, total) VALUES (2, 1325334482, 33.0); -INSERT INTO `order` (customer_id, created_at, total) VALUES (2, 1325502201, 40.0); - -INSERT INTO `order_with_null_fk` (customer_id, created_at, total) VALUES (1, 1325282384, 110.0); -INSERT INTO `order_with_null_fk` (customer_id, created_at, total) VALUES (2, 1325334482, 33.0); -INSERT INTO `order_with_null_fk` (customer_id, created_at, total) VALUES (2, 1325502201, 40.0); - -INSERT INTO `order_item` (order_id, item_id, quantity, subtotal) VALUES (1, 1, 1, 30.0); -INSERT INTO `order_item` (order_id, item_id, quantity, subtotal) VALUES (1, 2, 2, 40.0); -INSERT INTO `order_item` (order_id, item_id, quantity, subtotal) VALUES (2, 4, 1, 10.0); -INSERT INTO `order_item` (order_id, item_id, quantity, subtotal) VALUES (2, 5, 1, 15.0); -INSERT INTO `order_item` (order_id, item_id, quantity, subtotal) VALUES (2, 3, 1, 8.0); -INSERT INTO `order_item` (order_id, item_id, quantity, subtotal) VALUES (3, 2, 1, 40.0); - -INSERT INTO `order_item_with_null_fk` (order_id, item_id, quantity, subtotal) VALUES (1, 1, 1, 30.0); -INSERT INTO `order_item_with_null_fk` (order_id, item_id, quantity, subtotal) VALUES (1, 2, 2, 40.0); -INSERT INTO `order_item_with_null_fk` (order_id, item_id, quantity, subtotal) VALUES (2, 4, 1, 10.0); -INSERT INTO `order_item_with_null_fk` (order_id, item_id, quantity, subtotal) VALUES (2, 5, 1, 15.0); -INSERT INTO `order_item_with_null_fk` (order_id, item_id, quantity, subtotal) VALUES (2, 3, 1, 8.0); -INSERT INTO `order_item_with_null_fk` (order_id, item_id, quantity, subtotal) VALUES (3, 2, 1, 40.0); +INSERT INTO "profile" (description) VALUES ('profile customer 1'); +INSERT INTO "profile" (description) VALUES ('profile customer 3'); + +INSERT INTO "customer" (email, name, address, status, profile_id) VALUES ('user1@example.com', 'user1', 'address1', 1, 1); +INSERT INTO "customer" (email, name, address, status) VALUES ('user2@example.com', 'user2', 'address2', 1); +INSERT INTO "customer" (email, name, address, status, profile_id) VALUES ('user3@example.com', 'user3', 'address3', 2, 2); + +INSERT INTO "category" (name) VALUES ('Books'); +INSERT INTO "category" (name) VALUES ('Movies'); + +INSERT INTO "item" (name, category_id) VALUES ('Agile Web Application Development with Yii1.1 and PHP5', 1); +INSERT INTO "item" (name, category_id) VALUES ('Yii 1.1 Application Development Cookbook', 1); +INSERT INTO "item" (name, category_id) VALUES ('Ice Age', 2); +INSERT INTO "item" (name, category_id) VALUES ('Toy Story', 2); +INSERT INTO "item" (name, category_id) VALUES ('Cars', 2); + +INSERT INTO "order" (customer_id, created_at, total) VALUES (1, 1325282384, 110.0); +INSERT INTO "order" (customer_id, created_at, total) VALUES (2, 1325334482, 33.0); +INSERT INTO "order" (customer_id, created_at, total) VALUES (2, 1325502201, 40.0); + +INSERT INTO "order_with_null_fk" (customer_id, created_at, total) VALUES (1, 1325282384, 110.0); +INSERT INTO "order_with_null_fk" (customer_id, created_at, total) VALUES (2, 1325334482, 33.0); +INSERT INTO "order_with_null_fk" (customer_id, created_at, total) VALUES (2, 1325502201, 40.0); + +INSERT INTO "order_item" (order_id, item_id, quantity, subtotal) VALUES (1, 1, 1, 30.0); +INSERT INTO "order_item" (order_id, item_id, quantity, subtotal) VALUES (1, 2, 2, 40.0); +INSERT INTO "order_item" (order_id, item_id, quantity, subtotal) VALUES (2, 4, 1, 10.0); +INSERT INTO "order_item" (order_id, item_id, quantity, subtotal) VALUES (2, 5, 1, 15.0); +INSERT INTO "order_item" (order_id, item_id, quantity, subtotal) VALUES (2, 3, 1, 8.0); +INSERT INTO "order_item" (order_id, item_id, quantity, subtotal) VALUES (3, 2, 1, 40.0); + +INSERT INTO "order_item_with_null_fk" (order_id, item_id, quantity, subtotal) VALUES (1, 1, 1, 30.0); +INSERT INTO "order_item_with_null_fk" (order_id, item_id, quantity, subtotal) VALUES (1, 2, 2, 40.0); +INSERT INTO "order_item_with_null_fk" (order_id, item_id, quantity, subtotal) VALUES (2, 4, 1, 10.0); +INSERT INTO "order_item_with_null_fk" (order_id, item_id, quantity, subtotal) VALUES (2, 5, 1, 15.0); +INSERT INTO "order_item_with_null_fk" (order_id, item_id, quantity, subtotal) VALUES (2, 3, 1, 8.0); +INSERT INTO "order_item_with_null_fk" (order_id, item_id, quantity, subtotal) VALUES (3, 2, 1, 40.0); diff --git a/tests/unit/data/mysql.sql b/tests/unit/data/mysql.sql index deb03f5..aeea84e 100644 --- a/tests/unit/data/mysql.sql +++ b/tests/unit/data/mysql.sql @@ -108,18 +108,20 @@ CREATE TABLE null_values ( ); CREATE TABLE `type` ( - `int_col` int(11) NOT NULL, - `int_col2` int(11) DEFAULT '1', + `int_col` integer NOT NULL, + `int_col2` integer DEFAULT '1', `char_col` char(100) NOT NULL, `char_col2` varchar(100) DEFAULT 'something', `char_col3` text, + `enum_col` enum('a', 'B'), `float_col` double(4,3) NOT NULL, `float_col2` double DEFAULT '1.23', `blob_col` blob, `numeric_col` decimal(5,2) DEFAULT '33.22', `time` timestamp NOT NULL DEFAULT '2002-01-01 00:00:00', `bool_col` tinyint(1) NOT NULL, - `bool_col2` tinyint(1) DEFAULT '1' + `bool_col2` tinyint(1) DEFAULT '1', + `ts_default` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `profile` (description) VALUES ('profile customer 1'); diff --git a/tests/unit/data/postgres.sql b/tests/unit/data/postgres.sql index 4163d8c..b5ebf3e 100644 --- a/tests/unit/data/postgres.sql +++ b/tests/unit/data/postgres.sql @@ -99,7 +99,8 @@ CREATE TABLE "type" ( numeric_col decimal(5,2) DEFAULT '33.22', time timestamp NOT NULL DEFAULT '2002-01-01 00:00:00', bool_col smallint NOT NULL, - bool_col2 smallint DEFAULT '1' + bool_col2 smallint DEFAULT '1', + ts_default TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); INSERT INTO "profile" (description) VALUES ('profile customer 1'); diff --git a/tests/unit/data/sqlite.sql b/tests/unit/data/sqlite.sql index 09c9da5..fa0653c 100644 --- a/tests/unit/data/sqlite.sql +++ b/tests/unit/data/sqlite.sql @@ -103,7 +103,8 @@ CREATE TABLE "type" ( numeric_col decimal(5,2) DEFAULT '33.22', time timestamp NOT NULL DEFAULT '2002-01-01 00:00:00', bool_col tinyint(1) NOT NULL, - bool_col2 tinyint(1) DEFAULT '1' + bool_col2 tinyint(1) DEFAULT '1', + ts_default TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); INSERT INTO "profile" (description) VALUES ('profile customer 1'); diff --git a/tests/unit/framework/db/ConnectionTest.php b/tests/unit/framework/db/ConnectionTest.php index 26fb31a..51be3d7 100644 --- a/tests/unit/framework/db/ConnectionTest.php +++ b/tests/unit/framework/db/ConnectionTest.php @@ -79,46 +79,46 @@ class ConnectionTest extends DatabaseTestCase $this->assertEquals('(column)', $connection->quoteColumnName('(column)')); } - public function testTransaction() - { - $connection = $this->getConnection(false); - $this->assertNull($connection->transaction); - $transaction = $connection->beginTransaction(); - $this->assertNotNull($connection->transaction); - $this->assertTrue($transaction->isActive); + public function testTransaction() + { + $connection = $this->getConnection(false); + $this->assertNull($connection->transaction); + $transaction = $connection->beginTransaction(); + $this->assertNotNull($connection->transaction); + $this->assertTrue($transaction->isActive); - $connection->createCommand()->insert('profile', ['description' => 'test transaction'])->execute(); + $connection->createCommand()->insert('profile', ['description' => 'test transaction'])->execute(); - $transaction->rollBack(); - $this->assertFalse($transaction->isActive); - $this->assertNull($connection->transaction); + $transaction->rollBack(); + $this->assertFalse($transaction->isActive); + $this->assertNull($connection->transaction); - $this->assertEquals(0, $connection->createCommand("SELECT COUNT(*) FROM profile WHERE description = 'test transaction';")->queryScalar()); + $this->assertEquals(0, $connection->createCommand("SELECT COUNT(*) FROM profile WHERE description = 'test transaction';")->queryScalar()); - $transaction = $connection->beginTransaction(); - $connection->createCommand()->insert('profile', ['description' => 'test transaction'])->execute(); - $transaction->commit(); - $this->assertFalse($transaction->isActive); - $this->assertNull($connection->transaction); + $transaction = $connection->beginTransaction(); + $connection->createCommand()->insert('profile', ['description' => 'test transaction'])->execute(); + $transaction->commit(); + $this->assertFalse($transaction->isActive); + $this->assertNull($connection->transaction); - $this->assertEquals(1, $connection->createCommand("SELECT COUNT(*) FROM profile WHERE description = 'test transaction';")->queryScalar()); - } + $this->assertEquals(1, $connection->createCommand("SELECT COUNT(*) FROM profile WHERE description = 'test transaction';")->queryScalar()); + } - public function testTransactionIsolation() - { - $connection = $this->getConnection(true); + public function testTransactionIsolation() + { + $connection = $this->getConnection(true); - $transaction = $connection->beginTransaction(Transaction::READ_UNCOMMITTED); - $transaction->commit(); + $transaction = $connection->beginTransaction(Transaction::READ_UNCOMMITTED); + $transaction->commit(); - $transaction = $connection->beginTransaction(Transaction::READ_COMMITTED); - $transaction->commit(); + $transaction = $connection->beginTransaction(Transaction::READ_COMMITTED); + $transaction->commit(); - $transaction = $connection->beginTransaction(Transaction::REPEATABLE_READ); - $transaction->commit(); + $transaction = $connection->beginTransaction(Transaction::REPEATABLE_READ); + $transaction->commit(); - $transaction = $connection->beginTransaction(Transaction::SERIALIZABLE); - $transaction->commit(); - } + $transaction = $connection->beginTransaction(Transaction::SERIALIZABLE); + $transaction->commit(); + } } diff --git a/tests/unit/framework/db/SchemaTest.php b/tests/unit/framework/db/SchemaTest.php index b77269c..b0734d9 100644 --- a/tests/unit/framework/db/SchemaTest.php +++ b/tests/unit/framework/db/SchemaTest.php @@ -3,6 +3,7 @@ namespace yiiunit\framework\db; use yii\caching\FileCache; +use yii\db\Expression; use yii\db\Schema; /** @@ -90,4 +91,210 @@ class SchemaTest extends DatabaseTestCase } fclose($fp); } + + public function getExpectedColumns() + { + return [ + 'int_col' => [ + 'type' => 'integer', + 'dbType' => 'int(11)', + 'phpType' => 'integer', + 'allowNull' => false, + 'autoIncrement' => false, + 'enumValues' => null, + 'size' => 11, + 'precision' => 11, + 'scale' => null, + 'defaultValue' => null, + ], + 'int_col2' => [ + 'type' => 'integer', + 'dbType' => 'int(11)', + 'phpType' => 'integer', + 'allowNull' => true, + 'autoIncrement' => false, + 'enumValues' => null, + 'size' => 11, + 'precision' => 11, + 'scale' => null, + 'defaultValue' => 1, + ], + 'char_col' => [ + 'type' => 'string', + 'dbType' => 'char(100)', + 'phpType' => 'string', + 'allowNull' => false, + 'autoIncrement' => false, + 'enumValues' => null, + 'size' => 100, + 'precision' => 100, + 'scale' => null, + 'defaultValue' => null, + ], + 'char_col2' => [ + 'type' => 'string', + 'dbType' => 'varchar(100)', + 'phpType' => 'string', + 'allowNull' => true, + 'autoIncrement' => false, + 'enumValues' => null, + 'size' => 100, + 'precision' => 100, + 'scale' => null, + 'defaultValue' => 'something', + ], + 'char_col3' => [ + 'type' => 'text', + 'dbType' => 'text', + 'phpType' => 'string', + 'allowNull' => true, + 'autoIncrement' => false, + 'enumValues' => null, + 'size' => null, + 'precision' => null, + 'scale' => null, + 'defaultValue' => null, + ], + 'enum_col' => [ + 'type' => 'string', + 'dbType' => "enum('a','B')", + 'phpType' => 'string', + 'allowNull' => true, + 'autoIncrement' => false, + 'enumValues' => ['a', 'B'], + 'size' => null, + 'precision' => null, + 'scale' => null, + 'defaultValue' => null, + ], + 'float_col' => [ + 'type' => 'float', + 'dbType' => 'double(4,3)', + 'phpType' => 'double', + 'allowNull' => false, + 'autoIncrement' => false, + 'enumValues' => null, + 'size' => 4, + 'precision' => 4, + 'scale' => 3, + 'defaultValue' => null, + ], + 'float_col2' => [ + 'type' => 'float', + 'dbType' => 'double', + 'phpType' => 'double', + 'allowNull' => true, + 'autoIncrement' => false, + 'enumValues' => null, + 'size' => null, + 'precision' => null, + 'scale' => null, + 'defaultValue' => 1.23, + ], + 'blob_col' => [ + 'type' => 'string', + 'dbType' => 'blob', + 'phpType' => 'string', + 'allowNull' => true, + 'autoIncrement' => false, + 'enumValues' => null, + 'size' => null, + 'precision' => null, + 'scale' => null, + 'defaultValue' => null, + ], + 'numeric_col' => [ + 'type' => 'decimal', + 'dbType' => 'decimal(5,2)', + 'phpType' => 'string', + 'allowNull' => true, + 'autoIncrement' => false, + 'enumValues' => null, + 'size' => 5, + 'precision' => 5, + 'scale' => 2, + 'defaultValue' => '33.22', + ], + 'time' => [ + 'type' => 'timestamp', + 'dbType' => 'timestamp', + 'phpType' => 'string', + 'allowNull' => false, + 'autoIncrement' => false, + 'enumValues' => null, + 'size' => null, + 'precision' => null, + 'scale' => null, + 'defaultValue' => '2002-01-01 00:00:00', + ], + 'bool_col' => [ + 'type' => 'smallint', + 'dbType' => 'tinyint(1)', + 'phpType' => 'integer', + 'allowNull' => false, + 'autoIncrement' => false, + 'enumValues' => null, + 'size' => 1, + 'precision' => 1, + 'scale' => null, + 'defaultValue' => null, + ], + 'bool_col2' => [ + 'type' => 'smallint', + 'dbType' => 'tinyint(1)', + 'phpType' => 'integer', + 'allowNull' => true, + 'autoIncrement' => false, + 'enumValues' => null, + 'size' => 1, + 'precision' => 1, + 'scale' => null, + 'defaultValue' => 1, + ], + 'ts_default' => [ + 'type' => 'timestamp', + 'dbType' => 'timestamp', + 'phpType' => 'string', + 'allowNull' => false, + 'autoIncrement' => false, + 'enumValues' => null, + 'size' => null, + 'precision' => null, + 'scale' => null, + 'defaultValue' => new Expression('CURRENT_TIMESTAMP'), + ], + ]; + } + + public function testColumnSchema() + { + $columns = $this->getExpectedColumns(); + + $table = $this->getConnection(false)->schema->getTableSchema('type', true); + + $expectedColNames = array_keys($columns); + sort($expectedColNames); + $colNames = $table->columnNames; + sort($colNames); + $this->assertEquals($expectedColNames, $colNames); + + foreach($table->columns as $name => $column) { + $expected = $columns[$name]; + $this->assertSame($expected['dbType'], $column->dbType, "dbType of colum $name does not match. type is $column->type, dbType is $column->dbType."); + $this->assertSame($expected['phpType'], $column->phpType, "phpType of colum $name does not match. type is $column->type, dbType is $column->dbType."); + $this->assertSame($expected['type'], $column->type, "type of colum $name does not match."); + $this->assertSame($expected['allowNull'], $column->allowNull, "allowNull of colum $name does not match."); + $this->assertSame($expected['autoIncrement'], $column->autoIncrement, "autoIncrement of colum $name does not match."); + $this->assertSame($expected['enumValues'], $column->enumValues, "enumValues of colum $name does not match."); + $this->assertSame($expected['size'], $column->size, "size of colum $name does not match."); + $this->assertSame($expected['precision'], $column->precision, "precision of colum $name does not match."); + $this->assertSame($expected['scale'], $column->scale, "scale of colum $name does not match."); + if (is_object($expected['defaultValue'])) { + $this->assertTrue(is_object($column->defaultValue), "defaultValue of colum $name is expected to be an object but it is not."); + $this->assertEquals((string) $expected['defaultValue'], (string) $column->defaultValue, "defaultValue of colum $name does not match."); + } else { + $this->assertSame($expected['defaultValue'], $column->defaultValue, "defaultValue of colum $name does not match."); + } + } + } } diff --git a/tests/unit/framework/db/cubrid/CubridSchemaTest.php b/tests/unit/framework/db/cubrid/CubridSchemaTest.php index 4f85220..003b405 100644 --- a/tests/unit/framework/db/cubrid/CubridSchemaTest.php +++ b/tests/unit/framework/db/cubrid/CubridSchemaTest.php @@ -1,6 +1,7 @@ <?php namespace yiiunit\framework\db\cubrid; +use yii\db\Expression; use yiiunit\framework\db\SchemaTest; /** @@ -33,4 +34,37 @@ class CubridSchemaTest extends SchemaTest } fclose($fp); } + + + public function getExpectedColumns() + { + $columns = parent::getExpectedColumns(); + $columns['int_col']['dbType'] = 'integer'; + $columns['int_col']['size'] = null; + $columns['int_col']['precision'] = null; + $columns['int_col2']['dbType'] = 'integer'; + $columns['int_col2']['size'] = null; + $columns['int_col2']['precision'] = null; + $columns['char_col3']['type'] = 'string'; + $columns['char_col3']['dbType'] = 'varchar(1073741823)'; + $columns['char_col3']['size'] = 1073741823; + $columns['char_col3']['precision'] = 1073741823; + $columns['enum_col']['dbType'] = "enum('a', 'B')"; + $columns['float_col']['dbType'] = 'double'; + $columns['float_col']['size'] = null; + $columns['float_col']['precision'] = null; + $columns['float_col']['scale'] = null; + $columns['numeric_col']['dbType'] = 'numeric(5,2)'; + $columns['blob_col']['phpType'] = 'resource'; + $columns['blob_col']['type'] = 'binary'; + $columns['bool_col']['dbType'] = 'short'; + $columns['bool_col']['size'] = null; + $columns['bool_col']['precision'] = null; + $columns['bool_col2']['dbType'] = 'short'; + $columns['bool_col2']['size'] = null; + $columns['bool_col2']['precision'] = null; + $columns['time']['defaultValue'] = '12:00:00 AM 01/01/2002'; + $columns['ts_default']['defaultValue'] = new Expression('SYS_TIMESTAMP'); + return $columns; + } } diff --git a/tests/unit/framework/db/pgsql/PostgreSQLConnectionTest.php b/tests/unit/framework/db/pgsql/PostgreSQLConnectionTest.php index 283edfd..c569a44 100644 --- a/tests/unit/framework/db/pgsql/PostgreSQLConnectionTest.php +++ b/tests/unit/framework/db/pgsql/PostgreSQLConnectionTest.php @@ -50,28 +50,28 @@ class PostgreSQLConnectionTest extends ConnectionTest $this->assertEquals('(column)', $connection->quoteColumnName('(column)')); } - public function testTransactionIsolation() - { - $connection = $this->getConnection(true); + public function testTransactionIsolation() + { + $connection = $this->getConnection(true); - $transaction = $connection->beginTransaction(); - $transaction->setIsolationLevel(Transaction::READ_UNCOMMITTED); - $transaction->commit(); + $transaction = $connection->beginTransaction(); + $transaction->setIsolationLevel(Transaction::READ_UNCOMMITTED); + $transaction->commit(); - $transaction = $connection->beginTransaction(); - $transaction->setIsolationLevel(Transaction::READ_COMMITTED); - $transaction->commit(); + $transaction = $connection->beginTransaction(); + $transaction->setIsolationLevel(Transaction::READ_COMMITTED); + $transaction->commit(); - $transaction = $connection->beginTransaction(); - $transaction->setIsolationLevel(Transaction::REPEATABLE_READ); - $transaction->commit(); + $transaction = $connection->beginTransaction(); + $transaction->setIsolationLevel(Transaction::REPEATABLE_READ); + $transaction->commit(); - $transaction = $connection->beginTransaction(); - $transaction->setIsolationLevel(Transaction::SERIALIZABLE); - $transaction->commit(); + $transaction = $connection->beginTransaction(); + $transaction->setIsolationLevel(Transaction::SERIALIZABLE); + $transaction->commit(); - $transaction = $connection->beginTransaction(); - $transaction->setIsolationLevel(Transaction::SERIALIZABLE . ' READ ONLY DEFERRABLE'); - $transaction->commit(); - } + $transaction = $connection->beginTransaction(); + $transaction->setIsolationLevel(Transaction::SERIALIZABLE . ' READ ONLY DEFERRABLE'); + $transaction->commit(); + } } diff --git a/tests/unit/framework/db/pgsql/PostgreSQLQueryTest.php b/tests/unit/framework/db/pgsql/PostgreSQLQueryTest.php new file mode 100644 index 0000000..fbb8449 --- /dev/null +++ b/tests/unit/framework/db/pgsql/PostgreSQLQueryTest.php @@ -0,0 +1,16 @@ +<?php + +namespace yiiunit\framework\db\pgsql; + +use yii\db\pgsql\Schema; +use yiiunit\framework\db\QueryTest; +use yiiunit\framework\db\SchemaTest; + +/** + * @group db + * @group pgsql + */ +class PostgreSQLQueryTest extends QueryTest +{ + public $driverName = 'pgsql'; +} diff --git a/tests/unit/framework/db/pgsql/PostgreSQLSchemaTest.php b/tests/unit/framework/db/pgsql/PostgreSQLSchemaTest.php new file mode 100644 index 0000000..98b7c2b --- /dev/null +++ b/tests/unit/framework/db/pgsql/PostgreSQLSchemaTest.php @@ -0,0 +1,33 @@ +<?php + +namespace yiiunit\framework\db\pgsql; + +use yii\db\pgsql\Schema; +use yiiunit\framework\db\SchemaTest; + +/** + * @group db + * @group pgsql + */ +class PostgreSQLSchemaTest extends SchemaTest +{ + public $driverName = 'pgsql'; + + public function getExpectedColumns() + { + $columns = parent::getExpectedColumns(); + unset($columns['enum_col']); + $columns['int_col']['dbType'] = 'integer'; + $columns['int_col']['size'] = null; + $columns['int_col']['precision'] = null; + $columns['int_col2']['dbType'] = 'integer'; + $columns['int_col2']['size'] = null; + $columns['int_col2']['precision'] = null; + $columns['bool_col']['type'] = 'boolean'; + $columns['bool_col']['phpType'] = 'boolean'; + $columns['bool_col2']['type'] = 'boolean'; + $columns['bool_col2']['phpType'] = 'boolean'; + $columns['bool_col2']['defaultValue'] = true; + return $columns; + } +} diff --git a/tests/unit/framework/db/sqlite/SqliteConnectionTest.php b/tests/unit/framework/db/sqlite/SqliteConnectionTest.php index 3806712..9bc1e49 100644 --- a/tests/unit/framework/db/sqlite/SqliteConnectionTest.php +++ b/tests/unit/framework/db/sqlite/SqliteConnectionTest.php @@ -47,14 +47,14 @@ class SqliteConnectionTest extends ConnectionTest $this->assertEquals('(column)', $connection->quoteColumnName('(column)')); } - public function testTransactionIsolation() - { - $connection = $this->getConnection(true); + public function testTransactionIsolation() + { + $connection = $this->getConnection(true); - $transaction = $connection->beginTransaction(Transaction::READ_UNCOMMITTED); - $transaction->rollBack(); + $transaction = $connection->beginTransaction(Transaction::READ_UNCOMMITTED); + $transaction->rollBack(); - $transaction = $connection->beginTransaction(Transaction::SERIALIZABLE); - $transaction->rollBack(); - } + $transaction = $connection->beginTransaction(Transaction::SERIALIZABLE); + $transaction->rollBack(); + } } diff --git a/tests/unit/framework/db/sqlite/SqliteSchemaTest.php b/tests/unit/framework/db/sqlite/SqliteSchemaTest.php index 1cb6c6d..7862049 100644 --- a/tests/unit/framework/db/sqlite/SqliteSchemaTest.php +++ b/tests/unit/framework/db/sqlite/SqliteSchemaTest.php @@ -10,4 +10,23 @@ use yiiunit\framework\db\SchemaTest; class SqliteSchemaTest extends SchemaTest { protected $driverName = 'sqlite'; + + public function getExpectedColumns() + { + $columns = parent::getExpectedColumns(); + unset($columns['enum_col']); + $columns['int_col']['dbType'] = 'integer'; + $columns['int_col']['size'] = null; + $columns['int_col']['precision'] = null; + $columns['int_col2']['dbType'] = 'integer'; + $columns['int_col2']['size'] = null; + $columns['int_col2']['precision'] = null; + $columns['bool_col']['type'] = 'boolean'; + $columns['bool_col']['phpType'] = 'boolean'; + $columns['bool_col2']['type'] = 'boolean'; + $columns['bool_col2']['phpType'] = 'boolean'; + $columns['bool_col2']['defaultValue'] = true; + return $columns; + } + } -- libgit2 0.27.1