Completed
Push — master ( e07415...43827d )
by Agel_Nash
02:21
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 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 1
            throw new Exceptions\DriverException(
58 1
                $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 Interfaces\DriverInterface
89
     * @throws Exceptions\Exception
90
     */
91 20
    public function getDriver() : Interfaces\DriverInterface
92
    {
93 20
        return $this->driver;
94
    }
95
96
    /**
97
     * @return mixed
98
     * @throws Exceptions\Exception
99
     */
100 19
    public function connect()
101
    {
102 19
        $tStart = microtime(true);
103
104 19
        $out = $this->getDriver()->connect();
105
106 18
        $totalTime = microtime(true) - $tStart;
107 18
        if ($this->isDebug()) {
108 18
            $this->connectionTime = $totalTime;
109
        }
110
111 18
        $this->setCharset($this->getConfig('charset'), $this->getConfig('method'));
112
113 18
        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 18
    public function query($sql)
162
    {
163 18
        $tStart = microtime(true);
164 18
        if (\is_array($sql)) {
165 1
            $sql = implode("\n", $sql);
166
        }
167 18
        $this->lastQuery = $sql;
168
169 18
        $result = $this->getDriver()->query($this->getLastQuery());
170
171 18
        if ($result === false) {
172
            $this->checkLastError($this->getLastQuery());
173
        } else {
174 18
            $tend = microtime(true);
175 18
            $totalTime = $tend - $tStart;
176 18
            $this->queryTime += $totalTime;
177 18
            if ($this->isDebug()) {
178 18
                $this->collectQuery(
179 18
                    $result,
180 18
                    $this->getLastQuery(),
181 18
                    $this->executedQueries + 1,
182 18
                    $totalTime
183
                );
184
            }
185 18
            $this->executedQueries++;
186
187 18
            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 18
    public function setCharset(string $charset, $method = null) : bool
368
    {
369 18
        if ($method !== null) {
370 18
            $this->query($method . ' ' . $charset);
371
        }
372
373 18
        $tStart = microtime(true);
374
375 18
        $result = $this->getDriver()->setCharset($charset);
376
377 18
        $this->queryTime += microtime(true) - $tStart;
378
379 18
        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 9
    public function getRecordCount($result) : int
403
    {
404 9
        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 1
    public function getRow($result, $mode = 'assoc')
414
    {
415 1
        return $this->getDriver()->getRow($result, $mode);
416
    }
417
418
    /**
419
     * @param string string $name
420
     * @param mixed $result
421
     * @return array
422
     * @throws Exceptions\Exception
423
     */
424 3
    public function getColumn(string $name, $result) : array
425
    {
426 3
        if (\is_scalar($result)) {
427 2
            $result = $this->query($result);
428
        }
429
430 3
        return $this->getDriver()->getColumn($name, $result);
431
    }
432
433
    /**
434
     * @param mixed $result
435
     * @return array
436
     * @throws Exceptions\Exception
437
     */
438 1
    public function getColumnNames($result) : array
439
    {
440 1
        if (\is_scalar($result)) {
441
            $result = $this->query($result);
442
        }
443
444 1
        return $this->getDriver()->getColumnNames($result);
445
    }
446
447
    /**
448
     * @param mixed $result
449
     * @return bool|mixed
450
     * @throws Exceptions\Exception
451
     */
452 3
    public function getValue($result)
453
    {
454 3
        if (\is_scalar($result)) {
455 3
            $result = $this->query($result);
456
        }
457
458 3
        return $this->convertValue(
459 3
            $this->getDriver()->getValue($result)
460
        );
461
    }
462
463
    /**
464
     * @param string $table
465
     * @return array
466
     * @throws Exceptions\Exception
467
     */
468 1
    public function getTableMetaData(string $table) : array
469
    {
470 1
        $metadata = [];
471 1
        if (! empty($table)) {
472 1
            $sql = 'SHOW FIELDS FROM ' . $table;
473 1
            $result = $this->query($sql);
474 1
            $metadata = $this->getDriver()->getTableMetaData($result);
475
        }
476
477 1
        return $metadata;
478
    }
479
480
    /**
481
     * @param $result
482
     * @param bool $index
483
     * @return array
484
     * @throws Exceptions\Exception
485
     */
486 1
    public function makeArray($result, bool $index = false) : array
487
    {
488 1
        $rsArray = [];
489 1
        $iterator = 0;
490 1
        while ($row = $this->getRow($result)) {
491 1
            $returnIndex = $index !== false && isset($row[$index]) ? $row[$index] : $iterator;
492 1
            $rsArray[$returnIndex] = $row;
493 1
            $iterator++;
494
        }
495
496 1
        return $rsArray;
497
    }
498
499
    /**
500
     * @return string
501
     * @throws Exceptions\Exception
502
     */
503 1
    public function getVersion() : string
504
    {
505 1
        return $this->getDriver()->getVersion();
506
    }
507
508
    /**
509
     * @param string $table
510
     * @return mixed
511
     * @throws Exceptions\Exception
512
     */
513 1
    public function optimize(string $table)
514
    {
515 1
        $result = $this->query('OPTIMIZE TABLE ' . $table);
516 1
        if ($result !== false) {
517 1
            $result = $this->query('ALTER TABLE ' . $table);
518
        }
519
520 1
        return $result;
521
    }
522
523
    /**
524
     * @param string $table
525
     * @return mixed
526
     * @throws Exceptions\Exception
527
     */
528 1
    public function truncate(string $table)
529
    {
530 1
        return $this->query('TRUNCATE ' . $table);
531
    }
532
533
    /**
534
     * @return mixed
535
     * @throws Exceptions\Exception
536
     */
537 3
    public function getInsertId()
538
    {
539 3
        return $this->convertValue(
540 3
            $this->getDriver()->getInsertId()
541
        );
542
    }
543
544
    /**
545
     * @return int
546
     * @throws Exceptions\Exception
547
     */
548 18
    public function getAffectedRows() : int
549
    {
550 18
        return $this->getDriver()->getAffectedRows();
551
    }
552
}
553