Passed
Pull Request — 4.11 (#10334)
by Steve
08:01
created

Utf8TestHelper   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 58
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 21
dl 0
loc 58
rs 10
c 1
b 0
f 0
wmc 17

5 Methods

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