[TASK] DBAL: Create rudimentary mappings 35/36335/20
authorAndreas Fernandez <a.fernandez@scripting-base.de>
Wed, 4 Feb 2015 11:31:53 +0000 (12:31 +0100)
committerChristian Kuhn <lolli@schwarzbu.ch>
Fri, 7 Aug 2015 11:09:39 +0000 (13:09 +0200)
If a table or a field is not mapped already, a rudimentary name is
created, respecting the pre-defined limits in the DBMS specifics.
The mappings are inserted into LocalConfiguration.php.

Resolves: #64568
Releases: master
Change-Id: I6047487e6ef7196142ac88cf77545591224b9dcc
Reviewed-on: http://review.typo3.org/36335
Reviewed-by: Morton Jonuschat <m.jonuschat@mojocode.de>
Tested-by: Morton Jonuschat <m.jonuschat@mojocode.de>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
typo3/sysext/dbal/Classes/Database/DatabaseConnection.php
typo3/sysext/dbal/Classes/Database/Specifics/AbstractSpecifics.php

index 8d53f12..392b6f9 100644 (file)
@@ -2901,9 +2901,9 @@ class DatabaseConnection extends \TYPO3\CMS\Core\Database\DatabaseConnection {
                // Process query based on type:
                switch ($parsedQuery['type']) {
                        case 'CREATETABLE':
-
                        case 'ALTERTABLE':
-
+                               $this->createMappingsIfRequired($parsedQuery);
+                               // Fall-through next instruction
                        case 'DROPTABLE':
                                $this->clearCachedFieldInfo();
                                $this->map_genericQueryParsed($parsedQuery);
@@ -3689,6 +3689,51 @@ class DatabaseConnection extends \TYPO3\CMS\Core\Database\DatabaseConnection {
                }
        }
 
+       /**
+        * Create a mapping for each table and field if required.
+        *
+        * @param array $parsedQuery The parsed query
+        * @return void
+        */
+       protected function createMappingsIfRequired($parsedQuery) {
+               if (
+                       !$this->dbmsSpecifics->specificExists(Specifics\AbstractSpecifics::TABLE_MAXLENGTH)
+                       && !$this->dbmsSpecifics->specificExists(Specifics\AbstractSpecifics::FIELD_MAXLENGTH)
+               ) {
+                       return;
+               }
+
+               $mappingConfiguration = array();
+               $table = $parsedQuery['TABLE'];
+               if (!isset($this->mapping[$table])) {
+                       $truncatedTable = $this->dbmsSpecifics->truncateIdentifier($table, Specifics\AbstractSpecifics::TABLE_MAXLENGTH);
+                       if ($table !== $truncatedTable) {
+                               $mappingConfiguration['mapTableName'] = $truncatedTable;
+                       }
+               }
+               foreach ($parsedQuery['FIELDS'] as $field => $_) {
+                       if (!isset($this->mapping[$table]['mapFieldNames'][$field])) {
+                               $truncatedField = $this->dbmsSpecifics->truncateIdentifier($field, Specifics\AbstractSpecifics::FIELD_MAXLENGTH);
+                               if ($field !== $truncatedField) {
+                                       $mappingConfiguration['mapFieldNames'][$field] = $truncatedField;
+                               }
+                       }
+               }
+               if (!empty($mappingConfiguration)) {
+                       /** @var \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager */
+                       $objectManager = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
+                       /** @var \TYPO3\CMS\Core\Configuration\ConfigurationManager $configurationManager */
+                       $configurationManager = $objectManager->get(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class);
+                       $configurationManager->setLocalConfigurationValueByPath(
+                               'EXTCONF/dbal/mapping/' . $table,
+                               $mappingConfiguration
+                       );
+
+                       // renew mapping information
+                       $this->mapping = array_merge($this->mapping, array($table => $mappingConfiguration));
+               }
+       }
+
        /**************************************
         *
         * Debugging
index b2e2f94..16bed72 100644 (file)
@@ -151,6 +151,28 @@ abstract class AbstractSpecifics {
        }
 
        /**
+        * Truncates the name of the identifier.
+        * Based on TYPO3.FLOWs' FlowAnnotationDriver::truncateIdentifier()
+        *
+        * @param string $identifier
+        * @param string $specific
+        * @return string
+        */
+       public function truncateIdentifier($identifier, $specific) {
+               if (!$this->specificExists($specific)) {
+                       return $identifier;
+               }
+
+               $maxLength = $this->getSpecific($specific);
+               if (strlen($identifier) > $maxLength) {
+                       $truncateChars = 10;
+                       $identifier = substr($identifier, 0, $maxLength - $truncateChars) . '_' . substr(sha1($identifier), 0, $truncateChars - 1);
+               }
+
+               return $identifier;
+       }
+
+       /**
         * Adjust query parts for DBMS
         *
         * @param string $select_fields