Passed
Push — main ( f01a67...ddbd64 )
by Peter
02:42
created

Insert::addValues()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 4
nc 2
nop 1
dl 0
loc 9
rs 10
c 1
b 0
f 0
ccs 5
cts 5
cp 1
crap 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace QB\Generic\Statement;
6
7
use QB\Generic\Clause\Table;
8
9
class Insert implements IInsert
10
{
11
    /** @var array<int,string|Table> */
12
    protected array $tables = [];
13
14
    /** @var string[] */
15
    protected array $modifiers = [];
16
17
    /** @var array<int|string,string> */
18
    protected array $columns = [];
19
20
    /** @var array<int,mixed> */
21
    protected array $values = [];
22
23
    /**
24
     * @param string|Table $table
25
     *
26
     * @return $this
27
     */
28 28
    public function setInto(string|Table $table): static
29
    {
30 28
        $this->tables = [$table];
31
32 28
        return $this;
33
    }
34
35
    /**
36
     * @param string ...$modifiers
37
     *
38
     * @return $this
39
     */
40 1
    public function addModifier(string ...$modifiers): static
41
    {
42 1
        $this->modifiers = array_merge($this->modifiers, $modifiers);
43
44 1
        return $this;
45
    }
46
47
    /**
48
     * @param string ...$columns
49
     *
50
     * @return $this
51
     */
52 17
    public function setColumns(string ...$columns): static
53
    {
54 17
        if (count($this->values) > 0 && count($columns) !== count($this->values[0])) {
55 3
            throw new \InvalidArgumentException('number of columns does not match the number of values');
56
        }
57
58 14
        $this->columns = $columns;
59
60 14
        return $this;
61
    }
62
63
    /**
64
     * @param mixed ...$values
65
     *
66
     * @return $this
67
     */
68 24
    public function addValues(...$values): static
69
    {
70 24
        if (count($this->columns) > 0 && count($values) !== count($this->columns)) {
71 3
            throw new \InvalidArgumentException('number of values does not match the number of columns');
72
        }
73
74 21
        $this->values[] = $values;
75
76 21
        return $this;
77
    }
78
79
    /**
80
     * @return string
81
     */
82 17
    public function __toString(): string
83
    {
84 17
        if (!$this->isValid()) {
85 3
            throw new \RuntimeException('under-initialized INSERT query');
86
        }
87
88 14
        $sqlParts = array_merge(
89 14
            [$this->getCommand()],
90 14
            $this->values(),
91
        );
92
93 14
        $sqlParts = array_filter($sqlParts);
94
95 14
        return implode(PHP_EOL, $sqlParts);
96
    }
97
98
    /**
99
     * @return bool
100
     */
101 5
    public function isValid(): bool
102
    {
103 5
        return count($this->tables) === 1 && count($this->values) > 0;
104
    }
105
106 14
    protected function getCommand(): string
107
    {
108 14
        $sql = [];
109 14
        $sql[] = 'INSERT';
110 14
        $sql[] = $this->getModifiers();
111 14
        $sql[] = 'INTO';
112 14
        $sql[] = $this->tables[0];
113
114 14
        $sql = array_filter($sql);
115
116 14
        $sql = implode(' ', $sql);
117
118 14
        if (count($this->columns) === 0) {
119 9
            return $sql;
120
        }
121
122 5
        return $sql . ' (' . implode(', ', $this->columns) . ')';
123
    }
124
125 14
    protected function getModifiers(): string
126
    {
127 14
        if (empty($this->modifiers)) {
128 11
            return '';
129
        }
130
131 3
        return implode(' ', $this->modifiers);
132
    }
133
134 12
    protected function values(): array
135
    {
136 12
        $columnCount = count($this->columns) > 0 ? count($this->columns) : count($this->values[0]);
137
138 12
        $values = array_fill(0, $columnCount, '?');
139
140 12
        $row = sprintf('(%s)', implode(', ', $values));
141
142 12
        $rows = array_fill(0, count($this->values), $row);
143
144 12
        return ['VALUES ' . implode(",\n", $rows)];
145
    }
146
147
    /**
148
     * @return array
149
     */
150 3
    public function getParams(): array
151
    {
152 3
        $params = [];
153
154 3
        foreach ($this->values as $values) {
155 3
            foreach ($values as $value) {
156 3
                $params[] = [$value, \PDO::PARAM_STR];
157
            }
158
        }
159
160 3
        return $params;
161
    }
162
163
    /**
164
     * @return array
165
     */
166 3
    public function getValues(): array
167
    {
168 3
        return array_merge(...$this->values);
169
    }
170
}
171