[TASK] Add schema migration service and dumping utility 27/58627/2
authorStanislas Rolland <typo3@sjbr.ca>
Sun, 14 Oct 2018 18:15:49 +0000 (14:15 -0400)
committerStanislas Rolland <typo3@sjbr.ca>
Sun, 14 Oct 2018 18:16:43 +0000 (20:16 +0200)
Import from TYPO3 8 LTS migration service and table dumping utility
that were removed in TYPO3 9 LTS.

Change-Id: I008860ffe8aa005d155e46979b0730657bd1e407
Resolves: #86610
Reviewed-on: https://review.typo3.org/58627
Reviewed-by: Stanislas Rolland <typo3@sjbr.ca>
Tested-by: Stanislas Rolland <typo3@sjbr.ca>
ChangeLog
Classes/Utility/DatabaseUtility.php

index 37a1cb2..57384a9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,6 @@
 2018-10-14  Stanislas Rolland  <typo3(arobas)sjbr.ca>
 
-       * Resolves #86610: Add database schema migration service
+       * Resolves #86610: Add schema migration service and dumping utility
 
 2018-10-11  Stanislas Rolland  <typo3(arobas)sjbr.ca>
 
index f6c52d8..e023377 100644 (file)
 <?php
 namespace SJBR\StaticInfoTables\Utility;
 
-/***************************************************************
- *  Copyright notice
+/*
+ * This file is part of the TYPO3 CMS project.
  *
- *  (c) 2012 Susanne Moog, <susanne.moog@typo3.org>
- *  All rights reserved
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
  *
- *  This script is part of the TYPO3 project. The TYPO3 project is
- *  free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
  *
- *  The GNU General Public License can be found at
- *  http://www.gnu.org/copyleft/gpl.html.
- *  A copy is found in the textfile GPL.txt and important notices to the license
- *  from the author is found in LICENSE.txt distributed with these scripts.
- *
- *
- *  This script is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  This copyright notice MUST APPEAR in all copies of the script!
- ***************************************************************/
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
 /**
  * Utility for dealing with database related operations
- *
- * @author Susanne Moog <susanne.moog@typo3.org>
  */
-class DatabaseUtility extends \TYPO3\CMS\Extensionmanager\Utility\DatabaseUtility {
-
-       /**
-        * Header comments of the SQL dump file
-        *
-        * @return string Table header
-        */
-       protected function dumpHeader() {
-               return trim('
+class DatabaseUtility implements \TYPO3\CMS\Core\SingletonInterface
+{
+    /**
+     * @var string
+     */
+    const MULTI_LINEBREAKS = '
+
+
+';
+    /**
+     * Dump content for static tables
+     *
+     * @param array $dbFields
+     * @return string
+     */
+    public function dumpStaticTables($dbFields)
+    {
+        $out = '';
+        // Traverse the table list and dump each:
+        foreach ($dbFields as $table => $fields) {
+            if (is_array($dbFields[$table]['fields'])) {
+                $header = $this->dumpHeader();
+                $tableHeader = $this->dumpTableHeader($table, $dbFields[$table], true);
+                $insertStatements = $this->dumpTableContent($table, $dbFields[$table]['fields']);
+                $out .= $header . self::MULTI_LINEBREAKS . $tableHeader . self::MULTI_LINEBREAKS . $insertStatements . self::MULTI_LINEBREAKS;
+            }
+        }
+        return $out;
+    }
+
+    /**
+     * Header comments of the SQL dump file
+     *
+     * @return string Table header
+     */
+    protected function dumpHeader()
+    {
+        return trim('
 # TYPO3 Extension Manager dump 1.1
 #
+# Host: ' . $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['host'] . '    Database: ' . $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['dbname'] . '
 #--------------------------------------------------------
 ');
-       }
-}
+    }
 
-?>
\ No newline at end of file
+    /**
+     * Dump CREATE TABLE definition
+     *
+     * @param string $table
+     * @param array $fieldKeyInfo
+     * @param bool $dropTableIfExists
+     * @return string
+     */
+    protected function dumpTableHeader($table, array $fieldKeyInfo, $dropTableIfExists = false)
+    {
+        $lines = [];
+        $dump = '';
+        // Create field definitions
+        if (is_array($fieldKeyInfo['fields'])) {
+            foreach ($fieldKeyInfo['fields'] as $fieldN => $data) {
+                $lines[] = '  ' . $fieldN . ' ' . $data;
+            }
+        }
+        // Create index key definitions
+        if (is_array($fieldKeyInfo['keys'])) {
+            foreach ($fieldKeyInfo['keys'] as $fieldN => $data) {
+                $lines[] = '  ' . $data;
+            }
+        }
+        // Compile final output:
+        if (!empty($lines)) {
+            $dump = trim('
+#
+# Table structure for table "' . $table . '"
+#
+' . ($dropTableIfExists ? 'DROP TABLE IF EXISTS ' . $table . ';
+' : '') . 'CREATE TABLE ' . $table . ' (
+' . implode((',' . LF), $lines) . '
+);');
+        }
+        return $dump;
+    }
+
+    /**
+     * Dump table content
+     * Is DBAL compliant, but the dump format is written as MySQL standard.
+     * If the INSERT statements should be imported in a DBMS using other
+     * quoting than MySQL they must first be translated.
+     *
+     * @param string $table Table name
+     * @param array $fieldStructure Field structure
+     * @return string SQL Content of dump (INSERT statements)
+     */
+    protected function dumpTableContent($table, array $fieldStructure)
+    {
+        // Substitution of certain characters (borrowed from phpMySQL):
+        $search = ['\\', '\'', "\0", "\n", "\r", "\x1A"];
+        $replace = ['\\\\', '\\\'', '\\0', '\\n', '\\r', '\\Z'];
+        $lines = [];
+        // Select all rows from the table:
+        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
+            ->getQueryBuilderForTable($table);
+        $queryBuilder->getRestrictions()
+            ->removeAll();
+        $result = $queryBuilder->select('*')
+            ->from($table)
+            ->execute();
+        // Traverse the selected rows and dump each row as a line in the file:
+        while ($row = $result->fetch()) {
+            $values = [];
+            foreach ($fieldStructure as $field => $structure) {
+                $values[] = isset($row[$field]) ? '\'' . str_replace($search, $replace, $row[$field]) . '\'' : 'NULL';
+            }
+            $lines[] = 'INSERT INTO ' . $table . ' VALUES (' . implode(', ', $values) . ');';
+        }
+        // Implode lines and return:
+        return implode(LF, $lines);
+    }
+}