mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-10-31 02:28:35 +08:00 
			
		
		
		
	Fix tests addCheck(), dropCheck() MariaDB. (#20174)
				
					
				
			This commit is contained in:
		| @ -205,8 +205,10 @@ SQL; | ||||
|      */ | ||||
|     protected function loadTableChecks($tableName) | ||||
|     { | ||||
|         $version = $this->db->getServerVersion(); | ||||
|  | ||||
|         // check version MySQL >= 8.0.16 | ||||
|         if (version_compare($this->db->getSlavePdo()->getAttribute(\PDO::ATTR_SERVER_VERSION), '8.0.16', '<')) { | ||||
|         if (\stripos($version, 'MariaDb') === false && \version_compare($version, '8.0.16', '<')) { | ||||
|             throw new NotSupportedException('MySQL < 8.0.16 does not support check constraints.'); | ||||
|         } | ||||
|  | ||||
| @ -230,17 +232,9 @@ SQL; | ||||
|         $tableRows = $this->normalizePdoRowKeyCase($tableRows, true); | ||||
|  | ||||
|         foreach ($tableRows as $tableRow) { | ||||
|             $matches = []; | ||||
|             $columnName = null; | ||||
|  | ||||
|             if (preg_match('/\(`?([a-zA-Z0-9_]+)`?\s*[><=]/', $tableRow['check_clause'], $matches)) { | ||||
|                 $columnName = $matches[1]; | ||||
|             } | ||||
|  | ||||
|             $check = new CheckConstraint( | ||||
|                 [ | ||||
|                     'name' => $tableRow['constraint_name'], | ||||
|                     'columnNames' => [$columnName], | ||||
|                     'expression' => $tableRow['check_clause'], | ||||
|                 ] | ||||
|             ); | ||||
|  | ||||
| @ -773,14 +773,6 @@ abstract class SchemaTest extends DatabaseTestCase | ||||
|             $this->expectException('yii\base\NotSupportedException'); | ||||
|         } | ||||
|  | ||||
|         if ( | ||||
|             $this->driverName === 'mysql' && | ||||
|             version_compare($this->getConnection(false)->getServerVersion(), '8.0.16', '<') && | ||||
|             $type === 'checks' | ||||
|         ) { | ||||
|             $this->expectException('yii\base\NotSupportedException'); | ||||
|         } | ||||
|  | ||||
|         $constraints = $this->getConnection(false)->getSchema()->{'getTable' . ucfirst($type)}($tableName); | ||||
|         $this->assertMetadataEquals($expected, $constraints); | ||||
|     } | ||||
| @ -797,14 +789,6 @@ abstract class SchemaTest extends DatabaseTestCase | ||||
|             $this->expectException('yii\base\NotSupportedException'); | ||||
|         } | ||||
|  | ||||
|         if ( | ||||
|             $this->driverName === 'mysql' && | ||||
|             version_compare($this->getConnection(false)->getServerVersion(), '8.0.16', '<') && | ||||
|             $type === 'checks' | ||||
|         ) { | ||||
|             $this->expectException('yii\base\NotSupportedException'); | ||||
|         } | ||||
|  | ||||
|         $connection = $this->getConnection(false); | ||||
|         $connection->getSlavePdo(true)->setAttribute(PDO::ATTR_CASE, PDO::CASE_UPPER); | ||||
|         $constraints = $connection->getSchema()->{'getTable' . ucfirst($type)}($tableName, true); | ||||
| @ -823,21 +807,13 @@ abstract class SchemaTest extends DatabaseTestCase | ||||
|             $this->expectException('yii\base\NotSupportedException'); | ||||
|         } | ||||
|  | ||||
|         if ( | ||||
|             $this->driverName === 'mysql' && | ||||
|             version_compare($this->getConnection(false)->getServerVersion(), '8.0.16', '<') && | ||||
|             $type === 'checks' | ||||
|         ) { | ||||
|             $this->expectException('yii\base\NotSupportedException'); | ||||
|         } | ||||
|  | ||||
|         $connection = $this->getConnection(false); | ||||
|         $connection->getSlavePdo(true)->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER); | ||||
|         $constraints = $connection->getSchema()->{'getTable' . ucfirst($type)}($tableName, true); | ||||
|         $this->assertMetadataEquals($expected, $constraints); | ||||
|     } | ||||
|  | ||||
|     private function assertMetadataEquals($expected, $actual) | ||||
|     protected function assertMetadataEquals($expected, $actual) | ||||
|     { | ||||
|         switch (\strtolower(\gettype($expected))) { | ||||
|             case 'object': | ||||
| @ -865,7 +841,7 @@ abstract class SchemaTest extends DatabaseTestCase | ||||
|         $this->assertEquals($expected, $actual); | ||||
|     } | ||||
|  | ||||
|     private function normalizeArrayKeys(array &$array, $caseSensitive) | ||||
|     protected function normalizeArrayKeys(array &$array, $caseSensitive) | ||||
|     { | ||||
|         $newArray = []; | ||||
|         foreach ($array as $value) { | ||||
| @ -889,7 +865,7 @@ abstract class SchemaTest extends DatabaseTestCase | ||||
|         $array = $newArray; | ||||
|     } | ||||
|  | ||||
|     private function normalizeConstraints(&$expected, &$actual) | ||||
|     protected function normalizeConstraints(&$expected, &$actual) | ||||
|     { | ||||
|         if (\is_array($expected)) { | ||||
|             foreach ($expected as $key => $value) { | ||||
| @ -904,7 +880,7 @@ abstract class SchemaTest extends DatabaseTestCase | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private function normalizeConstraintPair(Constraint $expectedConstraint, Constraint $actualConstraint) | ||||
|     protected function normalizeConstraintPair(Constraint $expectedConstraint, Constraint $actualConstraint) | ||||
|     { | ||||
|         if ($expectedConstraint::className() !== $actualConstraint::className()) { | ||||
|             return; | ||||
|  | ||||
| @ -35,6 +35,7 @@ class CommandTest extends \yiiunit\framework\db\CommandTest | ||||
|             'int1' => 'integer', | ||||
|             'int2' => 'integer', | ||||
|             'int3' => 'integer', | ||||
|             'int4' => 'integer', | ||||
|         ])->execute(); | ||||
|  | ||||
|         $this->assertEmpty($schema->getTableChecks($tableName, true)); | ||||
| @ -43,14 +44,22 @@ class CommandTest extends \yiiunit\framework\db\CommandTest | ||||
|             ['name' => 'check_int1_positive', 'expression' => '[[int1]] > 0', 'expected' => '(`int1` > 0)'], | ||||
|             ['name' => 'check_int2_nonzero', 'expression' => '[[int2]] <> 0', 'expected' => '(`int2` <> 0)'], | ||||
|             ['name' => 'check_int3_less_than_100', 'expression' => '[[int3]] < 100', 'expected' => '(`int3` < 100)'], | ||||
|             ['name' => 'check_int1_less_than_int2', 'expression' => '[[int1]] < [[int2]]', 'expected' => '(`int1` < `int2`)'], | ||||
|         ]; | ||||
|  | ||||
|         if (\stripos($db->getServerVersion(), 'MariaDb') !== false) { | ||||
|             $constraints[0]['expected'] = '`int1` > 0'; | ||||
|             $constraints[1]['expected'] = '`int2` <> 0'; | ||||
|             $constraints[2]['expected'] = '`int3` < 100'; | ||||
|             $constraints[3]['expected'] = '`int1` < `int2`'; | ||||
|         } | ||||
|  | ||||
|         foreach ($constraints as $constraint) { | ||||
|             $db->createCommand()->addCheck($constraint['name'], $tableName, $constraint['expression'])->execute(); | ||||
|         } | ||||
|  | ||||
|         $tableChecks = $schema->getTableChecks($tableName, true); | ||||
|         $this->assertCount(3, $tableChecks); | ||||
|         $this->assertCount(4, $tableChecks); | ||||
|  | ||||
|         foreach ($constraints as $index => $constraint) { | ||||
|             $this->assertSame( | ||||
|  | ||||
| @ -78,8 +78,8 @@ SQL; | ||||
|     { | ||||
|         $result = parent::constraintsProvider(); | ||||
|  | ||||
|         $result['1: check'][2][0]->expression = "(`C_check` <> _utf8mb4\\'\\')"; | ||||
|  | ||||
|         $result['1: check'][2][0]->columnNames = null; | ||||
|         $result['1: check'][2][0]->expression = "`C_check` <> ''"; | ||||
|         $result['2: primary key'][2]->name = null; | ||||
|  | ||||
|         // Work aroung bug in MySQL 5.1 - it creates only this table in lowercase. O_o | ||||
| @ -88,6 +88,115 @@ SQL; | ||||
|         return $result; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @dataProvider constraintsProvider | ||||
|      * @param string $tableName | ||||
|      * @param string $type | ||||
|      * @param mixed $expected | ||||
|      */ | ||||
|     public function testTableSchemaConstraints($tableName, $type, $expected) | ||||
|     { | ||||
|         $version = $this->getConnection(false)->getServerVersion(); | ||||
|  | ||||
|         if ($expected === false) { | ||||
|             $this->expectException('yii\base\NotSupportedException'); | ||||
|         } | ||||
|  | ||||
|         if ( | ||||
|             $this->driverName === 'mysql' && | ||||
|             \stripos($version, 'MariaDb') === false && | ||||
|             version_compare($version, '8.0.16', '<') && | ||||
|             $type === 'checks' | ||||
|         ) { | ||||
|             $this->expectException('yii\base\NotSupportedException'); | ||||
|         } elseif ( | ||||
|             $this->driverName === 'mysql' && | ||||
|             \stripos($version, 'MariaDb') === false && | ||||
|             version_compare($version, '8.0.16', '>=') && | ||||
|             $tableName === 'T_constraints_1' && | ||||
|             $type === 'checks' | ||||
|         ) { | ||||
|             $expected[0]->expression = "(`C_check` <> _utf8mb4\\'\\')"; | ||||
|         } | ||||
|  | ||||
|         $constraints = $this->getConnection(false)->getSchema()->{'getTable' . ucfirst($type)}($tableName); | ||||
|         $this->assertMetadataEquals($expected, $constraints); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @dataProvider uppercaseConstraintsProvider | ||||
|      * @param string $tableName | ||||
|      * @param string $type | ||||
|      * @param mixed $expected | ||||
|      */ | ||||
|     public function testTableSchemaConstraintsWithPdoUppercase($tableName, $type, $expected) | ||||
|     { | ||||
|         $version = $this->getConnection(false)->getServerVersion(); | ||||
|  | ||||
|         if ($expected === false) { | ||||
|             $this->expectException('yii\base\NotSupportedException'); | ||||
|         } | ||||
|  | ||||
|         if ( | ||||
|             $this->driverName === 'mysql' && | ||||
|             \stripos($version, 'MariaDb') === false && | ||||
|             version_compare($version, '8.0.16', '<') && | ||||
|             $type === 'checks' | ||||
|         ) { | ||||
|             $this->expectException('yii\base\NotSupportedException'); | ||||
|         } elseif ( | ||||
|             $this->driverName === 'mysql' && | ||||
|             \stripos($version, 'MariaDb') === false && | ||||
|             version_compare($version, '8.0.16', '>=') && | ||||
|             $tableName === 'T_constraints_1' && | ||||
|             $type === 'checks' | ||||
|         ) { | ||||
|             $expected[0]->expression = "(`C_check` <> _utf8mb4\\'\\')"; | ||||
|         } | ||||
|  | ||||
|         $connection = $this->getConnection(false); | ||||
|         $connection->getSlavePdo(true)->setAttribute(\PDO::ATTR_CASE, \PDO::CASE_UPPER); | ||||
|         $constraints = $connection->getSchema()->{'getTable' . ucfirst($type)}($tableName, true); | ||||
|         $this->assertMetadataEquals($expected, $constraints); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @dataProvider lowercaseConstraintsProvider | ||||
|      * @param string $tableName | ||||
|      * @param string $type | ||||
|      * @param mixed $expected | ||||
|      */ | ||||
|     public function testTableSchemaConstraintsWithPdoLowercase($tableName, $type, $expected) | ||||
|     { | ||||
|         $version = $this->getConnection(false)->getServerVersion(); | ||||
|  | ||||
|         if ($expected === false) { | ||||
|             $this->expectException('yii\base\NotSupportedException'); | ||||
|         } | ||||
|  | ||||
|         if ( | ||||
|             $this->driverName === 'mysql' && | ||||
|             \stripos($version, 'MariaDb') === false && | ||||
|             version_compare($version, '8.0.16', '<') && | ||||
|             $type === 'checks' | ||||
|         ) { | ||||
|             $this->expectException('yii\base\NotSupportedException'); | ||||
|         } elseif ( | ||||
|             $this->driverName === 'mysql' && | ||||
|             \stripos($version, 'MariaDb') === false && | ||||
|             version_compare($version, '8.0.16', '>=') && | ||||
|             $tableName === 'T_constraints_1' && | ||||
|             $type === 'checks' | ||||
|         ) { | ||||
|             $expected[0]->expression = "(`C_check` <> _utf8mb4\\'\\')"; | ||||
|         } | ||||
|  | ||||
|         $connection = $this->getConnection(false); | ||||
|         $connection->getSlavePdo(true)->setAttribute(\PDO::ATTR_CASE, \PDO::CASE_LOWER); | ||||
|         $constraints = $connection->getSchema()->{'getTable' . ucfirst($type)}($tableName, true); | ||||
|         $this->assertMetadataEquals($expected, $constraints); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * When displayed in the INFORMATION_SCHEMA.COLUMNS table, a default CURRENT TIMESTAMP is displayed | ||||
|      * as CURRENT_TIMESTAMP up until MariaDB 10.2.2, and as current_timestamp() from MariaDB 10.2.3. | ||||
|  | ||||
| @ -31,6 +31,9 @@ class DeadLockTest extends \yiiunit\framework\db\mysql\ConnectionTest | ||||
|      */ | ||||
|     public function testDeadlockException() | ||||
|     { | ||||
|         if (\stripos($this->getConnection(false)->getServerVersion(), 'MariaDB') !== false) { | ||||
|             $this->markTestSkipped('MariaDB does not support this test'); | ||||
|         } | ||||
|         if (PHP_VERSION_ID >= 70400 && PHP_VERSION_ID < 70500) { | ||||
|             $this->markTestSkipped('Stable failed in PHP 7.4'); | ||||
|         } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Wilmer Arambula
					Wilmer Arambula