Passed
Push — master ( 286385...e07415 )
by Agel_Nash
02:39
created

Database::__construct()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 30
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 2.0094

Importance

Changes 0
Metric Value
cc 2
eloc 14
nc 2
nop 8
dl 0
loc 30
ccs 13
cts 15
cp 0.8667
crap 2.0094
rs 8.8571
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php namespace AgelxNash\Modx\Evo\Database;
2
3
class Database implements Interfaces\DatabaseInterface
4
{
5
    use Traits\DebugTrait,
6
        Traits\SupportTrait;
7
8
    /**
9
     * @var array
10
     */
11
    protected $config = [];
12
13
    /**
14
     * @var Drivers\MySqliDriver
15
     */
16
    protected $driver;
17
18
    /**
19
     * @var int
20
     */
21
    protected $safeLoopCount = 1000;
22
23
    /**
24
     * @param string $host
25
     * @param string $base
26
     * @param string $user
27
     * @param string $pass
28
     * @param string $prefix
29
     * @param string $charset
30
     * @param string $method
31
     * @param string $driver
32
     * @throws Exceptions\Exception
33
     */
34 38
    public function __construct(
35
        $host = '',
36
        $base = '',
37
        $user = '',
38
        $pass = '',
39
        $prefix = '',
40
        $charset = 'utf8mb4',
41
        $method = 'SET CHARACTER SET',
42
        $driver = Drivers\MySqliDriver::class
43
    ) {
44 38
        $base = trim($base, '`');
45
46 38
        $this->setConfig(compact(
47 38
            'host',
48 38
            'base',
49 38
            'user',
50 38
            'pass',
51 38
            'prefix',
52 38
            'charset',
53 38
            'method'
54
        ));
55
56 38
        if (! \in_array(Interfaces\DriverInterface::class, class_implements($driver), true)) {
57
            throw new Exceptions\Exception(
58
                $driver . ' should implements the ' . Interfaces\DriverInterface::class
59
            );
60
        }
61
62 38
        $this->driver = new $driver(
63 38
            $this->getConfig()
64
        );
65 38
    }
66
67
    /**
68
     * @param $data
69
     * @return $this
70
     */
71 38
    public function setConfig($data) : self
72
    {
73 38
        $this->config = $data;
74
75 38
        return $this;
76
    }
77
78
    /**
79
     * @param null|string $key
80
     * @return mixed
81
     */
82 38
    public function getConfig($key = null)
83
    {
84 38
        return ($key === null ? $this->config : ($this->config[$key] ?? null));
85
    }
86
87
    /**
88
     * @return mixed
89
     * @throws Exceptions\Exception
90
     */
91 2
    public function getConnect()
92
    {
93 2
        return $this->getDriver()->getConnect();
94
    }
95
96
    /**
97
     * @return Interfaces\DriverInterface
98
     * @throws Exceptions\Exception
99
     */
100 21
    public function getDriver() : Interfaces\DriverInterface
101
    {
102 21
        return $this->driver;
103
    }
104
105
    /**
106
     * @return mixed
107
     * @throws Exceptions\Exception
108
     */
109 19
    public function connect()
110
    {
111 19
        $tStart = microtime(true);
112
113 19
        $out = $this->getDriver()->connect();
114
115 18
        $totalTime = microtime(true) - $tStart;
116 18
        if ($this->isDebug()) {
117 18
            $this->connectionTime = $totalTime;
118
        }
119
120 18
        return $out;
121
    }
122
123
    /**
124
     * @return $this
125
     */
126 1
    public function disconnect() : self
127
    {
128 1
        $this->getDriver()->disconnect();
129
130 1
        $this->connectionTime = 0;
131 1
        $this->flushExecutedQuery();
132
133 1
        return $this;
134
    }
135
136
    /**
137
     * @return bool
138
     */
139 2
    public function isConnected() : bool
140
    {
141 2
        return $this->getDriver()->isConnected();
142
    }
143
144
    /**
145
     * @param string|array $data
146
     * @param int $safeCount
147
     * @return array|string
148
     * @throws Exceptions\Exception
149
     */
150 1
    public function escape($data, $safeCount = 0)
151
    {
152 1
        $safeCount++;
153 1
        if ($this->safeLoopCount < $safeCount) {
154 1
            throw new Exceptions\TooManyLoopsException("Too many loops '{$safeCount}'");
155
        }
156 1
        if (\is_array($data)) {
157 1
            if (\count($data) === 0) {
158
                $data = '';
159
            } else {
160 1
                foreach ($data as $i => $v) {
161 1
                    $data[$i] = $this->escape($v, $safeCount);
162
                }
163
            }
164
        } else {
165 1
            $data = $this->getDriver()->escape($data);
166
        }
167
168 1
        return $data;
169
    }
170
171
    /**
172
     * @param mixed $sql
173
     * @return mixed
174
     * @throws Exceptions\Exception
175
     */
176 13
    public function query($sql)
177
    {
178 13
        $tStart = microtime(true);
179 13
        if (\is_array($sql)) {
180 1
            $sql = implode("\n", $sql);
181
        }
182 13
        $this->lastQuery = $sql;
183
184 13
        $result = $this->getDriver()->query($this->getLastQuery());
185
186 13
        if ($result === false) {
187
            $this->checkLastError($this->getLastQuery());
188
        } else {
189 13
            $tend = microtime(true);
190 13
            $totalTime = $tend - $tStart;
191 13
            $this->queryTime += $totalTime;
192 13
            if ($this->isDebug()) {
193 13
                $this->collectQuery(
194 13
                    $result,
195 13
                    $this->getLastQuery(),
196 13
                    $this->executedQueries + 1,
197 13
                    $totalTime
198
                );
199
            }
200 13
            $this->executedQueries++;
201
202 13
            return $result;
203
        }
204
        return false;
205
    }
206
207
    /**
208
     * @param string $table
209
     * @param array|string $where
210
     * @param string $orderBy
211
     * @param string $limit
212
     * @return mixed
213
     * @throws Exceptions\Exception
214
     */
215 1
    public function delete($table, $where = '', $orderBy = '', $limit = '')
216
    {
217 1
        $table = $this->prepareFrom($table);
218 1
        $where = $this->prepareWhere($where);
219 1
        $orderBy = $this->prepareOrder($orderBy);
220 1
        $limit = $this->prepareOrder($limit);
221
222 1
        return $this->query("DELETE FROM {$table} {$where} {$orderBy} {$limit}");
223
    }
224
225
    /**
226
     * @param array|string $fields
227
     * @param array|string $tables
228
     * @param array|string $where
229
     * @param string $orderBy
230
     * @param string $limit
231
     * @return mixed
232
     * @throws Exceptions\Exception
233
     */
234 3
    public function select($fields, $tables, $where = '', $orderBy = '', $limit = '')
235
    {
236 3
        $fields = $this->prepareFields($fields);
237 3
        $tables = $this->prepareFrom($tables, true);
238 3
        $where = $this->prepareWhere($where);
239 3
        $orderBy = $this->prepareOrder($orderBy);
240 3
        $limit = $this->prepareLimit($limit);
241
242 3
        return $this->query("SELECT {$fields} FROM {$tables} {$where} {$orderBy} {$limit}");
243
    }
244
245
    /**
246
     * @param array|string $values
247
     * @param string $table
248
     * @param array|string $where
249
     * @return mixed
250
     * @throws Exceptions\Exception
251
     */
252 2
    public function update($values, string $table, $where = '')
253
    {
254 2
        $table = $this->prepareFrom($table);
255 2
        $values = $this->prepareValuesSet($values);
256 2
        if (mb_strtoupper(mb_substr($values, 0, 4)) !== 'SET ') {
257 2
            $values = 'SET ' . $values;
258
        }
259 2
        $where = $this->prepareWhere($where);
260
261 2
        return $this->query("UPDATE {$table} {$values} {$where}");
262
    }
263
264
    /**
265
     * @param array|string $fields
266
     * @param string $table
267
     * @param array|string $fromFields
268
     * @param string $fromTable
269
     * @param array|string $where
270
     * @param string $limit
271
     * @return mixed
272
     * @throws Exceptions\Exception
273
     */
274 4
    public function insert(
275
        $fields,
276
        string $table,
277
        $fromFields = '*',
278
        string $fromTable = '',
279
        $where = '',
280
        string $limit = ''
281
    ) {
282 4
        $table = $this->prepareFrom($table);
283
284 4
        $useFields = null;
285 4
        $lid = null;
286
287 4
        if (\is_array($fields)) {
288 4
            $useFields = empty($fromTable) ?
289 3
                $this->prepareValues($fields) :
290 4
                $this->prepareFields($fields, true);
291
        } else {
292 2
            $useFields = $fields;
293
        }
294
295 4
        if (empty($useFields) || ! \is_scalar($useFields) || ($useFields === '*' && ! empty($fromTable))) {
296
            throw (new Exceptions\InvalidFieldException('Invalid insert fields'))
297
                ->setData($fields);
298
        }
299
300 4
        if (empty($fromTable)) {
301 3
            $this->query("INSERT INTO {$table} {$useFields}");
302
        } else {
303 1
            if (empty($fromFields) || $fromFields === '*') {
304 1
                $fromFields = $this->prepareFields($fields, true);
305
            } else {
306 1
                $fromFields = $this->prepareFields($fromFields, true);
307
            }
308
309 1
            $where = $this->prepareWhere($where);
310 1
            $limit = $this->prepareLimit($limit);
311
312 1
            $lid = $this->query(
313 1
                "INSERT INTO {$table} ({$useFields}) SELECT {$fromFields} FROM {$fromTable} {$where} {$limit}"
314
            );
315
        }
316
317 4
        if ($lid === null && ($lid = $this->getInsertId()) === false) {
318
            throw new Exceptions\GetDataException("Couldn't get last insert key!");
319
        }
320
321 4
        return $this->convertValue($lid);
322
    }
323
324
    /**
325
     * @param string|array $fields
326
     * @param string $table
327
     * @param array|string $where
328
     * @return mixed
329
     * @throws Exceptions\Exception
330
     */
331 1
    public function save($fields, string $table, $where = '')
332
    {
333 1
        if ($where === '') {
334 1
            $mode = 'insert';
335
        } else {
336 1
            $result = $this->select('*', $table, $where);
337
338 1
            if ($this->getRecordCount($result) === 0) {
339 1
                $mode = 'insert';
340
            } else {
341 1
                $mode = 'update';
342
            }
343
        }
344
345 1
        return ($mode === 'insert') ? $this->insert($fields, $table) : $this->update($fields, $table, $where);
346
    }
347
348
    /**
349
     * @param $result
350
     * @return bool
351
     */
352 1
    public function isResult($result) : bool
353
    {
354 1
        return $this->getDriver()->isResult($result);
355
    }
356
357
    /**
358
     * @param $result
359
     * @return int
360
     */
361 1
    public function numFields($result) : int
362
    {
363 1
        return $this->getDriver()->numFields($result);
364
    }
365
366
    /**
367
     * @param $result
368
     * @param int $col
369
     * @return string|null
370
     */
371 1
    public function fieldName($result, $col = 0) :? string
372
    {
373 1
        return $this->getDriver()->fieldName($result, $col);
374
    }
375
376
    /**
377
     * @param string $charset
378
     * @param string|null $method
379
     * @return bool
380
     * @throws Exceptions\Exception
381
     */
382
    public function setCharset(string $charset, $method = null) : bool
383
    {
384
        if ($method !== null) {
385
            $this->query($method . ' ' . $charset);
386
        }
387
388
        $tStart = microtime(true);
389
390
        $result = $this->getDriver()->setCharset($charset);
391
392
        $this->queryTime += microtime(true) - $tStart;
393
394
        return $result;
395
    }
396
397
    /**
398
     * @param string $name
399
     * @return bool
400
     * @throws Exceptions\Exception
401
     */
402
    public function selectDb(string $name) : bool
403
    {
404
        $tStart = microtime(true);
405
406
        $result = $this->getDriver()->selectDb($name);
407
408
        $this->queryTime += microtime(true) - $tStart;
409
410
        return $result;
411
    }
412
413
    /**
414
     * @param $result
415
     * @return int
416
     */
417 9
    public function getRecordCount($result) : int
418
    {
419 9
        return $this->getDriver()->getRecordCount($result);
420
    }
421
422
    /**
423
     * @param $result
424
     * @param string $mode
425
     * @return array|mixed|object|\stdClass
426
     * @throws Exceptions\Exception
427
     */
428 1
    public function getRow($result, $mode = 'assoc')
429
    {
430 1
        return $this->getDriver()->getRow($result, $mode);
431
    }
432
433
    /**
434
     * @param string string $name
435
     * @param mixed $result
436
     * @return array
437
     * @throws Exceptions\Exception
438
     */
439 3
    public function getColumn(string $name, $result) : array
440
    {
441 3
        if (\is_scalar($result)) {
442 2
            $result = $this->query($result);
443
        }
444
445 3
        return $this->getDriver()->getColumn($name, $result);
446
    }
447
448
    /**
449
     * @param mixed $result
450
     * @return array
451
     * @throws Exceptions\Exception
452
     */
453 1
    public function getColumnNames($result) : array
454
    {
455 1
        if (\is_scalar($result)) {
456
            $result = $this->query($result);
457
        }
458
459 1
        return $this->getDriver()->getColumnNames($result);
460
    }
461
462
    /**
463
     * @param mixed $result
464
     * @return bool|mixed
465
     * @throws Exceptions\Exception
466
     */
467 3
    public function getValue($result)
468
    {
469 3
        if (\is_scalar($result)) {
470 3
            $result = $this->query($result);
471
        }
472
473 3
        return $this->convertValue(
474 3
            $this->getDriver()->getValue($result)
475
        );
476
    }
477
478
    /**
479
     * @param string $table
480
     * @return array
481
     * @throws Exceptions\Exception
482
     */
483 1
    public function getTableMetaData(string $table) : array
484
    {
485 1
        $metadata = [];
486 1
        if (! empty($table)) {
487 1
            $sql = 'SHOW FIELDS FROM ' . $table;
488 1
            $result = $this->query($sql);
489 1
            $metadata = $this->getDriver()->getTableMetaData($result);
490
        }
491
492 1
        return $metadata;
493
    }
494
495
    /**
496
     * @param $result
497
     * @param bool $index
498
     * @return array
499
     * @throws Exceptions\Exception
500
     */
501 1
    public function makeArray($result, bool $index = false) : array
502
    {
503 1
        $rsArray = [];
504 1
        $iterator = 0;
505 1
        while ($row = $this->getRow($result)) {
506 1
            $returnIndex = $index !== false && isset($row[$index]) ? $row[$index] : $iterator;
507 1
            $rsArray[$returnIndex] = $row;
508 1
            $iterator++;
509
        }
510
511 1
        return $rsArray;
512
    }
513
514
    /**
515
     * @return string
516
     * @throws Exceptions\Exception
517
     */
518 1
    public function getVersion() : string
519
    {
520 1
        return $this->getDriver()->getVersion();
521
    }
522
523
    /**
524
     * @param string $table
525
     * @return mixed
526
     * @throws Exceptions\Exception
527
     */
528 1
    public function optimize(string $table)
529
    {
530 1
        $result = $this->query('OPTIMIZE TABLE ' . $table);
531 1
        if ($result !== false) {
532 1
            $result = $this->query('ALTER TABLE ' . $table);
533
        }
534
535 1
        return $result;
536
    }
537
538
    /**
539
     * @param string $table
540
     * @return mixed
541
     * @throws Exceptions\Exception
542
     */
543 1
    public function truncate(string $table)
544
    {
545 1
        return $this->query('TRUNCATE ' . $table);
546
    }
547
548
    /**
549
     * @return mixed
550
     * @throws Exceptions\Exception
551
     */
552 3
    public function getInsertId()
553
    {
554 3
        return $this->convertValue(
555 3
            $this->getDriver()->getInsertId()
556
        );
557
    }
558
559
    /**
560
     * @return int
561
     * @throws Exceptions\Exception
562
     */
563 7
    public function getAffectedRows() : int
564
    {
565 7
        return $this->getDriver()->getAffectedRows();
566
    }
567
}
568