Passed
Push — master ( fafac8...b9fec6 )
by Sergei
15:30
created

AbstractMySQLDriver::convertException()   C

Complexity

Conditions 53
Paths 53

Size

Total Lines 77
Code Lines 65

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 66
CRAP Score 53

Importance

Changes 0
Metric Value
dl 0
loc 77
ccs 66
cts 66
cp 1
rs 5.0218
c 0
b 0
f 0
cc 53
eloc 65
nc 53
nop 2
crap 53

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
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\DBAL\Driver;
21
22
use Doctrine\DBAL\DBALException;
23
use Doctrine\DBAL\Driver;
24
use Doctrine\DBAL\Exception;
25
use Doctrine\DBAL\Platforms\MariaDb1027Platform;
26
use Doctrine\DBAL\Platforms\MySQL57Platform;
27
use Doctrine\DBAL\Platforms\MySQL80Platform;
28
use Doctrine\DBAL\Platforms\MySqlPlatform;
29
use Doctrine\DBAL\Schema\MySqlSchemaManager;
30
use Doctrine\DBAL\VersionAwarePlatformDriver;
31
use function preg_match;
32
use function stripos;
33
use function version_compare;
34
35
/**
36
 * Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for MySQL based drivers.
37
 *
38
 * @author Steve Müller <[email protected]>
39
 * @link   www.doctrine-project.org
40
 * @since  2.5
41
 */
42
abstract class AbstractMySQLDriver implements Driver, ExceptionConverterDriver, VersionAwarePlatformDriver
43
{
44
    /**
45
     * {@inheritdoc}
46
     *
47
     * @link http://dev.mysql.com/doc/refman/5.7/en/error-messages-client.html
48
     * @link http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html
49
     */
50 1098
    public function convertException($message, DriverException $exception)
51
    {
52 1098
        switch ($exception->getErrorCode()) {
53 1098
            case '1213':
54 76
                return new Exception\DeadlockException($message, $exception);
55 1098
            case '1205':
56 76
                return new Exception\LockWaitTimeoutException($message, $exception);
57 1098
            case '1050':
58 412
                return new Exception\TableExistsException($message, $exception);
59
60 770
            case '1051':
61 714
            case '1146':
62 658
                return new Exception\TableNotFoundException($message, $exception);
63
64 706
            case '1216':
65 706
            case '1217':
66 706
            case '1451':
67 690
            case '1452':
68 682
            case '1701':
69 108
                return new Exception\ForeignKeyConstraintViolationException($message, $exception);
70
71 674
            case '1062':
72 658
            case '1557':
73 658
            case '1569':
74 658
            case '1586':
75 92
                return new Exception\UniqueConstraintViolationException($message, $exception);
76
77 658
            case '1054':
78 650
            case '1166':
79 650
            case '1611':
80 84
                return new Exception\InvalidFieldNameException($message, $exception);
81
82 650
            case '1052':
83 642
            case '1060':
84 642
            case '1110':
85 84
                return new Exception\NonUniqueFieldNameException($message, $exception);
86
87 642
            case '1064':
88 634
            case '1149':
89 634
            case '1287':
90 634
            case '1341':
91 634
            case '1342':
92 634
            case '1343':
93 634
            case '1344':
94 634
            case '1382':
95 634
            case '1479':
96 634
            case '1541':
97 634
            case '1554':
98 634
            case '1626':
99 84
                return new Exception\SyntaxErrorException($message, $exception);
100
101 634
            case '1044':
102 634
            case '1045':
103 618
            case '1046':
104 618
            case '1049':
105 610
            case '1095':
106 610
            case '1142':
107 610
            case '1143':
108 610
            case '1227':
109 610
            case '1370':
110 610
            case '1429':
111 610
            case '2002':
112 602
            case '2005':
113 108
                return new Exception\ConnectionException($message, $exception);
114
115 602
            case '1048':
116 594
            case '1121':
117 594
            case '1138':
118 594
            case '1171':
119 594
            case '1252':
120 594
            case '1263':
121 594
            case '1364':
122 594
            case '1566':
123 84
                return new Exception\NotNullConstraintViolationException($message, $exception);
124
        }
125
126 594
        return new Exception\DriverException($message, $exception);
127
    }
128
129
    /**
130
     * {@inheritdoc}
131
     *
132
     * @throws DBALException
133
     */
134 331
    public function createDatabasePlatformForVersion($version)
135
    {
136 331
        $mariadb = false !== stripos($version, 'mariadb');
137 331
        if ($mariadb && version_compare($this->getMariaDbMysqlVersionNumber($version), '10.2.7', '>=')) {
138 110
            return new MariaDb1027Platform();
139
        }
140
141 278
        if (! $mariadb) {
142 220
            $oracleMysqlVersion = $this->getOracleMysqlVersionNumber($version);
143 163
            if (version_compare($oracleMysqlVersion, '8', '>=')) {
144 57
                return new MySQL80Platform();
145
            }
146 163
            if (version_compare($oracleMysqlVersion, '5.7.9', '>=')) {
147 110
                return new MySQL57Platform();
148
            }
149
        }
150
151 168
        return $this->getDatabasePlatform();
152
    }
153
154
    /**
155
     * Get a normalized 'version number' from the server string
156
     * returned by Oracle MySQL servers.
157
     *
158
     * @param string $versionString Version string returned by the driver, i.e. '5.7.10'
159
     * @throws DBALException
160
     */
161 220
    private function getOracleMysqlVersionNumber(string $versionString) : string
162
    {
163 220
        if ( ! preg_match(
164 220
            '/^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>\d+))?)?/',
165 220
            $versionString,
166 220
            $versionParts
167
        )) {
168 57
            throw DBALException::invalidPlatformVersionSpecified(
169 57
                $versionString,
170 57
                '<major_version>.<minor_version>.<patch_version>'
171
            );
172
        }
173 163
        $majorVersion = $versionParts['major'];
174 163
        $minorVersion = $versionParts['minor'] ?? 0;
175 163
        $patchVersion = $versionParts['patch'] ?? null;
176
177 163
        if ('5' === $majorVersion && '7' === $minorVersion && null === $patchVersion) {
178 57
            $patchVersion = '9';
179
        }
180
181 163
        return $majorVersion . '.' . $minorVersion . '.' . $patchVersion;
182
    }
183
184
    /**
185
     * Detect MariaDB server version, including hack for some mariadb distributions
186
     * that starts with the prefix '5.5.5-'
187
     *
188
     * @param string $versionString Version string as returned by mariadb server, i.e. '5.5.5-Mariadb-10.0.8-xenial'
189
     * @throws DBALException
190
     */
191 168
    private function getMariaDbMysqlVersionNumber(string $versionString) : string
192
    {
193 168
        if ( ! preg_match(
194 168
            '/^(?:5\.5\.5-)?(mariadb-)?(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)/i',
195 168
            $versionString,
196 168
            $versionParts
197
        )) {
198
            throw DBALException::invalidPlatformVersionSpecified(
199
                $versionString,
200
                '^(?:5\.5\.5-)?(mariadb-)?<major_version>.<minor_version>.<patch_version>'
201
            );
202
        }
203
204 168
        return $versionParts['major'] . '.' . $versionParts['minor'] . '.' . $versionParts['patch'];
205
    }
206
207
    /**
208
     * {@inheritdoc}
209
     */
210 514
    public function getDatabase(\Doctrine\DBAL\Connection $conn)
211
    {
212 514
        $params = $conn->getParams();
213
214 514
        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 boolean which is incompatible with the return type mandated by Doctrine\DBAL\Driver::getDatabase() of string.
Loading history...
215
    }
216
217
    /**
218
     * {@inheritdoc}
219
     * @return MySqlPlatform
220
     */
221 225
    public function getDatabasePlatform()
222
    {
223 225
        return new MySqlPlatform();
224
    }
225
226
    /**
227
     * {@inheritdoc}
228
     * @return MySqlSchemaManager
229
     */
230 121
    public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
231
    {
232 121
        return new MySqlSchemaManager($conn);
233
    }
234
}
235