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

Database::__construct()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 30
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 2

Importance

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