Passed
Push — main ( 4b03c8...85c7ac )
by Peter
02:31
created

Insert::addModifier()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
rs 10
c 1
b 0
f 0
ccs 3
cts 3
cp 1
crap 1
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 14
    public function setInto(string|Table $table): static
29
    {
30 14
        $this->tables = [$table];
31
32 14
        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 5
    public function addColumns(string ...$columns): static
53
    {
54 5
        $this->columns = array_merge($this->columns, $columns);
55
56 5
        return $this;
57
    }
58
59
    /**
60
     * @param mixed ...$values
61
     *
62
     * @return $this
63
     */
64 12
    public function addValues(...$values): static
65
    {
66 12
        if (count($this->columns) && count($values) !== count($this->columns)) {
67
            throw new \InvalidArgumentException('number of values does not match the number of columns');
68
        }
69
70 12
        $this->values[] = $values;
71
72 12
        return $this;
73
    }
74
75
    /**
76
     * @return string
77
     */
78 14
    public function __toString(): string
79
    {
80 14
        if (!$this->isValid()) {
81
            throw new \RuntimeException('under-initialized INSERT query');
82
        }
83
84 14
        $insert = $this->insert();
85
86 14
        $sqlParts = array_merge(
87 14
            [$insert],
88 14
            $this->values(),
89
        );
90
91 14
        $sqlParts = array_filter($sqlParts);
92
93 14
        return implode(PHP_EOL, $sqlParts);
94
    }
95
96 4
    public function isValid(): bool
97
    {
98 4
        return count($this->tables) === 1 && count($this->values) > 0;
99
    }
100
101 14
    protected function insert(): string
102
    {
103 14
        $sql = [];
104 14
        $sql[] = 'INSERT';
105 14
        $sql[] = $this->getModifiers();
106 14
        $sql[] = 'INTO';
107 14
        $sql[] = $this->tables[0];
108
109 14
        $sql = array_filter($sql);
110
111 14
        $sql = implode(' ', $sql);
112
113 14
        if (count($this->columns) === 0) {
114 9
            return $sql;
115
        }
116
117 5
        return $sql . ' (' . implode(', ', $this->columns) . ')';
118
    }
119
120 14
    protected function getModifiers(): string
121
    {
122 14
        if (empty($this->modifiers)) {
123 11
            return '';
124
        }
125
126 3
        return implode(' ', $this->modifiers);
127
    }
128
129 12
    protected function values(): array
130
    {
131 12
        $columnCount = count($this->columns) > 0 ? count($this->columns) : count($this->values[0]);
132
133 12
        $values = array_fill(0, $columnCount, '?');
134
135 12
        $row = sprintf('(%s)', implode(', ', $values));
136
137 12
        $rows = array_fill(0, count($this->values), $row);
138
139 12
        return ['VALUES ' . implode(",\n", $rows)];
140
    }
141
142
    /**
143
     * @return array
144
     */
145
    public function getParams(): array
146
    {
147
        $params = [];
148
149
        foreach ($this->values as $values) {
150
            foreach ($values as $value) {
151
                $params[] = [$value, \PDO::PARAM_STR];
152
            }
153
        }
154
155
        return $params;
156
    }
157
158
    /**
159
     * @return array
160
     */
161
    public function getValues(): array
162
    {
163
        return array_merge(...$this->values);
164
    }
165
}
166