Passed
Push — master ( 43827d...146f8a )
by Agel_Nash
02:46
created

MySqliDriver::getRow()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 22
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 5.0488

Importance

Changes 0
Metric Value
cc 5
eloc 17
nc 5
nop 2
dl 0
loc 22
ccs 14
cts 16
cp 0.875
crap 5.0488
rs 8.6737
c 0
b 0
f 0
1
<?php namespace AgelxNash\Modx\Evo\Database\Drivers;
2
3
use AgelxNash\Modx\Evo\Database\Interfaces\DriverInterface;
4
use AgelxNash\Modx\Evo\Database\Exceptions;
5
use mysqli;
6
use mysqli_result;
7
use mysqli_sql_exception;
8
use mysqli_driver;
9
10
class MySqliDriver implements DriverInterface
11
{
12
    /**
13
     * @var mysqli
14
     */
15
    protected $conn;
16
17
    /**
18
     * @var array
19
     */
20
    protected $config;
21
22
    /**
23
     * {@inheritDoc}
24
     */
25 40
    public function __construct(array $config = [])
26
    {
27 40
        $driver = new mysqli_driver();
28 40
        $driver->report_mode = MYSQLI_REPORT_STRICT | MYSQLI_REPORT_ERROR;
29
30 40
        $this->config = $config;
31 40
    }
32
33
    /**
34
     * @return mixed
35
     * @throws Exceptions\Exception
36
     */
37 20
    public function getConnect()
38
    {
39 20
        if (! $this->isConnected()) {
40 1
            return $this->connect();
41
        }
42
43 20
        return $this->conn;
44
    }
45
46
    /**
47
     * @return mysqli
48
     * @throws Exceptions\Exception
49
     */
50 21
    public function connect() : mysqli
51
    {
52
        try {
53 21
            $this->conn = new mysqli(
54 21
                $this->config['host'],
55 21
                $this->config['user'],
56 21
                $this->config['pass'],
57 21
                $this->config['base']
58
            );
59
60 20
            if ($this->isConnected() && $this->getConnect()->connect_error) {
61
                throw new Exceptions\ConnectException($this->conn->connect_error);
62
            }
63
64 20
            if (! $this->isConnected()) {
65
                throw new Exceptions\ConnectException(
66 20
                    $this->getLastError() ?: 'Failed to create the database connection!'
67
                );
68
            }
69 1
        } catch (mysqli_sql_exception $exception) {
70 1
            throw new Exceptions\ConnectException($exception->getMessage(), $exception->getCode());
71
        }
72
73 20
        return $this->conn;
74
    }
75
76
    /**
77
     * {@inheritDoc}
78
     */
79 1
    public function disconnect() : DriverInterface
80
    {
81 1
        if ($this->isConnected()) {
82 1
            $this->conn->close();
83
        }
84
85 1
        $this->conn = null;
86
87 1
        return $this;
88
    }
89
90
    /**
91
     * @return bool
92
     */
93 20
    public function isConnected() : bool
94
    {
95 20
        return ($this->conn instanceof mysqli);
96
    }
97
98
    /**
99
     * @param $data
100
     * @return mixed
101
     * @throws Exceptions\Exception
102
     */
103 1
    public function escape($data)
104
    {
105 1
        return $this->getConnect()->escape_string($data);
106
    }
107
108
    /**
109
     * @return mixed
110
     * @throws Exceptions\Exception
111
     */
112 3
    public function getInsertId()
113
    {
114 3
        return $this->getConnect()->insert_id;
115
    }
116
117
    /**
118
     * @return int
119
     * @throws Exceptions\Exception
120
     */
121 20
    public function getAffectedRows() : int
122
    {
123 20
        return $this->getConnect()->affected_rows;
124
    }
125
126
    /**
127
     * @return string
128
     * @throws Exceptions\Exception
129
     */
130 1
    public function getVersion() : string
131
    {
132 1
        return $this->getConnect()->server_info;
133
    }
134
135
    /**
136
     * @param mysqli_result $result
137
     * @return int
138
     */
139 10
    public function getRecordCount($result) : int
140
    {
141 10
        return $result->num_rows;
142
    }
143
144
    /**
145
     * @param string $charset
146
     * @return bool
147
     * @throws Exceptions\Exception
148
     */
149 20
    public function setCharset(string $charset) : bool
150
    {
151 20
        return $this->getConnect()->set_charset($charset);
152
    }
153
154
    /**
155
     * @param $result
156
     * @return bool
157
     */
158 11
    public function isResult($result) : bool
159
    {
160 11
        return $result instanceof mysqli_result;
161
    }
162
163
    /**
164
     * @param mysqli_result $result
165
     * @return int
166
     */
167 1
    public function numFields($result) : int
168
    {
169 1
        return $result->field_count;
170
    }
171
172
    /**
173
     * @param mysqli_result $result
174
     * @param int $col
175
     * @return string|null
176
     */
177 1
    public function fieldName($result, $col = 0) :? string
178
    {
179 1
        $field = $result->fetch_field_direct($col);
180
181 1
        return $field->name ?? null;
182
    }
183
184
    /**
185
     * @param string $name
186
     * @return bool
187
     * @throws Exceptions\Exception
188
     */
189
    public function selectDb(string $name) : bool
190
    {
191
        return $this->getConnect()->select_db($name);
192
    }
193
194
    /**
195
     * @param mysqli_result $result
196
     * @param string $mode
197
     * @return array|mixed|object|\stdClass
198
     * @throws Exceptions\Exception
199
     */
200 8
    public function getRow($result, $mode = 'assoc')
201
    {
202
        switch ($mode) {
203 8
            case 'assoc':
204 6
                $out = $result->fetch_assoc();
205 6
                break;
206 4
            case 'num':
207 4
                $out = $result->fetch_row();
208 4
                break;
209 1
            case 'object':
210 1
                $out = $result->fetch_object();
211 1
                break;
212 1
            case 'both':
213 1
                $out = $result->fetch_array(MYSQLI_BOTH);
214 1
                break;
215
            default:
216
                throw new Exceptions\UnknownFetchTypeException(
217
                    "Unknown get type ($mode) specified for fetchRow - must be empty, 'assoc', 'num' or 'both'."
218
                );
219
        }
220
221 8
        return $out;
222
    }
223
224
    /**
225
     * @param string $query
226
     * @return mixed
227
     * @throws Exceptions\Exception
228
     */
229 20
    public function query(string $query)
230
    {
231
        try {
232 20
            $result = $this->getConnect()->query($query);
233 2
        } catch (mysqli_sql_exception $exception) {
234 2
            throw (new Exceptions\QueryException($exception->getMessage(), $exception->getCode()))
235 2
                ->setQuery($query);
236
        }
237
238 20
        return $result;
239
    }
240
241
    /**
242
     * @param string $name
243
     * @param $result
244
     * @return array
245
     * @throws Exceptions\Exception
246
     */
247 3
    public function getColumn(string $name, $result) : array
248
    {
249 3
        $col = [];
250
251 3
        if ($result instanceof mysqli_result) {
252 3
            while ($row = $this->getRow($result)) {
253 3
                $col[] = $row[$name];
254
            }
255
        }
256
257 3
        return $col;
258
    }
259
260
    /**
261
     * @param $result
262
     * @return array
263
     */
264 1
    public function getColumnNames($result) : array
265
    {
266 1
        $names = [];
267
268 1
        if ($result instanceof mysqli_result) {
269 1
            $limit = $this->numFields($result);
270 1
            for ($i = 0; $i < $limit; $i++) {
271 1
                $names[] = $this->fieldName($result, $i);
272
            }
273
        }
274
275 1
        return $names;
276
    }
277
278
    /**
279
     * @param $result
280
     * @return bool|mixed
281
     * @throws Exceptions\Exception
282
     */
283 3
    public function getValue($result)
284
    {
285 3
        $out = false;
286
287 3
        if ($result instanceof mysqli_result) {
288 3
            $result = $this->getRow($result, 'num');
289 3
            $out = $result[0] ?? false;
290
        }
291
292 3
        return $out;
293
    }
294
295
    /**
296
     * @param $result
297
     * @return array|mixed
298
     * @throws Exceptions\Exception
299
     */
300 1
    public function getTableMetaData($result)
301
    {
302 1
        $out = [];
303
304 1
        if ($result instanceof mysqli_result) {
305 1
            while ($row = $this->getRow($result)) {
306 1
                $fieldName = $row['Field'];
307 1
                $out[$fieldName] = $row;
308
            }
309
        }
310
311 1
        return $out;
312
    }
313
314
    /**
315
     * @return string
316
     * @throws Exceptions\Exception
317
     */
318 1
    public function getLastError() : string
319
    {
320 1
        return $this->getConnect()->error;
321
    }
322
323
    /**
324
     * @return int
325
     * @throws Exceptions\Exception
326
     */
327 1
    public function getLastErrorNo() : int
328
    {
329 1
        return $this->getConnect()->errno;
330
    }
331
332
    /**
333
     * {@inheritDoc}
334
     */
335 1
    public function dataSeek($result, $position) : bool
336
    {
337 1
        return $result->data_seek($position);
338
    }
339
}
340