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