Skip to content

Commit 6f27dad

Browse files
committed
Merge branch '4.11' into 4
2 parents 07aae0e + dccaa91 commit 6f27dad

File tree

3 files changed

+81
-6
lines changed

3 files changed

+81
-6
lines changed

tests/php/ORM/MySQLPDOConnectorTest.php

+7-4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use SilverStripe\Dev\TestOnly;
1010
use SilverStripe\ORM\Tests\MySQLPDOConnectorTest\PDOConnector;
1111
use SilverStripe\ORM\DB;
12+
use SilverStripe\Tests\ORM\Utf8\Utf8TestHelper;
1213

1314
/**
1415
* @requires extension PDO
@@ -38,8 +39,9 @@ public function testConnectionCharsetControl($charset, $defaultCollation)
3839
$cset = $connection->query('show variables like "character_set_connection"')->fetch(PDO::FETCH_NUM)[1];
3940
$collation = $connection->query('show variables like "collation_connection"')->fetch(PDO::FETCH_NUM)[1];
4041

41-
$this->assertEquals($charset, $cset);
42-
$this->assertEquals($defaultCollation, $collation);
42+
$helper = new Utf8TestHelper();
43+
$this->assertEquals($helper->getUpdatedUtfCharsetForCurrentDB($charset), $cset);
44+
$this->assertEquals($helper->getUpdatedUtfCollationForCurrentDB($defaultCollation), $collation);
4345

4446
unset($cset, $connection, $connector, $config);
4547
}
@@ -66,8 +68,9 @@ public function testConnectionCollationControl($charset, $defaultCollation, $cus
6668
$cset = $connection->query('show variables like "character_set_connection"')->fetch(PDO::FETCH_NUM)[1];
6769
$collation = $connection->query('show variables like "collation_connection"')->fetch(PDO::FETCH_NUM)[1];
6870

69-
$this->assertEquals($charset, $cset);
70-
$this->assertEquals($customCollation, $collation);
71+
$helper = new Utf8TestHelper();
72+
$this->assertEquals($helper->getUpdatedUtfCharsetForCurrentDB($charset), $cset);
73+
$this->assertEquals($helper->getUpdatedUtfCollationForCurrentDB($customCollation), $collation);
7174

7275
unset($cset, $connection, $connector, $config);
7376
}

tests/php/ORM/MySQLiConnectorTest.php

+8-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use SilverStripe\Dev\TestOnly;
77
use SilverStripe\ORM\Tests\MySQLiConnectorTest\MySQLiConnector;
88
use SilverStripe\ORM\DB;
9+
use SilverStripe\Tests\ORM\Utf8\Utf8TestHelper;
910

1011
/**
1112
* @requires extension mysqli
@@ -31,6 +32,10 @@ public function testConnectionCharsetControl($charset, $defaultCollation)
3132

3233
$cset = $connection->get_charset();
3334

35+
// Note: we do not need to update the utf charset here because mysqli with newer
36+
// version of mysql/mariadb still self-reports as 'utf8' rather than 'utf8mb3'
37+
// This is unlike self::testConnectionCollationControl()
38+
// And also unlike MySQLPDOConnectorTest::testConnectionCharsetControl()
3439
$this->assertEquals($charset, $cset->charset);
3540
$this->assertEquals($defaultCollation, $cset->collation);
3641

@@ -77,8 +82,9 @@ public function testConnectionCollationControl($charset, $defaultCollation, $cus
7782
$cset = $connection->query('show variables like "character_set_connection"')->fetch_array()[1];
7883
$collation = $connection->query('show variables like "collation_connection"')->fetch_array()[1];
7984

80-
$this->assertEquals($charset, $cset);
81-
$this->assertEquals($customCollation, $collation);
85+
$helper = new Utf8TestHelper();
86+
$this->assertEquals($helper->getUpdatedUtfCharsetForCurrentDB($charset), $cset);
87+
$this->assertEquals($helper->getUpdatedUtfCollationForCurrentDB($customCollation), $collation);
8288

8389
$connection->close();
8490
unset($cset, $connection, $connector, $config);

tests/php/ORM/Utf8/Utf8TestHelper.php

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
namespace SilverStripe\Tests\ORM\Utf8;
4+
5+
use SilverStripe\Dev\TestOnly;
6+
use SilverStripe\ORM\DB;
7+
8+
class Utf8TestHelper implements TestOnly
9+
{
10+
private ?string $dbVersion = null;
11+
12+
public function getUpdatedUtfCharsetForCurrentDB(string $charset): string
13+
{
14+
if ($charset !== 'utf8') {
15+
return $charset;
16+
}
17+
return $this->isMySqlGte80() || $this->isMariaDBGte106() ? 'utf8mb3' : 'utf8';
18+
}
19+
20+
public function getUpdatedUtfCollationForCurrentDB(string $collation): string
21+
{
22+
if ($collation === 'utf8_general_ci') {
23+
return $this->isMariaDBGte106() ? 'utf8mb3_general_ci' : 'utf8_general_ci';
24+
}
25+
if ($collation === 'utf8_unicode_520_ci') {
26+
return $this->isMariaDBGte106() ? 'utf8mb3_unicode_520_ci' : 'utf8_unicode_520_ci';
27+
}
28+
return $collation;
29+
}
30+
31+
/**
32+
* MySQL has used utf8 as an alias for utf8mb3
33+
* Beginning with MySQL 8.0.28, utf8mb3 is used
34+
* https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8mb3.html
35+
*/
36+
private function isMySqlGte80(): bool
37+
{
38+
// Example MySQL version: 8.0.29
39+
if (preg_match('#^([0-9]+)\.[0-9]+\.[0-9]+$#', $this->getDBVersion(), $m)) {
40+
return (int) $m[1] >= 8;
41+
}
42+
return false;
43+
}
44+
45+
/**
46+
* Until MariaDB 10.5, utf8mb3 was an alias for utf8.
47+
* From MariaDB 10.6, utf8 is by default an alias for utf8mb3
48+
* https://mariadb.com/kb/en/unicode/
49+
*/
50+
private function isMariaDBGte106(): bool
51+
{
52+
// Example mariadb version: 5.5.5-10.6.8-mariadb-1:10.6.8+maria~focal
53+
if (preg_match('#([0-9]+)\.([0-9]+)\.[0-9]+-mariadb#', $this->getDBVersion(), $m)) {
54+
return (int) $m[1] >= 11 || ((int) $m[1] >= 10 && (int) $m[2] >= 6);
55+
}
56+
return false;
57+
}
58+
59+
private function getDBVersion(): string
60+
{
61+
if (is_null($this->dbVersion)) {
62+
$this->dbVersion = strtolower(DB::get_conn()->getVersion());
63+
}
64+
return $this->dbVersion;
65+
}
66+
}

0 commit comments

Comments
 (0)