From 98bdf619e35e869858e8eb72bacc28bbcbbfdee3 Mon Sep 17 00:00:00 2001 From: "John Paul E. Balandan, CPA" Date: Tue, 24 Feb 2026 17:31:14 +0800 Subject: [PATCH] test: turn `MySQLi` `$strictOn` to `true` by default --- app/Config/Database.php | 2 +- tests/_support/Config/Registrar.php | 10 +- .../_support/Database/Seeds/CITestSeeder.php | 36 ++-- tests/system/Database/Live/ForgeTest.php | 4 + tests/system/Database/Live/InsertTest.php | 33 +--- .../Database/Live/MySQLi/RawSqlTest.php | 162 ++++++++++-------- .../system/Database/Live/TransactionTest.php | 33 +--- 7 files changed, 133 insertions(+), 147 deletions(-) diff --git a/app/Config/Database.php b/app/Config/Database.php index d7939bc26f9e..29df3641adf7 100644 --- a/app/Config/Database.php +++ b/app/Config/Database.php @@ -177,7 +177,7 @@ class Database extends Config 'swapPre' => '', 'encrypt' => false, 'compress' => false, - 'strictOn' => false, + 'strictOn' => true, 'failover' => [], 'port' => 3306, 'foreignKeys' => true, diff --git a/tests/_support/Config/Registrar.php b/tests/_support/Config/Registrar.php index 8759dcb5a1a2..d69d5c83e463 100644 --- a/tests/_support/Config/Registrar.php +++ b/tests/_support/Config/Registrar.php @@ -41,7 +41,7 @@ class Registrar 'swapPre' => '', 'encrypt' => false, 'compress' => false, - 'strictOn' => false, + 'strictOn' => true, 'failover' => [], 'port' => 3306, ], @@ -60,7 +60,7 @@ class Registrar 'swapPre' => '', 'encrypt' => false, 'compress' => false, - 'strictOn' => false, + 'strictOn' => true, // @todo 4.7.0 to remove in v4.8.0 'failover' => [], 'port' => 5432, ], @@ -79,7 +79,7 @@ class Registrar 'swapPre' => '', 'encrypt' => false, 'compress' => false, - 'strictOn' => false, + 'strictOn' => true, // @todo 4.7.0 to remove in v4.8.0 'failover' => [], 'port' => 3306, 'foreignKeys' => true, @@ -100,7 +100,7 @@ class Registrar 'swapPre' => '', 'encrypt' => false, 'compress' => false, - 'strictOn' => false, + 'strictOn' => true, // @todo 4.7.0 to remove in v4.8.0 'failover' => [], 'port' => 1433, ], @@ -119,7 +119,7 @@ class Registrar 'swapPre' => '', 'encrypt' => false, 'compress' => false, - 'strictOn' => false, + 'strictOn' => true, // @todo 4.7.0 to remove in v4.8.0 'failover' => [], ], ]; diff --git a/tests/_support/Database/Seeds/CITestSeeder.php b/tests/_support/Database/Seeds/CITestSeeder.php index 09dba65f155b..a34a5b304f03 100644 --- a/tests/_support/Database/Seeds/CITestSeeder.php +++ b/tests/_support/Database/Seeds/CITestSeeder.php @@ -19,7 +19,6 @@ class CITestSeeder extends Seeder { public function run(): void { - // Job Data $data = [ 'user' => [ [ @@ -147,7 +146,8 @@ public function run(): void ], ]; - // set SQL times to more correct format + // Normalize formats and remove unsupported types for each database driver + if ($this->db->DBDriver === 'SQLite3') { $data['type_test'][0]['type_date'] = '2020/01/11'; $data['type_test'][0]['type_time'] = '15:22:00'; @@ -157,7 +157,15 @@ public function run(): void if ($this->db->DBDriver === 'Postgre') { $data['type_test'][0]['type_time'] = '15:22:00'; - $data['type_test'][0]['type_boolean'] = true; + $data['type_test'][0]['type_boolean'] = true; // PostgreSQL has native boolean type + + $data['ci_sessions'][] = [ + 'id' => 'ci_session:1f5o06b43phsnnf8if6bo33b635e4p2o', + 'ip_address' => '127.0.0.1', + 'timestamp' => '2021-06-25 21:54:14.991403+02', + 'data' => '\x' . bin2hex('__ci_last_regenerate|i:1624650854;_ci_previous_url|s:40:\"http://localhost/index.php/home/index\";'), + ]; + unset( $data['type_test'][0]['type_enum'], $data['type_test'][0]['type_set'], @@ -185,6 +193,11 @@ public function run(): void } if ($this->db->DBDriver === 'MySQLi') { + $data['type_test'][0]['type_time'] = '15:22:00'; + $data['type_test'][0]['type_date'] = '2020-01-11'; + $data['type_test'][0]['type_datetime'] = '2020-06-18 05:12:24'; + $data['type_test'][0]['type_timestamp'] = '2019-07-18 21:53:21'; + $data['ci_sessions'][] = [ 'id' => 'ci_session:1f5o06b43phsnnf8if6bo33b635e4p2o', 'ip_address' => '127.0.0.1', @@ -193,29 +206,22 @@ public function run(): void ]; } - if ($this->db->DBDriver === 'Postgre') { - $data['ci_sessions'][] = [ - 'id' => 'ci_session:1f5o06b43phsnnf8if6bo33b635e4p2o', - 'ip_address' => '127.0.0.1', - 'timestamp' => '2021-06-25 21:54:14.991403+02', - 'data' => '\x' . bin2hex('__ci_last_regenerate|i:1624650854;_ci_previous_url|s:40:\"http://localhost/index.php/home/index\";'), - ]; - } - if ($this->db->DBDriver === 'OCI8') { $this->db->query('alter session set NLS_DATE_FORMAT=?', ['YYYY-MM-DD HH24:MI:SS']); + $data['type_test'][0]['type_date'] = '2020-01-11 22:11:00'; $data['type_test'][0]['type_time'] = '2020-07-18 15:22:00'; $data['type_test'][0]['type_datetime'] = '2020-06-18 05:12:24'; $data['type_test'][0]['type_timestamp'] = '2020-06-18 21:53:21'; + unset($data['type_test'][0]['type_blob']); } - foreach ($data as $table => $dummyData) { + foreach ($data as $table => $seeds) { $this->db->table($table)->truncate(); - foreach ($dummyData as $singleDummyData) { - $this->db->table($table)->insert($singleDummyData); + foreach ($seeds as $seed) { + $this->db->table($table)->insert($seed); } } } diff --git a/tests/system/Database/Live/ForgeTest.php b/tests/system/Database/Live/ForgeTest.php index 9faf9d79afb7..39433abde857 100644 --- a/tests/system/Database/Live/ForgeTest.php +++ b/tests/system/Database/Live/ForgeTest.php @@ -1621,6 +1621,10 @@ public function testAddTextColumnWithConstraint(): void $this->forge->addColumn('user', [ 'text_with_constraint' => ['type' => 'nvarchar(max)', 'default' => ''], ]); + } elseif (in_array($this->db->DBDriver, ['MySQLi', 'Postgre', 'SQLite3'], true)) { + $this->forge->addColumn('user', [ + 'text_with_constraint' => ['type' => 'text'], + ]); } else { $this->forge->addColumn('user', [ 'text_with_constraint' => ['type' => 'text', 'constraint' => 255, 'default' => ''], diff --git a/tests/system/Database/Live/InsertTest.php b/tests/system/Database/Live/InsertTest.php index 79281a384e9a..1483d660c174 100644 --- a/tests/system/Database/Live/InsertTest.php +++ b/tests/system/Database/Live/InsertTest.php @@ -30,13 +30,8 @@ final class InsertTest extends CIUnitTestCase { use DatabaseTestTrait; - /** - * @var Forge - */ - public $forge; - - protected $refresh = true; - protected $seed = CITestSeeder::class; + protected $seed = CITestSeeder::class; + private Forge $forge; public function testInsert(): void { @@ -93,26 +88,10 @@ public function testInsertBatchFailed(): void { $this->expectException(DatabaseException::class); - $data = [ - [ - 'name' => 'Grocery Sales', - ], - [ - 'name' => null, - ], - ]; - - $db = $this->db; - - if ($this->db->DBDriver === 'MySQLi') { - // strict mode is required for MySQLi to throw an exception here - $config = config('Database'); - $config->tests['strictOn'] = true; - - $db = Database::connect($config->tests); - } - - $db->table('job')->insertBatch($data); + $this->db->table('job')->insertBatch([ + ['name' => 'Grocery Sales'], + ['name' => null], + ]); } public function testReplaceWithNoMatchingData(): void diff --git a/tests/system/Database/Live/MySQLi/RawSqlTest.php b/tests/system/Database/Live/MySQLi/RawSqlTest.php index 03c694d0ab47..b14f8d4d400d 100644 --- a/tests/system/Database/Live/MySQLi/RawSqlTest.php +++ b/tests/system/Database/Live/MySQLi/RawSqlTest.php @@ -28,8 +28,7 @@ final class RawSqlTest extends CIUnitTestCase { use DatabaseTestTrait; - protected $refresh = true; - protected $seed = CITestSeeder::class; + protected $seed = CITestSeeder::class; protected function setUp(): void { @@ -37,50 +36,49 @@ protected function setUp(): void if ($this->db->DBDriver !== 'MySQLi') { $this->markTestSkipped('Only MySQLi has its own implementation.'); - } else { - $this->addSqlFunction(); } + + $this->addSqlFunction(); } - protected function addSqlFunction(): void + private function addSqlFunction(): void { $this->db->query('DROP FUNCTION IF EXISTS setDateTime'); - - $sql = "CREATE FUNCTION setDateTime ( setDate varchar(20) ) - RETURNS DATETIME - READS SQL DATA - DETERMINISTIC - BEGIN - RETURN CONVERT(CONCAT(setDate,' ','01:01:11'), DATETIME); - END;"; - - $this->db->query($sql); + $this->db->query(<<<'SQL_WRAP' + CREATE FUNCTION setDateTime ( setDate varchar(20) ) + RETURNS DATETIME + READS SQL DATA + DETERMINISTIC + BEGIN + RETURN CONVERT(CONCAT(setDate,' ','01:01:11'), DATETIME); + END; + SQL_WRAP); } public function testRawSqlUpdateObject(): void { - $data = []; - - $row = new stdClass(); - $row->email = 'derek@world.com'; - $row->created_at = new RawSql("setDateTime('2022-01-01')"); - $data[] = $row; - - $row = new stdClass(); - $row->email = 'ahmadinejad@world.com'; - $row->created_at = new RawSql("setDateTime('2022-01-01')"); - $data[] = $row; - - $this->db->table('user')->updateBatch($data, 'email'); - - $row->created_at = new RawSql("setDateTime('2022-01-11')"); - - $this->db->table('user')->update($row, "email = 'ahmadinejad@world.com'"); + $this->db->table('user')->updateBatch([ + (object) [ + 'email' => 'derek@world.com', + 'created_at' => new RawSql("setDateTime('2022-01-01')"), + ], + (object) [ + 'email' => 'ahmadinejad@world.com', + 'created_at' => new RawSql("setDateTime('2022-01-01')"), + ], + ], 'email'); + $this->db->table('user')->update( + (object) ['created_at' => new RawSql("setDateTime('2022-01-11')")], + "email = 'ahmadinejad@world.com'", + ); $this->seeInDatabase('user', ['email' => 'derek@world.com', 'created_at' => '2022-01-01 01:01:11']); $this->seeInDatabase('user', ['email' => 'ahmadinejad@world.com', 'created_at' => '2022-01-11 01:01:11']); } + /** + * @deprecated This test covers the deprecated setUpdateBatch() method. + */ public function testRawSqlSetUpdateObject(): void { $data = []; @@ -107,99 +105,115 @@ public function testRawSqlSetUpdateObject(): void public function testRawSqlUpdateArray(): void { - $data = [ + $this->db->table('user')->updateBatch([ ['email' => 'derek@world.com', 'created_at' => new RawSql("setDateTime('2022-03-01')")], ['email' => 'ahmadinejad@world.com', 'created_at' => new RawSql("setDateTime('2022-03-01')")], - ]; - - $this->db->table('user')->updateBatch($data, 'email'); - + ], 'email'); $this->seeInDatabase('user', ['email' => 'derek@world.com', 'created_at' => '2022-03-01 01:01:11']); $this->seeInDatabase('user', ['email' => 'ahmadinejad@world.com', 'created_at' => '2022-03-01 01:01:11']); - $data = ['email' => 'ahmadinejad@world.com', 'created_at' => new RawSql("setDateTime('2022-03-11')")]; - - $this->db->table('user')->update($data, "email = 'ahmadinejad@world.com'"); - + $this->db->table('user')->update( + ['email' => 'ahmadinejad@world.com', 'created_at' => new RawSql("setDateTime('2022-03-11')")], + "email = 'ahmadinejad@world.com'", + ); $this->seeInDatabase('user', ['email' => 'ahmadinejad@world.com', 'created_at' => '2022-03-11 01:01:11']); } public function testRawSqlInsertArray(): void { - $data = [ - ['email' => 'pedro@world.com', 'created_at' => new RawSql("setDateTime('2022-04-01')")], - ['email' => 'todd@world.com', 'created_at' => new RawSql("setDateTime('2022-04-01')")], - ]; - - $this->db->table('user')->insertBatch($data); - + $this->db->table('user')->insertBatch([ + [ + 'name' => 'Pedro Pascal', + 'email' => 'pedro@world.com', + 'country' => 'Chile', + 'created_at' => new RawSql("setDateTime('2022-04-01')"), + ], + [ + 'name' => 'Todd Howard', + 'email' => 'todd@world.com', + 'country' => 'US', + 'created_at' => new RawSql("setDateTime('2022-04-01')"), + ], + ]); $this->seeInDatabase('user', ['email' => 'pedro@world.com', 'created_at' => '2022-04-01 01:01:11']); $this->seeInDatabase('user', ['email' => 'todd@world.com', 'created_at' => '2022-04-01 01:01:11']); - $data = ['email' => 'jason@world.com', 'created_at' => new RawSql("setDateTime('2022-04-11')")]; - - $this->db->table('user')->insert($data); - + $this->db->table('user')->insert([ + 'name' => 'Jason Momoa', + 'email' => 'jason@world.com', + 'country' => 'US', + 'created_at' => new RawSql("setDateTime('2022-04-11')"), + ]); $this->seeInDatabase('user', ['email' => 'jason@world.com', 'created_at' => '2022-04-11 01:01:11']); } public function testRawSqlInsertObject(): void { - $data = []; - - $row = new stdClass(); - $row->email = 'tony@world.com'; - $row->created_at = new RawSql("setDateTime('2022-05-01')"); - $data[] = $row; - - $row = new stdClass(); - $row->email = 'sara@world.com'; - $row->created_at = new RawSql("setDateTime('2022-05-01')"); - $data[] = $row; - - $this->db->table('user')->insertBatch($data); - - $row->email = 'jessica@world.com'; - $row->created_at = new RawSql("setDateTime('2022-05-11')"); - - $this->db->table('user')->insert($row); + $this->db->table('user')->insertBatch([ + (object) [ + 'name' => 'Tony Stark', + 'email' => 'tony@world.com', + 'country' => 'US', + 'created_at' => new RawSql("setDateTime('2022-05-01')"), + ], + (object) [ + 'name' => 'Sara Connor', + 'email' => 'sara@world.com', + 'country' => 'US', + 'created_at' => new RawSql("setDateTime('2022-05-01')"), + ], + ]); + $this->db->table('user')->insert((object) [ + 'name' => 'Jessica Jones', + 'email' => 'jessica@world.com', + 'country' => 'US', + 'created_at' => new RawSql("setDateTime('2022-05-11')"), + ]); $this->seeInDatabase('user', ['email' => 'tony@world.com', 'created_at' => '2022-05-01 01:01:11']); $this->seeInDatabase('user', ['email' => 'sara@world.com', 'created_at' => '2022-05-01 01:01:11']); $this->seeInDatabase('user', ['email' => 'jessica@world.com', 'created_at' => '2022-05-11 01:01:11']); } + /** + * @deprecated This test covers the deprecated setInsertBatch() method. + */ public function testRawSqlSetInsertObject(): void { $data = []; $row = new stdClass(); + $row->name = 'Laura Palmer'; $row->email = 'laura@world.com'; + $row->country = 'US'; $row->created_at = new RawSql("setDateTime('2022-06-01')"); $data[] = $row; $row = new stdClass(); + $row->name = 'Travis Touchdown'; $row->email = 'travis@world.com'; + $row->country = 'US'; $row->created_at = new RawSql("setDateTime('2022-06-01')"); $data[] = $row; $this->db->table('user')->setInsertBatch($data)->insertBatch(); - $this->seeInDatabase('user', ['email' => 'laura@world.com', 'created_at' => '2022-06-01 01:01:11']); $this->seeInDatabase('user', ['email' => 'travis@world.com', 'created_at' => '2022-06-01 01:01:11']); + $row = new stdClass(); + $row->name = 'Steve Rogers'; $row->email = 'steve@world.com'; + $row->country = 'US'; $row->created_at = new RawSql("setDateTime('2022-06-11')"); - $this->db->table('user')->set($row)->insert(); - $this->seeInDatabase('user', ['email' => 'steve@world.com', 'created_at' => '2022-06-11 01:01:11']); $this->db->table('user') + ->set('name', 'Dan Brown') ->set('email', 'dan@world.com') + ->set('country', 'US') ->set('created_at', new RawSql("setDateTime('2022-06-13')")) ->insert(); - $this->seeInDatabase('user', ['email' => 'dan@world.com', 'created_at' => '2022-06-13 01:01:11']); } } diff --git a/tests/system/Database/Live/TransactionTest.php b/tests/system/Database/Live/TransactionTest.php index 74df4e3fd974..d36cbf35d677 100644 --- a/tests/system/Database/Live/TransactionTest.php +++ b/tests/system/Database/Live/TransactionTest.php @@ -245,33 +245,16 @@ public function testTransStrictFalseAndDBDebugFalse(): void */ public function testTransInsertBatchFailed(): void { - $data = [ - [ - 'name' => 'Grocery Sales', - ], - [ - 'name' => null, - ], - ]; - - $db = $this->db; - - if ($this->db->DBDriver === 'MySQLi') { - // strict mode is required for MySQLi to throw an exception here - $config = config('Database'); - $config->tests['strictOn'] = true; - - $db = Database::connect($config->tests); - } + $this->db->transStrict(false)->transBegin(); + $this->db->table('job')->insertBatch([ + ['name' => 'Grocery Sales'], + ['name' => null], + ]); - $db->transStrict(false)->transBegin(); - $db->table('job')->insertBatch($data); - - $this->assertFalse($db->transStatus()); - - $db->transComplete(); + $this->assertFalse($this->db->transStatus()); - $db->transStrict(); + $this->db->transComplete(); + $this->db->transStrict(); $this->dontSeeInDatabase('job', ['name' => 'Grocery Sales']); }