2 namespace TYPO3\CMS\Install\Service;
45 $this->deletedPrefixKey = $prefix;
66 $lines = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(LF, $fileContent,
true);
69 foreach ($lines as $value) {
70 if ($value[0] ===
'#') {
75 $parts = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(
' ', $value,
true);
76 if (strtoupper($parts[0]) ===
'CREATE' && strtoupper($parts[1]) ===
'TABLE') {
77 $table = str_replace(
'`',
'', $parts[2]);
79 if (TYPO3_OS ==
'WIN') {
80 $table = strtolower($table);
84 if ($value[0] ===
')' && substr($value, -1) ===
';') {
86 if (preg_match(
'/(ENGINE|TYPE)[ ]*=[ ]*([a-zA-Z]*)/', $value, $ttype)) {
87 $total[$table][
'extra'][
'ENGINE'] = $ttype[2];
91 if (preg_match(
'/(COLLATE)[ ]*=[ ]*([a-zA-z0-9_-]+)/', $value, $tcollation)) {
92 $total[$table][
'extra'][
'COLLATE'] = $tcollation[2];
95 if (preg_match(
'/(CHARSET|CHARACTER SET)[ ]*=[ ]*([a-zA-z0-9_-]+)/', $value, $tcharset)) {
97 $charset = $tcharset[2];
107 $lineV = preg_replace(
'/,$/',
'', $value);
108 $lineV = str_replace(
'`',
'', $lineV);
110 $lineV = preg_replace(
'/\h+/',
' ', $lineV);
111 $parts = explode(
' ', $lineV, 2);
113 if (!preg_match(
'/(PRIMARY|UNIQUE|FULLTEXT|SPATIAL|INDEX|KEY)/', $parts[0])) {
115 if (stristr($parts[1],
'auto_increment')) {
116 $parts[1] = preg_replace(
'/ default \'0\'/i',
'', $parts[1]);
119 if (stristr($parts[1],
' DEFAULT ')) {
120 $parts[1] = str_ireplace(
' DEFAULT ',
' default ', $parts[1]);
123 $parts[1] = preg_replace(
'/(.*) (default .*) (NOT NULL)/',
'$1 $3 $2', $parts[1]);
124 $parts[1] = preg_replace(
'/(.*) (default .*) (NULL)/',
'$1 $3 $2', $parts[1]);
126 $total[$table][
'fields'][$key] = $parts[1];
129 $search = array(
'/UNIQUE (INDEX|KEY)/',
'/FULLTEXT (INDEX|KEY)/',
'/SPATIAL (INDEX|KEY)/',
'/INDEX/');
130 $replace = array(
'UNIQUE',
'FULLTEXT',
'SPATIAL',
'KEY');
131 $lineV = preg_replace($search, $replace, $lineV);
132 if (preg_match(
'/PRIMARY|UNIQUE|FULLTEXT|SPATIAL/', $parts[0])) {
133 $parts[1] = preg_replace(
'/^(KEY|INDEX) /',
'', $parts[1]);
135 $newParts = explode(
' ', $parts[1], 2);
136 $key = $parts[0] ==
'PRIMARY' ? $parts[0] : $newParts[0];
137 $total[$table][
'keys'][$key] = $lineV;
139 if (preg_match(
'/^(cache|index)_/', $table)) {
141 $total[$table][
'extra'][
'CLEAR'] = 1;
159 if (empty($this->character_sets)) {
161 if (method_exists($databaseConnection,
'admin_get_charsets')) {
162 $this->character_sets = $databaseConnection->admin_get_charsets();
165 $this->character_sets[$charset] = array();
169 if (isset($this->character_sets[$charset][
'Default collation'])) {
170 $collation = $this->character_sets[$charset][
'Default collation'];
184 $tempKeysPrefix = array();
186 $databaseConnection->connectDB();
187 echo $databaseConnection->sql_error();
188 $tables = $databaseConnection->admin_get_tables();
189 foreach ($tables as $tableName => $tableStatus) {
191 $fieldInformation = $databaseConnection->admin_get_fields($tableName);
192 foreach ($fieldInformation as $fN => $fieldRow) {
196 $keyInformation = $databaseConnection->admin_get_keys($tableName);
197 foreach ($keyInformation as $keyRow) {
198 $keyName = $keyRow[
'Key_name'];
199 $colName = $keyRow[
'Column_name'];
200 if ($keyRow[
'Sub_part'] && $keyRow[
'Index_type'] !==
'SPATIAL') {
201 $colName .=
'(' . $keyRow[
'Sub_part'] .
')';
203 $tempKeys[$tableName][$keyName][$keyRow[
'Seq_in_index']] = $colName;
204 if ($keyName ==
'PRIMARY') {
205 $prefix =
'PRIMARY KEY';
207 if ($keyRow[
'Index_type'] ===
'FULLTEXT') {
208 $prefix =
'FULLTEXT';
209 }
elseif ($keyRow[
'Index_type'] ===
'SPATIAL') {
211 }
elseif ($keyRow[
'Non_unique']) {
216 $prefix .=
' ' . $keyName;
218 $tempKeysPrefix[$tableName][$keyName] = $prefix;
221 if (is_array($tableStatus)) {
222 $tableExtraFields = array(
223 'Engine' =>
'ENGINE',
224 'Collation' =>
'COLLATE'
226 foreach ($tableExtraFields as $mysqlKey => $internalKey) {
227 if (isset($tableStatus[$mysqlKey])) {
228 $total[$tableName][
'extra'][$internalKey] = $tableStatus[$mysqlKey];
234 if (!empty($tempKeys)) {
235 foreach ($tempKeys as $table => $keyInf) {
236 foreach ($keyInf as $kName => $index) {
238 $total[$table][
'keys'][$kName] = $tempKeysPrefix[$table][$kName] .
' (' . implode(
',', $index) .
')';
255 public function getDatabaseExtra($FDsrc, $FDcomp, $onlyTableList =
'', $ignoreNotNullWhenComparing =
false)
259 if (is_array($FDsrc)) {
260 foreach ($FDsrc as $table => $info) {
262 if (!isset($FDcomp[$table])) {
264 $extraArr[$table] = $info;
265 $extraArr[$table][
'whole_table'] = 1;
267 $keyTypes = explode(
',',
'extra,fields,keys');
268 foreach ($keyTypes as $theKey) {
269 if (is_array($info[$theKey])) {
270 foreach ($info[$theKey] as $fieldN => $fieldC) {
271 $fieldN = str_replace(
'`',
'', $fieldN);
275 if ($fieldN ==
'COLLATE') {
279 if (!isset($FDcomp[$table][$theKey][$fieldN])) {
280 $extraArr[$table][$theKey][$fieldN] = $fieldC;
282 $fieldC = trim($fieldC);
289 $fieldC = preg_replace_callback(
290 '/^([a-zA-Z0-9]+)(\([^)]*\)\s.*)/',
291 function ($matches) {
return strtolower($matches[1]) . $matches[2]; },
297 if (preg_match(
'/^(TINYINT|SMALLINT|MEDIUMINT|INT|INTEGER|BIGINT|REAL|DOUBLE|FLOAT|DECIMAL|NUMERIC)\([^\)]+\)\s+(UNSIGNED|ZEROFILL)/i', $fieldC)) {
298 $fieldC = str_ireplace(array(
' UNSIGNED',
' ZEROFILL'),
'', $fieldC);
299 $FDcomp[$table][$theKey][$fieldN] = str_ireplace(array(
' UNSIGNED',
' ZEROFILL'),
'', $FDcomp[$table][$theKey][$fieldN]);
303 if ($fieldC !== $FDcomp[$table][$theKey][$fieldN]) {
314 if ($ignoreNotNullWhenComparing) {
315 $fieldC = str_replace(
' NOT NULL',
'', $fieldC);
316 $FDcomp[$table][$theKey][$fieldN] = str_replace(
' NOT NULL',
'', $FDcomp[$table][$theKey][$fieldN]);
318 if ($fieldC !== $FDcomp[$table][$theKey][$fieldN]) {
319 $diffArr[$table][$theKey][$fieldN] = $fieldC;
320 $diffArr_cur[$table][$theKey][$fieldN] = $FDcomp[$table][$theKey][$fieldN];
331 'extra' => $extraArr,
333 'diff_currentValues' => $diffArr_cur
347 $statements = array();
351 if ($keyList ==
'remove') {
355 $keyList = explode(
',', $keyList);
356 foreach ($keyList as $theKey) {
357 if (is_array($diffArr[$theKey])) {
358 foreach ($diffArr[$theKey] as $table => $info) {
359 $whole_table = array();
360 if (isset($info[
'keys']) && is_array($info[
'keys'])) {
361 foreach ($info[
'keys'] as $fN => $fV) {
362 if (!$info[
'whole_table'] && $theKey ===
'extra' && $remove) {
363 $statement =
'ALTER TABLE ' . $table . ($fN ===
'PRIMARY' ?
' DROP PRIMARY KEY' :
' DROP KEY ' . $fN) .
';';
364 $statements[
'drop'][md5($statement)] = $statement;
368 if (is_array($info[
'fields'])) {
369 foreach ($info[
'fields'] as $fN => $fV) {
370 if ($info[
'whole_table']) {
371 $whole_table[] = $fN .
' ' . $fV;
374 if (stristr($fV,
'auto_increment')) {
377 if (isset($info[
'keys'][
'PRIMARY'])) {
380 $fV .=
', ADD PRIMARY KEY (' . $fN .
')';
381 unset($info[
'keys'][
'PRIMARY']);
385 $info[
'extra'][
'CLEAR'] = 2;
388 if ($theKey ==
'extra') {
392 $prefixedFieldName =
$deletedPrefixKey . substr($fN, ($deletedPrefixLength - self::MYSQL_MAXIMUM_FIELD_WIDTH));
393 $statement =
'ALTER TABLE ' . $table .
' CHANGE ' . $fN .
' ' . $prefixedFieldName .
' ' . $fV .
';';
394 $statements[
'change'][md5($statement)] = $statement;
396 $statement =
'ALTER TABLE ' . $table .
' DROP ' . $fN .
';';
397 $statements[
'drop'][md5($statement)] = $statement;
400 $statement =
'ALTER TABLE ' . $table .
' ADD ' . $fN .
' ' . $fV .
';';
401 $statements[
'add'][md5($statement)] = $statement;
403 }
elseif ($theKey ==
'diff') {
404 $statement =
'ALTER TABLE ' . $table .
' CHANGE ' . $fN .
' ' . $fN .
' ' . $fV .
';';
405 $statements[
'change'][md5($statement)] = $statement;
406 $statements[
'change_currentValue'][md5($statement)] = $diffArr[
'diff_currentValues'][$table][
'fields'][$fN];
411 if (is_array($info[
'keys'])) {
412 foreach ($info[
'keys'] as $fN => $fV) {
413 if ($info[
'whole_table']) {
414 $whole_table[] = $fV;
416 if ($theKey ==
'extra') {
418 $statement =
'ALTER TABLE ' . $table .
' ADD ' . $fV .
';';
419 $statements[
'add'][md5($statement)] = $statement;
421 }
elseif ($theKey ==
'diff') {
422 $statement =
'ALTER TABLE ' . $table . ($fN ==
'PRIMARY' ?
' DROP PRIMARY KEY' :
' DROP KEY ' . $fN) .
';';
423 $statements[
'change'][md5($statement)] = $statement;
424 $statement =
'ALTER TABLE ' . $table .
' ADD ' . $fV .
';';
425 $statements[
'change'][md5($statement)] = $statement;
430 if (is_array($info[
'extra'])) {
432 $extras_currentValue = array();
433 $clear_table =
false;
434 foreach ($info[
'extra'] as $fN => $fV) {
437 if (!$info[
'whole_table']) {
439 if ($fN ==
'CLEAR') {
442 if (!empty($info[
'keys']) || $fV == 2) {
447 $extras[] = $fN .
'=' . $fV;
448 $extras_currentValue[] = $fN .
'=' . $diffArr[
'diff_currentValues'][$table][
'extra'][$fN];
454 $statement =
'TRUNCATE TABLE ' . $table .
';';
455 $statements[
'clear_table'][md5($statement)] = $statement;
457 if (!empty($extras)) {
458 $statement =
'ALTER TABLE ' . $table .
' ' . implode(
' ', $extras) .
';';
459 $statements[
'change'][md5($statement)] = $statement;
460 $statements[
'change_currentValue'][md5($statement)] = implode(
' ', $extras_currentValue);
463 if ($info[
'whole_table']) {
467 $prefixedTableName =
$deletedPrefixKey . substr($table, ($deletedPrefixLength - self::MYSQL_MAXIMUM_FIELD_WIDTH));
468 $statement =
'ALTER TABLE ' . $table .
' RENAME ' . $prefixedTableName .
';';
469 $statements[
'change_table'][md5($statement)] = $statement;
471 $statement =
'DROP TABLE ' . $table .
';';
472 $statements[
'drop_table'][md5($statement)] = $statement;
476 $statements[
'tables_count'][md5($statement)] = $count ?
'Records in table: ' . $count :
'';
478 $statement =
'CREATE TABLE ' . $table .
' (
482 if ($info[
'extra']) {
483 foreach ($info[
'extra'] as $k => $v) {
484 if ($k ==
'COLLATE' || $k ==
'CLEAR') {
490 $statement .=
' ' . $k .
'=' . $v;
494 $statements[
'create_table'][md5($statement)] = $statement;
511 $field = array($row[
'Type']);
512 if ($row[
'Null'] ==
'NO') {
513 $field[] =
'NOT NULL';
515 if (!strstr($row[
'Type'],
'blob') && !strstr($row[
'Type'],
'text')) {
517 if (!stristr($row[
'Extra'],
'auto_increment')) {
518 if ($row[
'Default'] === null) {
519 $field[] =
'default NULL';
521 $field[] =
'default \'' . addslashes($row[
'Default']) .
'\'';
526 $field[] = $row[
'Extra'];
528 if (trim($row[
'Comment']) !==
'') {
529 $field[] =
"COMMENT '" . $row[
'Comment'] .
"'";
531 return implode(
' ', $field);
544 $sqlcodeArr = explode(LF, $sqlcode);
546 $statementArray = array();
547 $statementArrayPointer = 0;
548 foreach ($sqlcodeArr as $line => $lineContent) {
549 $lineContent = trim($lineContent);
552 if (stristr($lineContent,
'auto_increment')) {
553 $lineContent = preg_replace(
'/ default \'0\'/i',
'', $lineContent);
555 if (!$removeNonSQL || $lineContent !==
'' && $lineContent[0] !==
'#' && substr($lineContent, 0, 2) !==
'--') {
557 $statementArray[$statementArrayPointer] .= $lineContent;
560 if (substr($lineContent, -1) ===
';') {
561 if (isset($statementArray[$statementArrayPointer])) {
562 if (!trim($statementArray[$statementArrayPointer]) || $query_regex && !preg_match((
'/' . $query_regex .
'/i'), trim($statementArray[$statementArrayPointer]))) {
563 unset($statementArray[$statementArrayPointer]);
566 $statementArrayPointer++;
568 $statementArray[$statementArrayPointer] .= LF;
571 return $statementArray;
584 $insertCount = array();
585 foreach ($statements as $line => $lineContent) {
587 if (preg_match(
'/^create[[:space:]]*table[[:space:]]*[`]?([[:alnum:]_]*)[`]?/i', substr($lineContent, 0, 100), $reg)) {
588 $table = trim($reg[1]);
591 if (TYPO3_OS ==
'WIN') {
592 $table = strtolower($table);
594 $sqlLines = explode(LF, $lineContent);
595 foreach ($sqlLines as $k => $v) {
596 if (stristr($v,
'auto_increment')) {
597 $sqlLines[$k] = preg_replace(
'/ default \'0\'/i',
'', $v);
600 $lineContent = implode(LF, $sqlLines);
601 $crTables[$table] = $lineContent;
603 }
elseif ($insertCountFlag && preg_match(
'/^insert[[:space:]]*into[[:space:]]*[`]?([[:alnum:]_]*)[`]?/i', substr($lineContent, 0, 100), $reg)) {
604 $nTable = trim($reg[1]);
605 $insertCount[$nTable]++;
608 return array($crTables, $insertCount);
620 $outStatements = array();
621 foreach ($statements as $line => $lineContent) {
623 if (preg_match(
'/^insert[[:space:]]*into[[:space:]]*[`]?([[:alnum:]_]*)[`]?/i', substr($lineContent, 0, 100), $reg)) {
624 $nTable = trim($reg[1]);
625 if ($nTable && $table === $nTable) {
626 $outStatements[] = $lineContent;
630 return $outStatements;
643 if (is_array($arr)) {
645 foreach ($arr as $key => $string) {
646 if (isset($keyArr[$key]) && $keyArr[$key]) {
647 $res = $databaseConnection->admin_query($string);
648 if ($res ===
false) {
649 $result[$key] = $databaseConnection->sql_error();
650 }
elseif (is_resource($res) || is_a($res,
'\\mysqli_result')) {
651 $databaseConnection->sql_free_result($res);
656 if (!empty($result)) {
672 foreach ($whichTables as $key => &$value) {
686 return \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded(
'dbal');