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