Completed
Push — master ( 348990...cde96e )
by Agel_Nash
03:07
created

IlluminateDriver::getRow()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 22
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 8.125

Importance

Changes 0
Metric Value
cc 5
eloc 17
nc 5
nop 2
dl 0
loc 22
ccs 8
cts 16
cp 0.5
crap 8.125
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 Illuminate\Database\Capsule\Manager as Capsule;
6
use Illuminate\Database\Connection;
7
use PDOStatement;
8
9
class IlluminateDriver implements DriverInterface
10
{
11
    /**
12
     * @var Connection
13
     */
14
    protected $conn;
15
16
    /**
17
     * @var Capsule
18
     */
19
    protected $capsule;
20
21
    private $affected_rows = 0;
22
23
    /**
24
     * @var array
25
     */
26
    protected $config;
27
28
    /**
29
     * @var array
30
     */
31
    public $lastError;
32
33
    /**
34
     * @var string
35
     */
36
    public $lastErrorNo;
37
38
    protected $driver = 'mysql';
39
40
    /**
41
     * {@inheritDoc}
42
     */
43 19
    public function __construct(array $config = [])
44
    {
45 19
        $this->capsule = new Capsule;
46
47 19
        $this->capsule->setAsGlobal();
48
49 19
        $this->config = $config;
50 19
    }
51
52
    /**
53
     * @return Connection
54
     * @throws Exceptions\Exception
55
     */
56 19
    public function getConnect() : Connection
57
    {
58 19
        if (! $this->isConnected()) {
59 1
            return $this->connect();
60
        }
61
62 19
        return $this->conn;
63
    }
64
65
    /**
66
     * @return
67
     * @throws Exceptions\Exception
68
     */
69 19
    public function connect() : Connection
70
    {
71
        try {
72 19
            $this->capsule->addConnection([
73 19
                'driver'    => $this->driver,
74 19
                'host'      => $this->config['host'],
75 19
                'database'  => $this->config['base'],
76 19
                'username'  => $this->config['user'],
77 19
                'password'  => $this->config['pass'],
78 19
                'charset'   => $this->config['charset'],
79 19
                'collation' => $this->config['collation'],
80 19
                'prefix'    => $this->config['prefix'],
81
            ]);
82
83 19
            $this->conn = $this->capsule->getConnection();
84
        } catch (\Exception $exception) {
85
            throw new Exceptions\ConnectException($exception->getMessage(), $exception->getCode());
86
        }
87
88 19
        return $this->conn;
89
    }
90
91
    /**
92
     * {@inheritDoc}
93
     */
94 1
    public function disconnect() : DriverInterface
95
    {
96 1
        if ($this->isConnected()) {
97 1
            $this->conn->disconnect();
98
        }
99
100 1
        $this->conn = null;
101
102 1
        return $this;
103
    }
104
105
    /**
106
     * @return bool
107
     */
108 19
    public function isConnected() : bool
109
    {
110 19
        return ($this->conn instanceof Connection && $this->conn->getDatabaseName());
111
    }
112
113
    /**
114
     * @param $data
115
     * @return mixed
116
     * @throws Exceptions\Exception
117
     */
118 1
    public function escape($data)
119
    {
120
        /**
121
         * It's not secure
122
         * But need for backward compatibility
123
         */
124
125 1
        $quote = $this->getConnect()->getPdo()->quote($data);
126 1
        return strpos($quote, '\'') === 0 ? mb_substr($quote, 1, -1) : $quote;
127
    }
128
129
    /**
130
     * @return mixed
131
     * @throws Exceptions\Exception
132
     */
133 3
    public function getInsertId()
134
    {
135 3
        return $this->getConnect()->getPdo()->lastInsertId();
136
    }
137
138
    /**
139
     * @return int
140
     * @throws Exceptions\Exception
141
     */
142 8
    public function getAffectedRows() : int
143
    {
144 8
        return $this->affected_rows;
145
    }
146
147
    /**
148
     * @return string
149
     * @throws Exceptions\Exception
150
     */
151 1
    public function getVersion() : string
152
    {
153 1
        return $this->getConnect()->getPdo()->getAttribute(\PDO::ATTR_SERVER_VERSION);
154
        //return $this->getConnect()->server_info;
155
    }
156
157
    /**
158
     * @param PDOStatement $result
159
     * @return int
160
     */
161 9
    public function getRecordCount($result) : int
162
    {
163 9
        return $result->rowCount();
164
    }
165
166
    /**
167
     * {@inheritDoc}
168
     */
169 19
    public function setCharset(string $charset, string $collation, $method = null) : bool
170
    {
171 19
        if ($method === null) {
172
            $method = $this->config['method'];
173
        }
174
175 19
        return (bool)$this->query($method . ' ' . $charset . ' COLLATE ' . $collation);
176
    }
177
178
    /**
179
     * @param $result
180
     * @return bool
181
     */
182 19
    public function isResult($result) : bool
183
    {
184 19
        return $result instanceof PDOStatement;
185
    }
186
187
    /**
188
     * @param PDOStatement $result
189
     * @return int
190
     */
191 1
    public function numFields($result) : int
192
    {
193 1
        return $result->columnCount();
194
    }
195
196
    /**
197
     * @param PDOStatement $result
198
     * @param int $col
199
     * @return string|null
200
     */
201 1
    public function fieldName($result, $col = 0) :? string
202
    {
203 1
        $field = $result->getColumnMeta($col);
204 1
        return $field['name'] ?? null;
205
    }
206
207
    /**
208
     * @param string $name
209
     * @return bool
210
     * @throws Exceptions\Exception
211
     */
212
    public function selectDb(string $name) : bool
213
    {
214
        $this->getConnect()->setDatabaseName($name);
215
216
        return true;
217
    }
218
219
    /**
220
     * @param PDOStatement $result
221
     * @param string $mode
222
     * @return array|mixed|object|\stdClass
223
     * @throws Exceptions\Exception
224
     */
225 7
    public function getRow($result, $mode = 'assoc')
226
    {
227
        switch ($mode) {
228 7
            case 'assoc':
229 5
                $out = $result->fetch(\PDO::FETCH_ASSOC);
230 5
                break;
231 3
            case 'num':
232 3
                $out = $result->fetch(\PDO::FETCH_NUM);
233 3
                break;
234
            case 'object':
235
                $out = $result->fetchObject();
236
                break;
237
            case 'both':
238
                $out = $result->fetch(\PDO::FETCH_BOTH);
239
                break;
240
            default:
241
                throw new Exceptions\UnknownFetchTypeException(
242
                    "Unknown get type ($mode) specified for fetchRow - must be empty, 'assoc', 'num' or 'both'."
243
                );
244
        }
245
246 7
        return $out;
247
    }
248
249
    /**
250
     * @param string $query
251
     * @return mixed
252
     * @throws Exceptions\Exception
253
     */
254 19
    public function query(string $query)
255
    {
256 19
        $result = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
257
        try {
258 19
            $result = $this->getConnect()->getPdo()->prepare(
259 19
                $query,
260
                [
261 19
                    \PDO::ATTR_CURSOR => \PDO::CURSOR_SCROLL
262
                ]
263
            );
264 19
            $result->setFetchMode(\PDO::FETCH_ASSOC);
265 19
            if ($result->execute() === false) {
266
                $result = false;
267
            }
268 19
            $this->affected_rows = \is_bool($result) ? 0 : $result->rowCount();
269 19
            if ($this->affected_rows === 0 && $this->isResult($result) && 0 !== mb_stripos(trim($query), 'SELECT')) {
270 19
                $result = true;
271
            }
272 2
        } catch (\Exception $exception) {
273 2
            $this->lastError = $this->isResult($result) ? $result->errorInfo() : [];
274 2
            $this->lastErrorNo = $this->isResult($result) ? ($result->errorCode() ?? $exception->getCode()) : '';
275 2
            throw (new Exceptions\QueryException($exception->getMessage(), $exception->getCode()))
276 2
                ->setQuery($query);
277
        }
278
279 19
        return $result;
280
    }
281
282
    /**
283
     * @param string $name
284
     * @param $result
285
     * @return array
286
     * @throws Exceptions\Exception
287
     */
288 3
    public function getColumn(string $name, $result) : array
289
    {
290 3
        $col = [];
291
292 3
        if ($result instanceof PDOStatement) {
293 3
            while ($row = $this->getRow($result)) {
294 3
                $col[] = $row[$name];
295
            }
296
        }
297
298 3
        return $col;
299
    }
300
301
    /**
302
     * @param $result
303
     * @return array
304
     */
305 1
    public function getColumnNames($result) : array
306
    {
307 1
        $names = [];
308
309 1
        if ($result instanceof PDOStatement) {
310 1
            $limit = $this->numFields($result);
311 1
            for ($i = 0; $i < $limit; $i++) {
312 1
                $names[] = $this->fieldName($result, $i);
313
            }
314
        }
315
316 1
        return $names;
317
    }
318
319
    /**
320
     * @param $result
321
     * @return bool|mixed
322
     * @throws Exceptions\Exception
323
     */
324 3
    public function getValue($result)
325
    {
326 3
        $out = false;
327
328 3
        if ($result instanceof PDOStatement) {
329 3
            $result = $this->getRow($result, 'num');
330 3
            $out = $result[0] ?? false;
331
        }
332
333 3
        return $out;
334
    }
335
336
    /**
337
     * @param $result
338
     * @return array|mixed
339
     * @throws Exceptions\Exception
340
     */
341 1
    public function getTableMetaData($result)
342
    {
343 1
        $out = [];
344
345 1
        if ($result instanceof PDOStatement) {
346 1
            while ($row = $this->getRow($result)) {
347 1
                $fieldName = $row['Field'];
348 1
                $out[$fieldName] = $row;
349
            }
350
        }
351
352 1
        return $out;
353
    }
354
355
    /**
356
     * @return string|null
357
     * @throws Exceptions\Exception
358
     */
359 1
    public function getLastError() :? string
360
    {
361 1
        return (string)($this->getConnect()->getPdo()->errorInfo()[2] ?? $this->lastError[2]);
362
    }
363
364
    /**
365
     * @return string|null
366
     * @throws Exceptions\Exception
367
     */
368 1
    public function getLastErrorNo() :? string
369
    {
370 1
        return (string)($this->getConnect()->getPdo()->errorInfo()[1] ?? $this->lastErrorNo);
371
    }
372
373
    /**
374
     * {@inheritDoc}
375
     * @param \PDOStatement $result
376
     */
377
    public function dataSeek(&$result, $position) : bool
378
    {
379
        throw new Exceptions\DriverException('No implemented');
380
    }
381
}
382