TYPO3 CMS  TYPO3_7-6
Mysql.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
18 
22 class Mysql extends AbstractCompiler
23 {
31  protected function compileINSERT($components)
32  {
33  $values = [];
34  if (isset($components['VALUES_ONLY']) && is_array($components['VALUES_ONLY'])) {
35  $valuesComponents = $components['EXTENDED'] === '1' ? $components['VALUES_ONLY'] : [$components['VALUES_ONLY']];
36  $tableFields = [];
37  } else {
38  $valuesComponents = $components['EXTENDED'] === '1' ? $components['FIELDS'] : [$components['FIELDS']];
39  $tableFields = array_keys($valuesComponents[0]);
40  }
41  foreach ($valuesComponents as $valuesComponent) {
42  $fields = [];
43  foreach ($valuesComponent as $fV) {
44  $fields[] = $fV[1] . $this->compileAddslashes($fV[0]) . $fV[1];
45  }
46  $values[] = '(' . implode(',', $fields) . ')';
47  }
48  // Make query:
49  $query = 'INSERT INTO ' . $components['TABLE'];
50  if (!empty($tableFields)) {
51  $query .= ' (' . implode(',', $tableFields) . ')';
52  }
53  $query .= ' VALUES ' . implode(',', $values);
54 
55  return $query;
56  }
57 
65  protected function compileCREATETABLE($components)
66  {
67  // Create fields and keys:
68  $fieldsKeys = [];
69  foreach ($components['FIELDS'] as $fN => $fCfg) {
70  $fieldsKeys[] = $fN . ' ' . $this->compileFieldCfg($fCfg['definition']);
71  }
72  if ($components['KEYS']) {
73  foreach ($components['KEYS'] as $kN => $kCfg) {
74  if ($kN === 'PRIMARYKEY') {
75  $fieldsKeys[] = 'PRIMARY KEY (' . implode(',', $kCfg) . ')';
76  } elseif ($kN === 'UNIQUE') {
77  $key = key($kCfg);
78  $fields = current($kCfg);
79  $fieldsKeys[] = 'UNIQUE KEY ' . $key . ' (' . implode(',', $fields) . ')';
80  } else {
81  $fieldsKeys[] = 'KEY ' . $kN . ' (' . implode(',', $kCfg) . ')';
82  }
83  }
84  }
85  // Make query:
86  $query = 'CREATE TABLE ' . $components['TABLE'] . ' (' .
87  implode(',', $fieldsKeys) . ')' .
88  ($components['engine'] ? ' ENGINE=' . $components['engine'] : '');
89 
90  return $query;
91  }
92 
100  protected function compileALTERTABLE($components)
101  {
102  // Make query:
103  $query = 'ALTER TABLE ' . $components['TABLE'] . ' ' . $components['action'] . ' ' . ($components['FIELD'] ?: $components['KEY']);
104  // Based on action, add the final part:
105  switch (SqlParser::normalizeKeyword($components['action'])) {
106  case 'ADD':
107  $query .= ' ' . $this->compileFieldCfg($components['definition']);
108  break;
109  case 'CHANGE':
110  $query .= ' ' . $components['newField'] . ' ' . $this->compileFieldCfg($components['definition']);
111  break;
112  case 'DROP':
113  case 'DROPKEY':
114  break;
115  case 'ADDKEY':
116  case 'ADDPRIMARYKEY':
117  case 'ADDUNIQUE':
118  $query .= ' (' . implode(',', $components['fields']) . ')';
119  break;
120  case 'DEFAULTCHARACTERSET':
121  $query .= $components['charset'];
122  break;
123  case 'ENGINE':
124  $query .= '= ' . $components['engine'];
125  break;
126  }
127  // Return query
128  return $query;
129  }
130 
141  public function compileFieldList($selectFields, $compileComments = true, $functionMapping = true)
142  {
143  // Prepare buffer variable:
144  $fields = '';
145  // Traverse the selectFields if any:
146  if (is_array($selectFields)) {
147  $outputParts = [];
148  foreach ($selectFields as $k => $v) {
149  // Detecting type:
150  switch ($v['type']) {
151  case 'function':
152  $outputParts[$k] = $v['function'] . '(' . $v['func_content'] . ')';
153  break;
154  case 'flow-control':
155  if ($v['flow-control']['type'] === 'CASE') {
156  $outputParts[$k] = $this->compileCaseStatement($v['flow-control']);
157  }
158  break;
159  case 'field':
160  $outputParts[$k] = ($v['distinct'] ? $v['distinct'] : '') . ($v['table'] ? $v['table'] . '.' : '') . $v['field'];
161  break;
162  }
163  // Alias:
164  if ($v['as']) {
165  $outputParts[$k] .= ' ' . $v['as_keyword'] . ' ' . $v['as'];
166  }
167  // Specifically for ORDER BY and GROUP BY field lists:
168  if ($v['sortDir']) {
169  $outputParts[$k] .= ' ' . $v['sortDir'];
170  }
171  }
172  if ($compileComments && $selectFields[0]['comments']) {
173  $fields = $selectFields[0]['comments'] . ' ';
174  }
175  $fields .= implode(', ', $outputParts);
176  }
177  return $fields;
178  }
179 
188  protected function compileAddslashes($str)
189  {
190  $search = ['\\', '\'', '"', "\x00", "\x0a", "\x0d", "\x1a"];
191  $replace = ['\\\\', '\\\'', '\\"', '\0', '\n', '\r', '\Z'];
192 
193  return str_replace($search, $replace, $str);
194  }
195 
202  public function compileFieldCfg($fieldCfg)
203  {
204  // Set type:
205  $cfg = $fieldCfg['fieldType'];
206  // Add value, if any:
207  if ((string)$fieldCfg['value'] !== '') {
208  $cfg .= '(' . $fieldCfg['value'] . ')';
209  }
210  // Add additional features:
211  if (is_array($fieldCfg['featureIndex'])) {
212  foreach ($fieldCfg['featureIndex'] as $featureDef) {
213  $cfg .= ' ' . $featureDef['keyword'];
214  // Add value if found:
215  if (is_array($featureDef['value'])) {
216  $cfg .= ' ' . $featureDef['value'][1] . $this->compileAddslashes($featureDef['value'][0]) . $featureDef['value'][1];
217  }
218  }
219  }
220  // Return field definition string:
221  return $cfg;
222  }
223 
232  public function compileWhereClause($clauseArray, $functionMapping = true)
233  {
234  // Prepare buffer variable:
235  $output = '';
236  // Traverse clause array:
237  if (is_array($clauseArray)) {
238  foreach ($clauseArray as $k => $v) {
239  // Set operator:
240  $output .= $v['operator'] ? ' ' . $v['operator'] : '';
241  // Look for sublevel:
242  if (is_array($v['sub'])) {
243  $output .= ' (' . trim($this->compileWhereClause($v['sub'])) . ')';
244  } elseif (isset($v['func']) && $v['func']['type'] === 'EXISTS') {
245  $output .= ' ' . trim($v['modifier']) . ' EXISTS (' . $this->compileSELECT($v['func']['subquery']) . ')';
246  } else {
247  if (isset($v['func']) && $v['func']['type'] === 'LOCATE') {
248  $output .= ' ' . trim($v['modifier']) . ' LOCATE(';
249  $output .= $v['func']['substr'][1] . $v['func']['substr'][0] . $v['func']['substr'][1];
250  $output .= ', ' . ($v['func']['table'] ? $v['func']['table'] . '.' : '') . $v['func']['field'];
251  $output .= isset($v['func']['pos']) ? ', ' . $v['func']['pos'][0] : '';
252  $output .= ')';
253  } elseif (isset($v['func']) && $v['func']['type'] === 'IFNULL') {
254  $output .= ' ' . trim($v['modifier']) . ' IFNULL(';
255  $output .= ($v['func']['table'] ? $v['func']['table'] . '.' : '') . $v['func']['field'];
256  $output .= ', ' . $v['func']['default'][1] . $this->compileAddslashes($v['func']['default'][0]) . $v['func']['default'][1];
257  $output .= ')';
258  } elseif (isset($v['func']) && $v['func']['type'] === 'CAST') {
259  $output .= ' ' . trim($v['modifier']) . ' CAST(';
260  $output .= ($v['func']['table'] ? $v['func']['table'] . '.' : '') . $v['func']['field'];
261  $output .= ' AS ' . $v['func']['datatype'][0];
262  $output .= ')';
263  } elseif (isset($v['func']) && $v['func']['type'] === 'FIND_IN_SET') {
264  $output .= ' ' . trim($v['modifier']) . ' FIND_IN_SET(';
265  $output .= $v['func']['str'][1] . $v['func']['str'][0] . $v['func']['str'][1];
266  $output .= ', ' . ($v['func']['table'] ? $v['func']['table'] . '.' : '') . $v['func']['field'];
267  $output .= ')';
268  } else {
269  // Set field/table with modifying prefix if any:
270  $output .= ' ' . trim($v['modifier'] . ' ' . ($v['table'] ? $v['table'] . '.' : '') . $v['field']);
271  // Set calculation, if any:
272  if ($v['calc']) {
273  $output .= $v['calc'] . $v['calc_value'][1] . $this->compileAddslashes($v['calc_value'][0]) . $v['calc_value'][1];
274  }
275  }
276  // Set comparator:
277  if ($v['comparator']) {
278  $output .= ' ' . $v['comparator'];
279  // Detecting value type; list or plain:
280  $comparator = SqlParser::normalizeKeyword($v['comparator']);
281  if ($comparator === 'NOTIN' || $comparator === 'IN') {
282  if (isset($v['subquery'])) {
283  $output .= ' (' . $this->compileSELECT($v['subquery']) . ')';
284  } else {
285  $valueBuffer = [];
286  foreach ($v['value'] as $realValue) {
287  $valueBuffer[] = $realValue[1] . $this->compileAddslashes($realValue[0]) . $realValue[1];
288  }
289  $output .= ' (' . trim(implode(',', $valueBuffer)) . ')';
290  }
291  } elseif ($comparator === 'BETWEEN' || $comparator === 'NOTBETWEEN') {
292  $lbound = $v['values'][0];
293  $ubound = $v['values'][1];
294  $output .= ' ' . $lbound[1] . $this->compileAddslashes($lbound[0]) . $lbound[1];
295  $output .= ' AND ';
296  $output .= $ubound[1] . $this->compileAddslashes($ubound[0]) . $ubound[1];
297  } else {
298  if (isset($v['value']['operator'])) {
299  $values = [];
300  foreach ($v['value']['args'] as $fieldDef) {
301  $values[] = ($fieldDef['table'] ? $fieldDef['table'] . '.' : '') . $fieldDef['field'];
302  }
303  $output .= ' ' . $v['value']['operator'] . '(' . implode(',', $values) . ')';
304  } else {
305  $output .= ' ' . $v['value'][1] . $this->compileAddslashes($v['value'][0]) . $v['value'][1];
306  }
307  }
308  }
309  }
310  }
311  }
312  // Return output buffer:
313  return $output;
314  }
315 }
compileFieldList($selectFields, $compileComments=true, $functionMapping=true)
Definition: Mysql.php:141
compileCaseStatement(array $components, $functionMapping=true)
compileWhereClause($clauseArray, $functionMapping=true)
Definition: Mysql.php:232