Completed
Push — master ( a45e07...0294bf )
by Agel_Nash
02:52
created

MySqliDriver::dataSeek()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

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