PlatformHelper::getServerVersion()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 9
rs 10
cc 2
nc 2
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace DH\Auditor\Provider\Doctrine\Persistence\Helper;
6
7
use Doctrine\DBAL\Connection;
8
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
9
10
abstract class PlatformHelper
11
{
12
    /**
13
     * MySQL < 5.7.7 and MariaDb < 10.2.2 index length requirements.
14
     *
15
     * @see https://github.com/doctrine/dbal/issues/3419
16
     */
17
    public static function isIndexLengthLimited(string $name, Connection $connection): bool
18
    {
19
        $columns = SchemaHelper::getAuditTableColumns();
20
        if (
21
            !isset($columns[$name])
22
            || $columns[$name]['type'] !== DoctrineHelper::getDoctrineType('STRING')
23
            || (isset($columns[$name]['options']['length']) && $columns[$name]['options']['length'] < 191)
24
        ) {
25
            return false;
26
        }
27
28
        $version = self::getServerVersion($connection);
29
30
        if (null === $version) {
31
            return false;
32
        }
33
34
        $mariadb = false !== mb_stripos($version, 'mariadb');
35
        if ($mariadb && version_compare(self::getMariaDbMysqlVersionNumber($version), '10.2.2', '<')) {
36
            return true;
37
        }
38
39
        return !$mariadb && version_compare(self::getOracleMysqlVersionNumber($version), '5.7.7', '<');
40
    }
41
42
    public static function getServerVersion(Connection $connection): ?string
43
    {
44
        $nativeConnection = $connection->getNativeConnection();
45
46
        if ($nativeConnection instanceof ServerInfoAwareConnection) {
47
            return $nativeConnection->getServerVersion();
48
        }
49
50
        return null;
51
    }
52
53
    public static function isJsonSupported(Connection $connection): bool
54
    {
55
        $version = self::getServerVersion($connection);
56
        if (null === $version) {
57
            return true;
58
        }
59
60
        $mariadb = false !== mb_stripos($version, 'mariadb');
61
62
        return !($mariadb && version_compare(self::getMariaDbMysqlVersionNumber($version), '10.2.7', '<'));
63
        // JSON wasn't supported on MariaDB before 10.2.7
64
        // @see https://mariadb.com/kb/en/json-data-type/
65
66
        // Assume JSON is supported
67
    }
68
69
    /**
70
     * Get a normalized 'version number' from the server string
71
     * returned by Oracle MySQL servers.
72
     *
73
     * @param string $versionString Version string returned by the driver, i.e. '5.7.10'
74
     *
75
     * @copyright Doctrine team
76
     */
77
    public static function getOracleMysqlVersionNumber(string $versionString): string
78
    {
79
        preg_match(
80
            '#^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>\d+))?)?#',
81
            $versionString,
82
            $versionParts
83
        );
84
85
        $majorVersion = $versionParts['major'];
86
        $minorVersion = $versionParts['minor'] ?? 0;
87
        $patchVersion = $versionParts['patch'] ?? null;
88
89
        if ('5' === $majorVersion && '7' === $minorVersion && null === $patchVersion) {
90
            $patchVersion = '9';
91
        }
92
93
        return $majorVersion.'.'.$minorVersion.'.'.$patchVersion;
94
    }
95
96
    /**
97
     * Detect MariaDB server version, including hack for some mariadb distributions
98
     * that starts with the prefix '5.5.5-'.
99
     *
100
     * @param string $versionString Version string as returned by mariadb server, i.e. '5.5.5-Mariadb-10.0.8-xenial'
101
     *
102
     * @copyright Doctrine team
103
     */
104
    public static function getMariaDbMysqlVersionNumber(string $versionString): string
105
    {
106
        preg_match(
107
            '#^(?:5\.5\.5-)?(mariadb-)?(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)#i',
108
            $versionString,
109
            $versionParts
110
        );
111
112
        return $versionParts['major'].'.'.$versionParts['minor'].'.'.$versionParts['patch'];
113
    }
114
}
115