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

Database::__construct()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 32
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 2

Importance

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