Completed
Push — master ( 969424...1c0e8d )
by Agel_Nash
03:49
created

MySqliDriver   B

Complexity

Total Complexity 39

Size/Duplication

Total Lines 246
Duplicated Lines 0 %

Test Coverage

Coverage 95.6%

Importance

Changes 0
Metric Value
wmc 39
dl 0
loc 246
ccs 87
cts 91
cp 0.956
rs 8.2857
c 0
b 0
f 0

20 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A dataSeek() 0 3 2
B connect() 0 27 6
A getLastError() 0 3 1
A escape() 0 3 1
B getRow() 0 22 5
A query() 0 13 2
A numFields() 0 3 2
A disconnect() 0 9 2
A getRecordCount() 0 3 2
A getAffectedRows() 0 3 1
A fieldName() 0 5 3
A isConnected() 0 3 1
A getVersion() 0 3 1
A setCharset() 0 9 2
A selectDb() 0 3 1
A getConnect() 0 7 2
A getLastErrorNo() 0 9 2
A getInsertId() 0 3 1
A isResult() 0 3 1
1
<?php namespace AgelxNash\Modx\Evo\Database\Drivers;
2
3
use AgelxNash\Modx\Evo\Database\Exceptions;
4
use mysqli;
5
use mysqli_result;
6
use mysqli_sql_exception;
7
use mysqli_driver;
8
use ReflectionClass;
9
10
/**
11
 * @property mysqli $conn
12
 */
13
class MySqliDriver extends AbstractDriver
14
{
15
    /**
16
     * {@inheritDoc}
17
     */
18 49
    public function __construct(array $config = [])
19
    {
20 49
        $driver = new mysqli_driver();
21 49
        $driver->report_mode = MYSQLI_REPORT_STRICT | MYSQLI_REPORT_ERROR;
22
23 49
        $this->setConfig($config);
24 49
    }
25
26
    /**
27
     * {@inheritDoc}
28
     */
29 29
    public function getConnect()
30
    {
31 29
        if (! $this->isConnected()) {
32 29
            return $this->connect();
33
        }
34
35 28
        return $this->conn;
36
    }
37
38
    /**
39
     * {@inheritDoc}
40
     */
41 29
    public function isConnected()
42
    {
43 29
        return ($this->conn instanceof mysqli);
44
    }
45
46
    /**
47
     * {@inheritDoc}
48
     */
49 1
    public function getLastError()
50
    {
51 1
        return $this->getConnect()->error;
52
    }
53
54
    /**
55
     * {@inheritDoc}
56
     */
57 3
    public function getLastErrorNo()
58
    {
59 3
        $out = (string)$this->getConnect()->sqlstate;
60
61 3
        if ($out === '00000') {
62 1
            $out = '';
63
        }
64
65 3
        return $out;
66
    }
67
68
    /**
69
     * {@inheritDoc}
70
     */
71 29
    public function connect()
72
    {
73
        try {
74 29
            $this->conn = new mysqli(
75 29
                $this->getConfig('host'),
76 29
                $this->getConfig('username'),
77 29
                $this->getConfig('password'),
78 29
                $this->getConfig('database')
79
            );
80
81 28
            if ($this->isConnected() && $this->getConnect()->connect_error) {
82
                $this->conn = null;
83
                throw new Exceptions\ConnectException($this->conn->connect_error);
84
            }
85
86 28
            if (! $this->isConnected()) {
87
                $this->conn = null;
88
                throw new Exceptions\ConnectException(
89 28
                    $this->getLastError() ?: 'Failed to create the database connection!'
90
                );
91
            }
92 1
        } catch (mysqli_sql_exception $exception) {
93 1
            $this->conn = null;
94 1
            throw new Exceptions\ConnectException($exception->getMessage(), $exception->getCode());
95
        }
96
97 28
        return $this->conn;
98
    }
99
100
    /**
101
     * {@inheritDoc}
102
     */
103 2
    public function disconnect()
104
    {
105 2
        if ($this->isConnected()) {
106 2
            $this->conn->close();
107
        }
108
109 2
        $this->conn = null;
110
111 2
        return $this;
112
    }
113
114
    /**
115
     * {@inheritDoc}
116
     */
117 20
    public function isResult($result)
118
    {
119 20
        return $result instanceof mysqli_result;
120
    }
121
122
    /**
123
     * @param mysqli_result $result
124
     * {@inheritDoc}
125
     */
126 1
    public function numFields($result)
127
    {
128 1
        return $this->isResult($result) ? $result->field_count : 0;
129
    }
130
131
    /**
132
     * @param mysqli_result $result
133
     * {@inheritDoc}
134
     */
135 1
    public function fieldName($result, $col = 0)
136
    {
137 1
        $field = $this->isResult($result) ? $result->fetch_field_direct($col) : [];
138
139 1
        return isset($field->name) ? $field->name : null;
140
    }
141
142
    /**
143
     * {@inheritDoc}
144
     */
145 27
    public function setCharset($charset, $method = null)
146
    {
147 27
        if ($method === null) {
148 1
            $method = $this->getConfig('method');
149
        }
150
151 27
        $this->query($method . ' ' . $charset);
152
153 27
        return $this->getConnect()->set_charset($charset);
154
    }
155
156
    /**
157
     * {@inheritDoc}
158
     */
159 1
    public function selectDb($name)
160
    {
161 1
        return $this->getConnect()->select_db($name);
162
    }
163
164
    /**
165
     * {@inheritDoc}
166
     */
167 1
    public function escape($data)
168
    {
169 1
        return $this->getConnect()->escape_string($data);
170
    }
171
172
    /**
173
     * {@inheritDoc}
174
     */
175 27
    public function query($sql)
176
    {
177
        try {
178 27
            $result = $this->getConnect()->query($sql);
179 3
        } catch (mysqli_sql_exception $exception) {
180 3
            $reflect = new ReflectionClass($exception);
181 3
            $property = $reflect->getProperty('sqlstate');
182 3
            $property->setAccessible(true);
183 3
            throw (new Exceptions\QueryException($exception->getMessage(), $property->getValue($exception)))
184 3
                ->setQuery($sql);
185
        }
186
187 27
        return $result;
188
    }
189
190
    /**
191
     * @param mysqli_result $result
192
     * {@inheritDoc}
193
     */
194 14
    public function getRecordCount($result)
195
    {
196 14
        return $this->isResult($result) ? $result->num_rows : 0;
197
    }
198
199
    /**
200
     * @param mysqli_result $result
201
     * {@inheritDoc}
202
     */
203 10
    public function getRow($result, $mode = 'assoc')
204
    {
205
        switch ($mode) {
206 10
            case 'assoc':
207 7
                $out = $result->fetch_assoc();
208 7
                break;
209 6
            case 'num':
210 5
                $out = $result->fetch_row();
211 5
                break;
212 2
            case 'object':
213 1
                $out = $result->fetch_object();
214 1
                break;
215 2
            case 'both':
216 1
                $out = $result->fetch_array(MYSQLI_BOTH);
217 1
                break;
218
            default:
219 1
                throw new Exceptions\UnknownFetchTypeException(
220 1
                    "Unknown get type ($mode) specified for fetchRow - must be empty, 'assoc', 'num' or 'both'."
221
                );
222
        }
223
224 10
        return $out;
225
    }
226
227
    /**
228
     * {@inheritDoc}
229
     */
230 2
    public function getVersion()
231
    {
232 2
        return $this->getConnect()->server_info;
233
    }
234
235
    /**
236
     * {@inheritDoc}
237
     */
238 3
    public function getInsertId()
239
    {
240 3
        return $this->getConnect()->insert_id;
241
    }
242
243
    /**
244
     * {@inheritDoc}
245
     */
246 8
    public function getAffectedRows()
247
    {
248 8
        return $this->getConnect()->affected_rows;
249
    }
250
251
    /**
252
     * @param mysqli_result $result
253
     * @param int $position
254
     * @return bool
255
     */
256 1
    public function dataSeek(&$result, $position)
257
    {
258 1
        return $this->isResult($result) ? $result->data_seek($position) : false;
259
    }
260
}
261