[BUGFIX] dbal: Cast field to CHAR for FIND_IN_SET()
[Packages/TYPO3.CMS.git] / typo3 / sysext / dbal / Classes / Database / Specifics / AbstractSpecifics.php
1 <?php
2 namespace TYPO3\CMS\Dbal\Database\Specifics;
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
17 /**
18 * This class handles the specifics of the active DBMS. Inheriting classes
19 * are intended to define their own specifics.
20 */
21 abstract class AbstractSpecifics {
22 /**
23 * Constants used as identifiers in $specificProperties.
24 */
25 const TABLE_MAXLENGTH = 'table_maxlength';
26 const FIELD_MAXLENGTH = 'field_maxlength';
27 const LIST_MAXEXPRESSIONS = 'list_maxexpressions';
28 const PARTIAL_STRING_INDEX = 'partial_string_index';
29 const CAST_FIND_IN_SET = 'cast_find_in_set';
30
31 /**
32 * Contains the specifics of a DBMS.
33 * This is intended to be overridden by inheriting classes.
34 *
35 * @var array
36 */
37 protected $specificProperties = array();
38
39 /**
40 * Contains the DBMS specific mapping information for native MySQL to ADOdb meta field types
41 *
42 * @var array
43 */
44 protected $nativeToMetaFieldTypeMap = array(
45 'STRING' => 'C',
46 'CHAR' => 'C',
47 'VARCHAR' => 'C',
48 'TINYBLOB' => 'C',
49 'TINYTEXT' => 'C',
50 'ENUM' => 'C',
51 'SET' => 'C',
52 'TEXT' => 'XL',
53 'LONGTEXT' => 'XL',
54 'MEDIUMTEXT' => 'XL',
55 'IMAGE' => 'B',
56 'LONGBLOB' => 'B',
57 'BLOB' => 'B',
58 'MEDIUMBLOB' => 'B',
59 'YEAR' => 'D',
60 'DATE' => 'D',
61 'TIME' => 'T',
62 'DATETIME' => 'T',
63 'TIMESTAMP' => 'T',
64 'FLOAT' => 'F',
65 'DOUBLE' => 'F',
66 'INT' => 'I8',
67 'INTEGER' => 'I8',
68 'TINYINT' => 'I8',
69 'SMALLINT' => 'I8',
70 'MEDIUMINT' => 'I8',
71 'BIGINT' => 'I8',
72 );
73
74 /**
75 * Contains the DBMS specific mapping overrides for native MySQL to ADOdb meta field types
76 */
77 protected $nativeToMetaFieldTypeOverrides = array();
78
79 /**
80 * Contains the default mapping information for ADOdb meta to MySQL native field types
81 *
82 * @var array
83 */
84 protected $metaToNativeFieldTypeMap = array(
85 'C' => 'VARCHAR',
86 'C2' => 'VARCHAR',
87 'X' => 'LONGTEXT',
88 'XL' => 'LONGTEXT',
89 'X2' => 'LONGTEXT',
90 'B' => 'LONGBLOB',
91 'D' => 'DATE',
92 'T' => 'DATETIME',
93 'L' => 'TINYINT',
94 'I' => 'BIGINT',
95 'I1' => 'BIGINT',
96 'I2' => 'BIGINT',
97 'I4' => 'BIGINT',
98 'I8' => 'BIGINT',
99 'F' => 'DOUBLE',
100 'N' => 'NUMERIC'
101 );
102
103 /**
104 * Contains the DBMS specific mapping information for ADOdb meta field types to MySQL native field types
105 *
106 * @var array
107 */
108 protected $metaToNativeFieldTypeOverrides = array();
109
110 /**
111 * Constructor
112 */
113 public function __construct() {
114 $this->nativeToMetaFieldTypeMap = array_merge($this->nativeToMetaFieldTypeMap, $this->nativeToMetaFieldTypeOverrides);
115 $this->metaToNativeFieldTypeMap = array_merge($this->metaToNativeFieldTypeMap, $this->metaToNativeFieldTypeOverrides);
116 }
117
118 /**
119 * Checks if a specific is defined for the used DBMS.
120 *
121 * @param string $specific
122 * @return bool
123 */
124 public function specificExists($specific) {
125 return isset($this->specificProperties[$specific]);
126 }
127
128 /**
129 * Gets the specific value.
130 *
131 * @param string $specific
132 * @return mixed
133 */
134 public function getSpecific($specific) {
135 return $this->specificProperties[$specific];
136 }
137
138 /**
139 * Splits $expressionList into multiple chunks.
140 *
141 * @param array $expressionList
142 * @param bool $preserveArrayKeys If TRUE, array keys are preserved in array_chunk()
143 * @return array
144 */
145 public function splitMaxExpressions($expressionList, $preserveArrayKeys = FALSE) {
146 if (!$this->specificExists(self::LIST_MAXEXPRESSIONS)) {
147 return array($expressionList);
148 }
149
150 return array_chunk($expressionList, $this->getSpecific(self::LIST_MAXEXPRESSIONS), $preserveArrayKeys);
151 }
152
153 /**
154 * Adjust query parts for DBMS
155 *
156 * @param string $select_fields
157 * @param string $from_table
158 * @param string $where_clause
159 * @param string $groupBy
160 * @param string $orderBy
161 * @param string $limit
162 * @return void
163 */
164 public function transformQueryParts(&$select_fields, &$from_table, &$where_clause, &$groupBy = '', &$orderBy = '', &$limit = '') {}
165
166 /**
167 * Transforms a database specific representation of field information and translates it
168 * as close as possible to the MySQL standard.
169 *
170 * @param array $fieldRow
171 * @param string $metaType
172 * @return array
173 */
174 public function transformFieldRowToMySQL($fieldRow, $metaType) {
175 $mysqlType = $this->getNativeFieldType($metaType);
176 $mysqlType .= $this->getNativeFieldLength($mysqlType, $fieldRow['max_length']);
177
178 $fieldRow['Field'] = $fieldRow['name'];
179 $fieldRow['Type'] = strtolower($mysqlType);
180 $fieldRow['Null'] = $this->getNativeNotNull($fieldRow['not_null']);
181 $fieldRow['Key'] = $this->getNativeKeyForField($fieldRow);
182 $fieldRow['Default'] = $this->getNativeDefaultValue($fieldRow);
183 $fieldRow['Extra'] = $this->getNativeExtraFieldAttributes($fieldRow);
184
185 return $fieldRow;
186 }
187
188 /**
189 * Return actual MySQL type for meta field type
190 *
191 * @param string $metaType Meta type (currenly ADOdb syntax only, http://phplens.com/lens/adodb/docs-adodb.htm#metatype)
192 * @return string Native type as reported as in mysqldump files, uppercase
193 */
194 public function getNativeFieldType($metaType) {
195 $metaType = strtoupper($metaType);
196 return empty($this->metaToNativeFieldTypeMap[$metaType]) ? $metaType : $this->metaToNativeFieldTypeMap[$metaType];
197 }
198
199 /**
200 * Return MetaType for native MySQL field type
201 *
202 * @param string $nativeType native type as reported as in mysqldump files
203 * @return string Meta type (currently ADOdb syntax only, http://phplens.com/lens/adodb/docs-adodb.htm#metatype)
204 */
205 public function getMetaFieldType($nativeType) {
206 $nativeType = strtoupper($nativeType);
207 return empty($this->nativeToMetaFieldTypeMap[$nativeType]) ? 'N' : $this->nativeToMetaFieldTypeMap[$nativeType];
208 }
209
210 /**
211 * Determine the native field length information for a table field.
212 *
213 * @param string $mysqlType
214 * @param int $maxLength
215 * @return string
216 */
217 public function getNativeFieldLength($mysqlType, $maxLength) {
218 if ($maxLength === -1) {
219 return '';
220 }
221 switch ($mysqlType) {
222 case 'INT':
223 return '(11)';
224 default:
225 return '(' . $maxLength . ')';
226 }
227 }
228
229 /**
230 * Return the MySQL native representation of the NOT NULL setting
231 *
232 * @param mixed $notNull
233 * @return string
234 */
235 protected function getNativeNotNull($notNull) {
236 return (bool)$notNull ? 'NO' : 'YES';
237 }
238
239 /**
240 * Return the default value of a field formatted to match the native MySQL SQL dialect
241 *
242 * @param array $fieldDefinition
243 * @return mixed
244 */
245 protected function getNativeDefaultValue($fieldDefinition) {
246 return $fieldDefinition['default_value'];
247 }
248
249 /**
250 * Return the MySQL native key type indicator - https://dev.mysql.com/doc/refman/5.5/en/show-columns.html
251 * PRI - the column is a PRIMARY KEY or is one of the columns in a multiple-column PRIMARY KEY
252 * UNI - the column is the first column of a UNIQUE index
253 * MUL - the column is the first column of a nonunique index
254 * If more than one of the values applies return the one with the highest priority, in the order PRI, UNI, MUL
255 * If none applies return empty value.
256 *
257 * @param array $fieldRow
258 * @return string
259 */
260 protected function getNativeKeyForField($fieldRow) {
261 return '';
262 }
263
264 /**
265 * Return the MySQL native extra field information - https://dev.mysql.com/doc/refman/5.5/en/show-columns.html
266 * auto_increment for columns that have the AUTO_INCREMENT attribute
267 * on update CURRENT_TIMESTAMP for TIMESTAMP columns that have the ON UPDATE CURRENT_TIMESTAMP attribute.
268 *
269 * @param array $fieldRow
270 * @return string
271 */
272 protected function getNativeExtraFieldAttributes($fieldRow) {
273 return '';
274 }
275 }