Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: case-insensitivity in the like() method when in use with accented characters #9238

Merged
merged 7 commits into from
Nov 3, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion .github/workflows/reusable-phpunit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ jobs:
steps:
- name: Create database for MSSQL Server
if: ${{ inputs.db-platform == 'SQLSRV' }}
run: sqlcmd -S 127.0.0.1 -U sa -P 1Secure*Password1 -Q "CREATE DATABASE test"
run: sqlcmd -S 127.0.0.1 -U sa -P 1Secure*Password1 -Q "CREATE DATABASE test COLLATE Latin1_General_100_CS_AS_SC_UTF8"

- name: Install latest ImageMagick
if: ${{ contains(inputs.extra-extensions, 'imagick') }}
Expand Down
2 changes: 1 addition & 1 deletion system/Database/BaseBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -1151,7 +1151,7 @@ protected function _like($field, string $match = '', string $type = 'AND ', stri

foreach ($keyValue as $k => $v) {
if ($insensitiveSearch) {
$v = strtolower($v);
$v = mb_strtolower($v, 'UTF-8');
}

$prefix = empty($this->{$clause}) ? $this->groupGetType('') : $this->groupGetType($type);
Expand Down
8 changes: 4 additions & 4 deletions system/Database/SQLSRV/Forge.php
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,10 @@ protected function _alterTable(string $alterType, string $table, $processedField

$sql = <<<SQL
SELECT name
FROM SYS.DEFAULT_CONSTRAINTS
WHERE PARENT_OBJECT_ID = OBJECT_ID('{$fullTable}')
AND PARENT_COLUMN_ID IN (
SELECT column_id FROM sys.columns WHERE NAME IN ({$fields}) AND object_id = OBJECT_ID(N'{$fullTable}')
FROM sys.default_constraints
WHERE parent_object_id = OBJECT_ID('{$fullTable}')
AND parent_column_id IN (
SELECT column_id FROM sys.columns WHERE name IN ({$fields}) AND object_id = OBJECT_ID(N'{$fullTable}')
)
SQL;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ public function up(): void

if ($this->db->DBDriver === 'SQLSRV') {
unset($dataTypeFields['type_timestamp']);
$dataTypeFields['type_text'] = ['type' => 'NVARCHAR(max)', 'null' => true];
}

if ($this->db->DBDriver === 'Postgre' || $this->db->DBDriver === 'SQLSRV') {
Expand Down
20 changes: 20 additions & 0 deletions tests/_support/Database/Seeds/CITestSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,26 @@ public function run(): void
'key' => 'key',
'value' => 'value',
],
[
'key' => 'multibyte characters pl',
'value' => 'śćźżłąęó',
michalsn marked this conversation as resolved.
Show resolved Hide resolved
],
[
'key' => 'multibyte characters fa',
'value' => 'خٌوب',
],
[
'key' => 'multibyte characters bn',
'value' => 'টাইপ',
],
[
'key' => 'multibyte characters ko',
'value' => '캐스팅',
],
[
'key' => 'multibyte characters ml',
'value' => 'ടൈപ്പ്',
],
],
'type_test' => [
[
Expand Down
12 changes: 9 additions & 3 deletions tests/system/Database/Live/ForgeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@
$this->forge->dropTable('', true);
}

public function testForeignKey(): void

Check warning on line 491 in tests/system/Database/Live/ForgeTest.php

View workflow job for this annotation

GitHub Actions / DatabaseLive (8.2, OCI8, 8.0) / tests

Took 2.8231s from 0.5000s limit to run CodeIgniter\\Database\\Live\\ForgeTest::testForeignKey
{
$this->forge->dropTable('forge_test_invoices', true);
$this->forge->dropTable('forge_test_users', true);
Expand Down Expand Up @@ -1230,7 +1230,7 @@
$this->forge->dropTable('forge_test_1', true);
}

public function testSetKeyNames(): void

Check warning on line 1233 in tests/system/Database/Live/ForgeTest.php

View workflow job for this annotation

GitHub Actions / DatabaseLive (8.2, OCI8, 8.0) / tests

Took 1.0125s from 0.5000s limit to run CodeIgniter\\Database\\Live\\ForgeTest::testSetKeyNames
{
$this->forge->dropTable('forge_test_1', true);

Expand Down Expand Up @@ -1578,7 +1578,7 @@
$this->forge->dropTable('forge_test_four', true);
}

public function testDropKey(): void

Check warning on line 1581 in tests/system/Database/Live/ForgeTest.php

View workflow job for this annotation

GitHub Actions / DatabaseLive (8.2, OCI8, 8.0) / tests

Took 0.8120s from 0.5000s limit to run CodeIgniter\\Database\\Live\\ForgeTest::testDropKey
{
$this->forge->dropTable('key_test_users', true);
$keyName = 'key_test_users_id';
Expand Down Expand Up @@ -1615,9 +1615,15 @@
public function testAddTextColumnWithConstraint(): void
{
// some DBMS do not allow a constraint for type TEXT
$this->forge->addColumn('user', [
'text_with_constraint' => ['type' => 'text', 'constraint' => 255, 'default' => ''],
]);
if ($this->db->DBDriver === 'SQLSRV') {
$this->forge->addColumn('user', [
'text_with_constraint' => ['type' => 'nvarchar(max)', 'default' => ''],
]);
} else {
$this->forge->addColumn('user', [
'text_with_constraint' => ['type' => 'text', 'constraint' => 255, 'default' => ''],
]);
}

$this->assertTrue($this->db->fieldExists('text_with_constraint', 'user'));

Expand Down Expand Up @@ -1665,7 +1671,7 @@
$this->forge->dropTable('forge_test_users', true);
}

public function testProcessIndexes(): void

Check warning on line 1674 in tests/system/Database/Live/ForgeTest.php

View workflow job for this annotation

GitHub Actions / DatabaseLive (8.2, OCI8, 8.0) / tests

Took 1.4042s from 0.5000s limit to run CodeIgniter\\Database\\Live\\ForgeTest::testProcessIndexes
{
// make sure tables don't exist
$this->forge->dropTable('actions', true);
Expand Down
2 changes: 1 addition & 1 deletion tests/system/Database/Live/GetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public function testGetFieldData(): void
$this->assertSame('int', $typeTest[0]->type_name); // INTEGER AUTOINC
$this->assertSame('varchar', $typeTest[1]->type_name); // VARCHAR
$this->assertSame('char', $typeTest[2]->type_name); // CHAR
$this->assertSame('text', $typeTest[3]->type_name); // TEXT
$this->assertSame('nvarchar', $typeTest[3]->type_name); // TEXT
$this->assertSame('smallint', $typeTest[4]->type_name); // SMALLINT
$this->assertSame('int', $typeTest[5]->type_name); // INTEGER
$this->assertSame('float', $typeTest[6]->type_name); // FLOAT
Expand Down
24 changes: 24 additions & 0 deletions tests/system/Database/Live/LikeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use CodeIgniter\Database\RawSql;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use Tests\Support\Database\Seeds\CITestSeeder;

Expand Down Expand Up @@ -75,6 +76,29 @@ public function testLikeCaseInsensitive(): void
$this->assertSame('Developer', $job->name);
}

#[DataProvider('provideMultibyteCharacters')]
public function testLikeCaseInsensitiveWithMultibyteCharacter(string $match, string $result): void
{
$wai = $this->db->table('without_auto_increment')->like('value', $match, 'both', null, true)->get();
$wai = $wai->getRow();

$this->assertSame($result, $wai->key);
}

/**
* @return iterable<string, array{0: string, 1: string}>
*/
public static function provideMultibyteCharacters(): iterable
{
yield from [
'polish' => ['ŁĄ', 'multibyte characters pl'],
'farsi' => ['خٌوب', 'multibyte characters fa'],
'bengali' => ['টাইপ', 'multibyte characters bn'],
'korean' => ['캐스팅', 'multibyte characters ko'],
'malayalam' => ['ടൈപ്പ്', 'multibyte characters ml'],
];
}

public function testOrLike(): void
{
$jobs = $this->db->table('job')->like('name', 'ian')
Expand Down
1 change: 1 addition & 0 deletions user_guide_src/source/changelogs/v4.5.6.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Bugs Fixed
- **Session Library:** The session initialization debug message now uses the correct log type "debug" instead of "info".

- **Validation:** Fixed the `getValidated()` method that did not return valid data when validation rules used multiple asterisks.
- **Database:** Fixed the case insensitivity option in the ``like()`` method when dealing with accented characters.

- **Parser:** Fixed bug that caused equal key names to be replaced by the key name defined first.

Expand Down
Loading