Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions system/Database/Postgre/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -469,9 +469,8 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri
return ($index->type === 'UNIQUE' || $index->type === 'PRIMARY') && $hasAllFields;
});

foreach (array_map(static fn ($index) => $index->fields, $allIndexes) as $index) {
$constraints[] = current($index);
// only one index can be used?
foreach ($allIndexes as $index) {
$constraints = $index->fields;
break;
}

Expand Down
4 changes: 2 additions & 2 deletions system/Database/SQLite3/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri
return ($index->type === 'PRIMARY' || $index->type === 'UNIQUE') && $hasAllFields;
});

foreach (array_map(static fn ($index) => $index->fields, $allIndexes) as $index) {
$constraints[] = current($index);
foreach ($allIndexes as $index) {
$constraints = $index->fields;
break;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ public function up(): void
'value' => ['type' => 'VARCHAR', 'constraint' => 400, 'null' => true],
])->addKey('id', true)->createTable('misc', true);

// Team members Table (composite key)
$this->forge->addField([
'team_id' => ['type' => 'INTEGER', 'constraint' => 3],
'person_id' => ['type' => 'INTEGER', 'constraint' => 3],
'role' => ['type' => 'VARCHAR', 'constraint' => 40],
'status' => ['type' => 'VARCHAR', 'constraint' => 40],
'created_at' => ['type' => 'DATETIME', 'null' => true],
])->addUniqueKey(['team_id', 'person_id'])->createTable('team_members', true);

// Database Type test table
// missing types:
// TINYINT,MEDIUMINT,BIT,YEAR,BINARY,VARBINARY,TINYTEXT,LONGTEXT,
Expand Down
14 changes: 14 additions & 0 deletions tests/_support/Database/Seeds/CITestSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,20 @@ public function run(): void
'value' => 'ടൈപ്പ്',
],
],
'team_members' => [
[
'team_id' => 1,
'person_id' => 22,
'role' => 'member',
'status' => 'active',
],
[
'team_id' => 1,
'person_id' => 33,
'role' => 'mentor',
'status' => 'active',
],
],
'type_test' => [
[
'type_varchar' => 'test',
Expand Down
1 change: 1 addition & 0 deletions tests/system/Database/Live/MetadataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ protected function setUp(): void
$prefix . 'user',
$prefix . 'job',
$prefix . 'misc',
$prefix . 'team_members',
$prefix . 'type_test',
$prefix . 'empty',
$prefix . 'secondary',
Expand Down
32 changes: 31 additions & 1 deletion tests/system/Database/Live/UpsertTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ public function testUpsertBatchWithOnConflictAndUpdateFields(): void
$this->assertSame('El Salvador', $data[4]->country);
}

public function testUpsertWithMatchingDataOnUniqueIndexandPrimaryKey(): void
public function testUpsertWithMatchingDataOnUniqueIndexAndPrimaryKey(): void
{
$data = [
'id' => 6,
Expand Down Expand Up @@ -607,6 +607,36 @@ public function testUpsertBatchMultipleConstraints(): void
}
}

/**
* @see https://github.com/codeigniter4/CodeIgniter4/issues/9450
*/
public function testUpsertBatchCompositeUniqueIndex(): void
{
$data = [
[
'team_id' => 1,
'person_id' => 22,
'role' => 'leader',
'status' => 'active',
],
[
'team_id' => 1,
'person_id' => 33,
'role' => 'member',
'status' => 'active',
],
];

// uses (team_id, person_id) - composite unique index
$this->db->table('team_members')->upsertBatch($data);

$this->seeInDatabase('team_members', ['team_id' => 1, 'person_id' => 22, 'role' => 'leader']);
$this->dontSeeInDatabase('team_members', ['team_id' => 1, 'person_id' => 22, 'role' => 'member']);

$this->seeInDatabase('team_members', ['team_id' => 1, 'person_id' => 33, 'role' => 'member']);
$this->dontSeeInDatabase('team_members', ['team_id' => 1, 'person_id' => 33, 'role' => 'mentor']);
}

public function testSetBatchOneRow(): void
{
$data = [
Expand Down
1 change: 1 addition & 0 deletions user_guide_src/source/changelogs/v4.6.1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Bugs Fixed

- **CURLRequest:** Fixed an issue where multiple header sections appeared in the CURL response body during multiple redirects from the target server.
- **Cors:** Fixed a bug in the Cors filter that caused the appropriate headers to not be added when another filter returned a response object in the ``before`` filter.
- **Database:** Fixed a bug in ``Postgre`` and ``SQLite3`` handlers where composite unique keys were not fully taken into account for ``upsert`` type of queries.

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