Passed
Pull Request — master (#3645)
by Matthew
14:01
created

AbstractMySQLDriver::convertException()   D

Complexity

Conditions 57
Paths 56

Size

Total Lines 82
Code Lines 70

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 68
CRAP Score 57.2459

Importance

Changes 0
Metric Value
eloc 70
c 0
b 0
f 0
dl 0
loc 82
ccs 68
cts 71
cp 0.9577
rs 4.1666
cc 57
nc 56
nop 2
crap 57.2459

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Doctrine\DBAL\Driver;
4
5
use Doctrine\DBAL\Connection;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Doctrine\DBAL\Driver\Connection. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
6
use Doctrine\DBAL\DBALException;
7
use Doctrine\DBAL\Driver;
8
use Doctrine\DBAL\Exception;
9
use Doctrine\DBAL\Platforms\MariaDb1027Platform;
10
use Doctrine\DBAL\Platforms\MySQL57Platform;
11
use Doctrine\DBAL\Platforms\MySQL80Platform;
12
use Doctrine\DBAL\Platforms\MySqlPlatform;
13
use Doctrine\DBAL\Schema\MySqlSchemaManager;
14
use Doctrine\DBAL\VersionAwarePlatformDriver;
15
use function preg_match;
16
use function stripos;
17
use function version_compare;
18
19
/**
20
 * Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for MySQL based drivers.
21
 */
22
abstract class AbstractMySQLDriver implements Driver, ExceptionConverterDriver, VersionAwarePlatformDriver
23
{
24
    /**
25
     * {@inheritdoc}
26
     *
27
     * @link http://dev.mysql.com/doc/refman/5.7/en/error-messages-client.html
28
     * @link http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html
29
     */
30 8536
    public function convertException($message, DriverException $exception)
31
    {
32 8536
        switch ($exception->getErrorCode()) {
33 8536
            case '1213':
34 6840
                return new Exception\DeadlockException($message, $exception);
35 8528
            case '1205':
36 6813
                return new Exception\LockWaitTimeoutException($message, $exception);
37 8520
            case '1050':
38 7029
                return new Exception\TableExistsException($message, $exception);
39
40 8512
            case '1051':
41 8504
            case '1146':
42 7010
                return new Exception\TableNotFoundException($message, $exception);
43
44 8496
            case '1216':
45 8488
            case '1217':
46 8480
            case '1451':
47 8472
            case '1452':
48 8464
            case '1701':
49 7863
                return new Exception\ForeignKeyConstraintViolationException($message, $exception);
50
51 8464
            case '1062':
52 8456
            case '1557':
53 8448
            case '1569':
54 8440
            case '1586':
55 6972
                return new Exception\UniqueConstraintViolationException($message, $exception);
56
57 8432
            case '1054':
58 8424
            case '1166':
59 8416
            case '1611':
60 7747
                return new Exception\InvalidFieldNameException($message, $exception);
61
62 8408
            case '1052':
63 8400
            case '1060':
64 8392
            case '1110':
65 7666
                return new Exception\NonUniqueFieldNameException($message, $exception);
66
67 8384
            case '1064':
68 8376
            case '1149':
69 8368
            case '1287':
70 8360
            case '1341':
71 8352
            case '1342':
72 8344
            case '1343':
73 8336
            case '1344':
74 8328
            case '1382':
75 8320
            case '1479':
76 8312
            case '1541':
77 8304
            case '1554':
78 8296
            case '1626':
79 7441
                return new Exception\SyntaxErrorException($message, $exception);
80
81 8288
            case '1044':
82 8253
            case '1045':
83 8218
            case '1046':
84 8183
            case '1049':
85 8148
            case '1095':
86 8113
            case '1142':
87 8078
            case '1143':
88 8043
            case '1227':
89 8008
            case '1370':
90 7973
            case '1429':
91 7973
            case '2002':
92 7938
            case '2005':
93 7633
            case '2054':
94 8216
                return new Exception\ConnectionException($message, $exception);
95 7633
            case '2006':
96
                if ($exception instanceof Driver\Mysqli\MysqliConnectionException || $exception instanceof PDOConnectionException) {
97
                    return new Exception\ConnectionException($message, $exception);
98
                }
99
                break;
100 7633
            case '1048':
101 7598
            case '1121':
102 7563
            case '1138':
103 7528
            case '1171':
104 7493
            case '1252':
105 7458
            case '1263':
106 7423
            case '1364':
107 7388
            case '1566':
108 7625
                return new Exception\NotNullConstraintViolationException($message, $exception);
109
        }
110
111 6786
        return new Exception\DriverException($message, $exception);
112
    }
113
114
    /**
115
     * {@inheritdoc}
116
     *
117
     * @throws DBALException
118
     */
119 6763
    public function createDatabasePlatformForVersion($version)
120
    {
121 6763
        $mariadb = stripos($version, 'mariadb') !== false;
122 6763
        if ($mariadb && version_compare($this->getMariaDbMysqlVersionNumber($version), '10.2.7', '>=')) {
123 6757
            return new MariaDb1027Platform();
124
        }
125
126 6763
        if (! $mariadb) {
127 6763
            $oracleMysqlVersion = $this->getOracleMysqlVersionNumber($version);
128 6757
            if (version_compare($oracleMysqlVersion, '8', '>=')) {
129 6757
                return new MySQL80Platform();
130
            }
131 6757
            if (version_compare($oracleMysqlVersion, '5.7.9', '>=')) {
132 6757
                return new MySQL57Platform();
133
            }
134
        }
135
136 6757
        return $this->getDatabasePlatform();
137
    }
138
139
    /**
140
     * Get a normalized 'version number' from the server string
141
     * returned by Oracle MySQL servers.
142
     *
143
     * @param string $versionString Version string returned by the driver, i.e. '5.7.10'
144
     *
145
     * @throws DBALException
146
     */
147 6763
    private function getOracleMysqlVersionNumber(string $versionString) : string
148
    {
149 6763
        if (! preg_match(
150 12
            '/^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>\d+))?)?/',
151 6763
            $versionString,
152 6763
            $versionParts
153
        )) {
154 6730
            throw DBALException::invalidPlatformVersionSpecified(
155 6
                $versionString,
156 6730
                '<major_version>.<minor_version>.<patch_version>'
157
            );
158
        }
159 6757
        $majorVersion = $versionParts['major'];
160 6757
        $minorVersion = $versionParts['minor'] ?? 0;
161 6757
        $patchVersion = $versionParts['patch'] ?? null;
162
163 6757
        if ($majorVersion === '5' && $minorVersion === '7' && $patchVersion === null) {
164 6757
            $patchVersion = '9';
165
        }
166
167 6757
        return $majorVersion . '.' . $minorVersion . '.' . $patchVersion;
168
    }
169
170
    /**
171
     * Detect MariaDB server version, including hack for some mariadb distributions
172
     * that starts with the prefix '5.5.5-'
173
     *
174
     * @param string $versionString Version string as returned by mariadb server, i.e. '5.5.5-Mariadb-10.0.8-xenial'
175
     *
176
     * @throws DBALException
177
     */
178 6757
    private function getMariaDbMysqlVersionNumber(string $versionString) : string
179
    {
180 6757
        if (! preg_match(
181 6
            '/^(?:5\.5\.5-)?(mariadb-)?(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)/i',
182 6757
            $versionString,
183 6757
            $versionParts
184
        )) {
185
            throw DBALException::invalidPlatformVersionSpecified(
186
                $versionString,
187
                '^(?:5\.5\.5-)?(mariadb-)?<major_version>.<minor_version>.<patch_version>'
188
            );
189
        }
190
191 6757
        return $versionParts['major'] . '.' . $versionParts['minor'] . '.' . $versionParts['patch'];
192
    }
193
194
    /**
195
     * {@inheritdoc}
196
     */
197 8163
    public function getDatabase(Connection $conn)
198
    {
199 8163
        $params = $conn->getParams();
200
201 8163
        return $params['dbname'] ?? $conn->query('SELECT DATABASE()')->fetchColumn();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $params['dbname']...BASE()')->fetchColumn() also could return the type false which is incompatible with the return type mandated by Doctrine\DBAL\Driver::getDatabase() of string.
Loading history...
202
    }
203
204
    /**
205
     * {@inheritdoc}
206
     *
207
     * @return MySqlPlatform
208
     */
209 6763
    public function getDatabasePlatform()
210
    {
211 6763
        return new MySqlPlatform();
212
    }
213
214
    /**
215
     * {@inheritdoc}
216
     *
217
     * @return MySqlSchemaManager
218
     */
219 6676
    public function getSchemaManager(Connection $conn)
220
    {
221 6676
        return new MySqlSchemaManager($conn);
222
    }
223
}
224