diff --git a/system/Database/BaseBuilder.php b/system/Database/BaseBuilder.php index ca64800463a2..51ed022d131d 100644 --- a/system/Database/BaseBuilder.php +++ b/system/Database/BaseBuilder.php @@ -2198,7 +2198,7 @@ protected function formatValues(array $values): array * * @param array|object|null $set a dataset * - * @return false|int|list Number of rows inserted or FALSE on failure, SQL array when testMode + * @return false|int|list Number of rows inserted or FALSE on no data to perform an insert operation, SQL array when testMode */ public function insertBatch($set = null, ?bool $escape = null, int $batchSize = 100) { diff --git a/system/Database/Postgre/Connection.php b/system/Database/Postgre/Connection.php index ad278145afef..64b85eafb064 100644 --- a/system/Database/Postgre/Connection.php +++ b/system/Database/Postgre/Connection.php @@ -227,6 +227,10 @@ protected function getDriverFunctionPrefix(): string */ public function affectedRows(): int { + if ($this->resultID === false) { + return 0; + } + return pg_affected_rows($this->resultID); } diff --git a/system/Database/SQLSRV/Connection.php b/system/Database/SQLSRV/Connection.php index 6903f42eebac..26b4983dba0a 100644 --- a/system/Database/SQLSRV/Connection.php +++ b/system/Database/SQLSRV/Connection.php @@ -444,6 +444,10 @@ public function error(): array */ public function affectedRows(): int { + if ($this->resultID === false) { + return 0; + } + return sqlsrv_rows_affected($this->resultID); } diff --git a/tests/system/Database/Live/InsertTest.php b/tests/system/Database/Live/InsertTest.php index ca2117a06b35..01cc74e9c26b 100644 --- a/tests/system/Database/Live/InsertTest.php +++ b/tests/system/Database/Live/InsertTest.php @@ -13,6 +13,7 @@ namespace CodeIgniter\Database\Live; +use CodeIgniter\Database\Exceptions\DatabaseException; use CodeIgniter\Database\Forge; use CodeIgniter\Database\RawSql; use CodeIgniter\Test\CIUnitTestCase; @@ -79,13 +80,31 @@ public function testInsertBatch(): void ], ]; - $this->db->table($table)->insertBatch($data); + $count = $this->db->table($table)->insertBatch($data); + + $this->assertSame(2, $count); $expected = $data; $this->seeInDatabase($table, $expected[0]); $this->seeInDatabase($table, $expected[1]); } + public function testInsertBatchFailed(): void + { + $this->expectException(DatabaseException::class); + + $data = [ + [ + 'name' => 'Grocery Sales', + ], + [ + 'name' => null, + ], + ]; + + $this->db->table('job')->insertBatch($data); + } + public function testReplaceWithNoMatchingData(): void { $data = [ diff --git a/tests/system/Database/Live/TransactionTest.php b/tests/system/Database/Live/TransactionTest.php index 3414d2dfffdf..d3915c2217c8 100644 --- a/tests/system/Database/Live/TransactionTest.php +++ b/tests/system/Database/Live/TransactionTest.php @@ -239,4 +239,28 @@ public function testTransStrictFalseAndDBDebugFalse(): void $this->enableDBDebug(); } + + /** + * @see https://github.com/codeigniter4/CodeIgniter4/issues/9362 + */ + public function testTransInsertBatchFailed(): void + { + $data = [ + [ + 'name' => 'Grocery Sales', + ], + [ + 'name' => null, + ], + ]; + + $this->db->transBegin(); + $this->db->table('job')->insertBatch($data); + + $this->assertFalse($this->db->transStatus()); + + $this->db->transRollback(); + + $this->dontSeeInDatabase('job', ['name' => 'Grocery Sales']); + } } diff --git a/user_guide_src/source/changelogs/v4.5.8.rst b/user_guide_src/source/changelogs/v4.5.8.rst index cad7fec30248..ae29b59fb165 100644 --- a/user_guide_src/source/changelogs/v4.5.8.rst +++ b/user_guide_src/source/changelogs/v4.5.8.rst @@ -30,6 +30,8 @@ Deprecations Bugs Fixed ********** +- **Database:** Fixed a bug where ``Builder::affectedRows()`` threw an error when the previous query call failed in ``Postgre`` and ``SQLSRV`` drivers. + See the repo's `CHANGELOG.md `_ for a complete list of bugs fixed.