DatabaseAddQueryTrait   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
wmc 16
eloc 53
c 2
b 1
f 0
dl 0
loc 125
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getKeysValues() 0 13 2
A generateAddQueryValuesPart() 0 13 3
A generateAddQueryUpdatePart() 0 14 3
A generateAddQuery() 0 20 2
A generateAddQueryPrefix() 0 16 4
A generateAddQueryFieldsPart() 0 7 1
A generateValuesString() 0 4 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace WebServCo\Framework\Traits;
6
7
use WebServCo\Framework\Database\QueryType;
8
use WebServCo\Framework\Helpers\ArrayHelper;
9
10
trait DatabaseAddQueryTrait
11
{
12
    abstract public function escapeIdentifier(string $string): string;
13
14
    abstract public function escapeTableName(string $string): string;
15
16
    /**
17
    * @param array<mixed> $addData
18
    * @param array<mixed> $updateData
19
    */
20
    final protected function generateAddQuery(
21
        string $queryType,
22
        string $tableName,
23
        array $addData = [],
24
        array $updateData = []
25
    ): string {
26
        $multiDimensional = ArrayHelper::isMultidimensional($addData);
27
28
        [$keys, $data] = $this->getKeysValues($addData);
29
30
        $query = $this->generateAddQueryPrefix($queryType);
31
        $query .= ' ' . $this->escapeTableName($tableName);
32
        $query .= $this->generateAddQueryFieldsPart($keys);
33
        $query .= $this->generateAddQueryValuesPart($data, $multiDimensional);
34
35
        if ($multiDimensional) {
36
            return $query;
37
        }
38
39
        return $query . $this->generateAddQueryUpdatePart($updateData);
40
    }
41
42
    /**
43
    * @param array<mixed> $data
44
    * @return array<mixed>
45
    */
46
    final protected function getKeysValues(array $data = []): array
47
    {
48
        $multiDimensional = ArrayHelper::isMultidimensional($data);
49
        if ($multiDimensional) {
50
            $keys = \array_keys(\call_user_func_array('array_merge', $data));
51
            // fill any missing keys with empty data
52
            $keyPair = \array_combine($keys, \array_fill(0, \count($keys), null));
53
            $data = \array_map(static fn ($e) => \array_merge((array) $keyPair, $e), $data);
54
        } else {
55
            $keys = \array_keys($data);
56
        }
57
58
        return [$keys, $data];
59
    }
60
61
    final protected function generateAddQueryPrefix(string $queryType): string
62
    {
63
        switch ($queryType) {
64
            case QueryType::REPLACE:
65
                $query = QueryType::REPLACE . ' INTO';
66
                break;
67
            case QueryType::INSERT_IGNORE:
68
                $query = QueryType::INSERT_IGNORE . ' INTO';
69
                break;
70
            case QueryType::INSERT:
71
            default:
72
                $query = QueryType::INSERT . ' INTO';
73
                break;
74
        }
75
76
        return $query;
77
    }
78
79
    /**
80
    * @param array<int,string> $fields
81
    */
82
    final protected function generateAddQueryFieldsPart(array $fields): string
83
    {
84
        return ' (' . \implode(
85
            ', ',
86
            \array_map([$this, 'escapeIdentifier'], $fields),
87
        ) .
88
        ')';
89
    }
90
91
    /**
92
    * @param array<mixed> $data
93
    */
94
    final protected function generateAddQueryValuesPart(array $data, bool $multiDimensional): string
95
    {
96
        $query = ' VALUES';
97
        if ($multiDimensional) {
98
            $valuesStrings = [];
99
            foreach ($data as $item) {
100
                $valuesStrings[] = $this->generateValuesString($item);
101
            }
102
            $query .= \implode(', ', $valuesStrings);
103
        } else {
104
            $query .= $this->generateValuesString($data);
105
        }
106
        return $query;
107
    }
108
109
    /**
110
    * @param array<mixed> $data
111
    */
112
    final protected function generateAddQueryUpdatePart(array $data = []): string
113
    {
114
        if (!$data) {
115
            return '';
116
        }
117
118
        $strings = [];
119
        foreach ($data as $k => $v) {
120
            $strings[] = \sprintf('%s = ?', $this->escapeIdentifier((string) $k));
121
        }
122
123
        $query = " ON DUPLICATE KEY UPDATE ";
124
        $query .= \implode(', ', $strings);
125
        return $query;
126
    }
127
128
    /**
129
    * @param array<int,float|int|string> $data
130
    */
131
    final protected function generateValuesString(array $data): string
132
    {
133
        $placeholdersString = \WebServCo\Framework\Database\Utils\PreparedStatements::generatePlaceholdersString($data);
134
        return ' (' . $placeholdersString . ')';
135
    }
136
}
137