Skip to content

Commit af878a4

Browse files
committed
fix: Casting in insertBatch and updateBatch methods.
1 parent 63e9ebd commit af878a4

File tree

4 files changed

+162
-0
lines changed

4 files changed

+162
-0
lines changed

system/BaseModel.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,19 @@ public function insertBatch(?array $set = null, ?bool $escape = null, int $batch
909909

910910
if (is_array($set)) {
911911
foreach ($set as &$row) {
912+
// If casts are used, convert the data first
913+
if ($this->useCasts()) {
914+
if (is_array($row)) {
915+
$row = $this->converter->toDataSource($row);
916+
} elseif ($row instanceof stdClass) {
917+
$row = (array) $row;
918+
$row = $this->converter->toDataSource($row);
919+
} elseif ($row instanceof Entity) {
920+
$row = $this->converter->extract($row);
921+
} elseif (is_object($row)) {
922+
$row = $this->converter->extract($row);
923+
}
924+
}
912925
// If $row is using a custom class with public or protected
913926
// properties representing the collection elements, we need to grab
914927
// them as an array.
@@ -1051,6 +1064,19 @@ public function updateBatch(?array $set = null, ?string $index = null, int $batc
10511064
{
10521065
if (is_array($set)) {
10531066
foreach ($set as &$row) {
1067+
// If casts are used, convert the data first
1068+
if ($this->useCasts()) {
1069+
if (is_array($row)) {
1070+
$row = $this->converter->toDataSource($row);
1071+
} elseif ($row instanceof stdClass) {
1072+
$row = (array) $row;
1073+
$row = $this->converter->toDataSource($row);
1074+
} elseif ($row instanceof Entity) {
1075+
$row = $this->converter->extract($row);
1076+
} elseif (is_object($row)) {
1077+
$row = $this->converter->extract($row);
1078+
}
1079+
}
10541080
// If $row is using a custom class with public or protected
10551081
// properties representing the collection elements, we need to grab
10561082
// them as an array.

tests/system/Models/InsertModelTest.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use stdClass;
2323
use Tests\Support\Entity\User;
2424
use Tests\Support\Models\JobModel;
25+
use Tests\Support\Models\UserCastsTimestampModel;
2526
use Tests\Support\Models\UserModel;
2627
use Tests\Support\Models\UserObjModel;
2728
use Tests\Support\Models\WithoutAutoIncrementModel;
@@ -376,4 +377,55 @@ public function testInsertWithDefaultValue(): void
376377
$id = $this->model->getInsertID();
377378
$this->assertSame($entity->country, $this->model->find($id)->country);
378379
}
380+
381+
public function testInsertBatchWithCasts(): void
382+
{
383+
$userData = [
384+
[
385+
'name' => 'Smriti',
386+
'email' => [
387+
'personal' => '[email protected]',
388+
'work' => '[email protected]'
389+
],
390+
'country' => 'India',
391+
],
392+
[
393+
'name' => 'Rahul',
394+
'email' => [
395+
'personal' => '[email protected]',
396+
'work' => '[email protected]'
397+
],
398+
'country' => 'India',
399+
]
400+
];
401+
$this->createModel(UserCastsTimestampModel::class);
402+
403+
$numRows = $this->model->insertBatch($userData);
404+
405+
$this->assertSame(2, $numRows);
406+
407+
$rows = $this->model->where('country', 'India')->findAll();
408+
409+
$this->assertNotEmpty($rows);
410+
$this->assertCount(2, $rows);
411+
412+
$smriti = $rows[0];
413+
$rahul = $rows[1];
414+
415+
$this->assertNotNull($smriti);
416+
$this->assertNotNull($rahul);
417+
418+
// Check Smriti
419+
$this->assertSame('Smriti', $smriti['name']);
420+
$this->assertIsArray($smriti['email']);
421+
$this->assertSame('[email protected]', $smriti['email']['personal']);
422+
$this->assertSame('[email protected]', $smriti['email']['work']);
423+
424+
// Check Rahul
425+
$this->assertSame('Rahul', $rahul['name']);
426+
$this->assertIsArray($rahul['email']);
427+
$this->assertSame('[email protected]', $rahul['email']['personal']);
428+
$this->assertSame('[email protected]', $rahul['email']['work']);
429+
}
430+
379431
}

tests/system/Models/UpdateModelTest.php

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
use Tests\Support\Models\EventModel;
2727
use Tests\Support\Models\JobModel;
2828
use Tests\Support\Models\SecondaryModel;
29+
use Tests\Support\Models\UserCastsTimestampModel;
2930
use Tests\Support\Models\UserModel;
3031
use Tests\Support\Models\UserTimestampModel;
3132
use Tests\Support\Models\UUIDPkeyModel;
@@ -602,4 +603,86 @@ public function testUpdateEntityUpdateOnlyChangedFalse(): void
602603
$this->assertTrue($result);
603604
$this->assertNotSame($updateAtBefore, $updateAtAfter);
604605
}
606+
607+
public function testUpdateBatchWithCasts(): void
608+
{
609+
$this->createModel(UserCastsTimestampModel::class);
610+
611+
// Step 1: Insert initial users
612+
$initialData = [
613+
[
614+
'name' => 'Smriti',
615+
'email' => [
616+
'personal' => '[email protected]',
617+
'work' => '[email protected]',
618+
],
619+
'country' => 'India',
620+
],
621+
[
622+
'name' => 'Rahul',
623+
'email' => [
624+
'personal' => '[email protected]',
625+
'work' => '[email protected]',
626+
],
627+
'country' => 'India',
628+
],
629+
];
630+
631+
$this->model->insertBatch($initialData);
632+
633+
$rows = $this->model->where('country', 'India')->findAll();
634+
635+
$this->assertNotEmpty($rows);
636+
$this->assertCount(2, $rows);
637+
638+
$smriti = $rows[0];
639+
$rahul = $rows[1];
640+
641+
$this->assertNotNull($smriti);
642+
$this->assertNotNull($rahul);
643+
644+
// Step 3: Prepare update data (must include 'id' key)
645+
$updateData = [
646+
[
647+
'id' => $smriti['id'],
648+
'name' => 'Smriti Updated',
649+
'email' => [
650+
'personal' => '[email protected]',
651+
'work' => '[email protected]',
652+
],
653+
],
654+
[
655+
'id' => $rahul['id'],
656+
'name' => 'Rahul Updated',
657+
'email' => [
658+
'personal' => '[email protected]',
659+
'work' => '[email protected]',
660+
],
661+
],
662+
];
663+
664+
// Step 4: Perform batch update
665+
$numRows = $this->model->updateBatch($updateData, 'id');
666+
$this->assertSame(2, $numRows);
667+
668+
$rows = $this->model->where('country', 'India')->findAll();
669+
670+
$this->assertNotEmpty($rows);
671+
$this->assertCount(2, $rows);
672+
673+
$smritiUpdated = $rows[0];
674+
$rahulUpdated = $rows[1];
675+
676+
// Smriti assertions
677+
$this->assertSame('Smriti Updated', $smritiUpdated['name']);
678+
$this->assertIsArray($smritiUpdated['email']);
679+
$this->assertSame('[email protected]', $smritiUpdated['email']['personal']);
680+
$this->assertSame('[email protected]', $smritiUpdated['email']['work']);
681+
682+
// Rahul assertions
683+
$this->assertSame('Rahul Updated', $rahulUpdated['name']);
684+
$this->assertIsArray($rahulUpdated['email']);
685+
$this->assertSame('[email protected]', $rahulUpdated['email']['personal']);
686+
$this->assertSame('[email protected]', $rahulUpdated['email']['work']);
687+
}
605688
}

user_guide_src/source/changelogs/v4.6.4.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Bugs Fixed
3434
- **Database:** Fixed a bug in ``Connection::getFieldData()`` for ``SQLSRV`` and ``OCI8`` where extra characters were returned in column default values (specific to those handlers), instead of following the convention used by other drivers.
3535
- **Forge:** Fixed a bug in ``Postgre`` and ``SQLSRV`` where changing a column's default value using ``Forge::modifyColumn()`` method produced incorrect SQL syntax.
3636
- **Model:** Fixed a bug in ``Model::replace()`` where ``created_at`` field (when available) wasn't set correctly.
37+
- **Model:** Fixed a bug in ``Model::insertBatch()`` and ``Model::updateBatch()`` where casts were not applied to inserted or updated values.
3738

3839
See the repo's
3940
`CHANGELOG.md <https://github.com/codeigniter4/CodeIgniter4/blob/develop/CHANGELOG.md>`_

0 commit comments

Comments
 (0)