Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
58.18% |
32 / 55 |
|
50.00% |
3 / 6 |
CRAP | |
0.00% |
0 / 1 |
MysqlGrammar | |
58.18% |
32 / 55 |
|
50.00% |
3 / 6 |
66.12 | |
0.00% |
0 / 1 |
compilePostQueries | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
56 | |||
compileAlterRemove | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
compileSelectTables | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
compileSelectFields | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
compileCreateFields | |
90.91% |
20 / 22 |
|
0.00% |
0 / 1 |
12.11 | |||
compileCreateTableSettings | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | /** |
3 | * Jingga |
4 | * |
5 | * PHP Version 8.1 |
6 | * |
7 | * @package phpOMS\DataStorage\Database\Schema\Grammar |
8 | * @copyright Dennis Eichhorn |
9 | * @license OMS License 2.0 |
10 | * @version 1.0.0 |
11 | * @link https://jingga.app |
12 | */ |
13 | declare(strict_types=1); |
14 | |
15 | namespace phpOMS\DataStorage\Database\Schema\Grammar; |
16 | |
17 | use phpOMS\DataStorage\Database\BuilderAbstract; |
18 | use phpOMS\DataStorage\Database\Query\Builder; |
19 | use phpOMS\DataStorage\Database\Schema\Builder as SchemaBuilder; |
20 | use phpOMS\DataStorage\Database\Schema\QueryType; |
21 | |
22 | /** |
23 | * Database query grammar. |
24 | * |
25 | * @package phpOMS\DataStorage\Database\Schema\Grammar |
26 | * @license OMS License 2.0 |
27 | * @link https://jingga.app |
28 | * @since 1.0.0 |
29 | */ |
30 | class MysqlGrammar extends Grammar |
31 | { |
32 | /** |
33 | * System identifier. |
34 | * |
35 | * @var string |
36 | * @since 1.0.0 |
37 | */ |
38 | public string $systemIdentifierStart = '`'; |
39 | |
40 | /** |
41 | * System identifier. |
42 | * |
43 | * @var string |
44 | * @since 1.0.0 |
45 | */ |
46 | public string $systemIdentifierEnd = '`'; |
47 | |
48 | /** |
49 | * {@inheritdoc} |
50 | */ |
51 | public function compilePostQueries(BuilderAbstract $query) : array |
52 | { |
53 | /** @var SchemaBuilder $query */ |
54 | |
55 | $sql = []; |
56 | switch ($query->getType()) { |
57 | case QueryType::CREATE_TABLE: |
58 | foreach ($query->createFields as $name => $field) { |
59 | if (isset($field['meta']['multi_autoincrement'])) { |
60 | $tmpSql = 'CREATE TRIGGER update_' . $name |
61 | . ' BEFORE INSERT ON ' . $query->createTable |
62 | . ' FOR EACH ROW BEGIN' |
63 | . ' SET NEW.' . $name . ' = (' |
64 | . 'SELECT COALESCE(MAX(' . $name . '), 0) + 1' |
65 | . ' FROM ' . $query->createTable |
66 | . ' WHERE'; |
67 | |
68 | foreach ($field['meta']['multi_autoincrement'] as $index => $autoincrement) { |
69 | $tmpSql .= ($index > 0 ? ' AND' : '') . ' ' . $autoincrement . ' = NEW.' . $autoincrement; |
70 | } |
71 | |
72 | $tmpSql .= ' LIMIT 1); END;'; |
73 | |
74 | $sql[] = $tmpSql; |
75 | } |
76 | } |
77 | |
78 | break; |
79 | default: |
80 | return []; |
81 | } |
82 | |
83 | return $sql; |
84 | } |
85 | |
86 | /** |
87 | * Compile remove |
88 | * |
89 | * @param Builder $query Builder |
90 | * @param array $remove Remove data |
91 | * |
92 | * @return string |
93 | * |
94 | * @since 1.0.0 |
95 | */ |
96 | protected function compileAlterRemove(BuilderAbstract $query, array $remove) : string |
97 | { |
98 | $keyWord = $remove['type'] === 'CONSTRAINT' ? 'FOREIGN KEY ' : 'COLUMN'; |
99 | |
100 | return 'DROP ' . $keyWord . ' ' . $remove['identifier']; |
101 | } |
102 | |
103 | /** |
104 | * Compile from. |
105 | * |
106 | * @param SchemaBuilder $query Builder |
107 | * @param array $table Tables |
108 | * |
109 | * @return string |
110 | * |
111 | * @since 1.0.0 |
112 | */ |
113 | protected function compileSelectTables(SchemaBuilder $query, array $table) : string |
114 | { |
115 | $builder = new Builder($query->getConnection()); |
116 | $builder->select('table_name') |
117 | ->from('information_schema.tables') |
118 | ->where('table_schema', '=', $query->getConnection()->getDatabase()); |
119 | |
120 | return \rtrim($builder->toSql(), ';'); |
121 | } |
122 | |
123 | /** |
124 | * Compile from. |
125 | * |
126 | * @param SchemaBuilder $query Builder |
127 | * @param string $table Tables |
128 | * |
129 | * @return string |
130 | * |
131 | * @since 1.0.0 |
132 | */ |
133 | protected function compileSelectFields(SchemaBuilder $query, string $table) : string |
134 | { |
135 | $builder = new Builder($query->getConnection()); |
136 | $builder->select('*') |
137 | ->from('information_schema.columns') |
138 | ->where('table_schema', '=', $query->getConnection()->getDatabase()) |
139 | ->andWhere('table_name', '=', $table); |
140 | |
141 | return \rtrim($builder->toSql(), ';'); |
142 | } |
143 | |
144 | /** |
145 | * Compile create table fields query. |
146 | * |
147 | * @param SchemaBuilder $query Query |
148 | * @param array $fields Fields to create |
149 | * |
150 | * @return string |
151 | * |
152 | * @since 1.0.0 |
153 | */ |
154 | protected function compileCreateFields(SchemaBuilder $query, array $fields) : string |
155 | { |
156 | $fieldQuery = ''; |
157 | $keys = ''; |
158 | |
159 | foreach ($fields as $name => $field) { |
160 | $fieldQuery .= ' ' . $this->expressionizeTableColumn([$name]) . ' ' . $field['type']; |
161 | |
162 | if (isset($field['default']) || ($field['default'] === null && ($field['null'] ?? false))) { |
163 | $fieldQuery .= ' DEFAULT ' . $this->compileValue($query, $field['default']); |
164 | } |
165 | |
166 | if ($field['null'] ?? false) { |
167 | $fieldQuery .= ' ' . ($field['null'] ? '' : 'NOT ') . 'NULL'; |
168 | } |
169 | |
170 | if ($field['autoincrement'] ?? false) { |
171 | $fieldQuery .= ' AUTO_INCREMENT'; |
172 | } |
173 | |
174 | $fieldQuery .= ','; |
175 | |
176 | if ($field['primary'] ?? false) { |
177 | $keys .= ' PRIMARY KEY (' . $this->expressionizeTableColumn([$name]) . '),'; |
178 | } |
179 | |
180 | if ($field['unique'] ?? false) { |
181 | $keys .= ' UNIQUE KEY (' . $this->expressionizeTableColumn([$name]) . '),'; |
182 | } |
183 | |
184 | if (isset($field['foreignTable'], $field['foreignKey'])) { |
185 | $keys .= ' FOREIGN KEY (' . $this->expressionizeTableColumn([$name]) . ') REFERENCES ' |
186 | . $this->expressionizeTableColumn([$field['foreignTable']]) |
187 | . ' (' . $this->expressionizeTableColumn([$field['foreignKey']]) . '),'; |
188 | } |
189 | |
190 | if (isset($field['meta']['multi_autoincrement'])) { |
191 | $query->hasPostQuery = true; |
192 | } |
193 | } |
194 | |
195 | return '(' . \ltrim(\rtrim($fieldQuery . $keys, ','), ' ') . ')'; |
196 | } |
197 | |
198 | /** |
199 | * Compile create table settings query. |
200 | * |
201 | * @param BuilderAbstract $query Query |
202 | * @param bool $settings Has settings |
203 | * |
204 | * @return string |
205 | * |
206 | * @since 1.0.0 |
207 | */ |
208 | protected function compileCreateTableSettings(BuilderAbstract $query, bool $settings) : string |
209 | { |
210 | return 'ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1'; |
211 | } |
212 | } |