[TASK] mssql: A series of functional test fixes 04/53104/3
authorChristian Kuhn <lolli@schwarzbu.ch>
Mon, 22 May 2017 13:39:09 +0000 (15:39 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Sun, 4 Jun 2017 08:27:10 +0000 (10:27 +0200)
A couple of straight patches withis functional test cases
for mssql compatibility:
* Set identity where records with uids are inserted
* Quote LOB fields correctly
* A change to cope with [] encapsulated field and table names

Change-Id: I103021550fbe5c62f15e82454c766d67fc0dc63f
Resolves: #81465
Releases: master, 8.7
Reviewed-on: https://review.typo3.org/53104
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
typo3/sysext/core/Tests/Functional/Category/Collection/CategoryCollectionTest.php
typo3/sysext/core/Tests/Functional/Collection/RecordCollectionRepositoryTest.php
typo3/sysext/core/Tests/Functional/RegistryTest.php
typo3/sysext/frontend/Tests/Functional/ContentObject/ContentObjectRendererTest.php
typo3/sysext/frontend/Tests/Functional/Controller/TypoScriptFrontendControllerTest.php

index 766e50e..6a4ba5f 100644 (file)
@@ -14,8 +14,11 @@ namespace TYPO3\CMS\Core\Tests\Functional\Category\Collection;
  * The TYPO3 project - inspiring people to share!
  */
 
+use Doctrine\DBAL\Schema\Column;
+use Doctrine\DBAL\Schema\TableDiff;
 use Doctrine\DBAL\Types\Type;
 use TYPO3\CMS\Core\Category\Collection\CategoryCollection;
+use TYPO3\CMS\Core\Database\Connection;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
@@ -336,7 +339,7 @@ class CategoryCollectionTest extends \TYPO3\TestingFramework\Core\Functional\Fun
             'is_dummy_record' => 1
         ];
 
-        $connection->insert('sys_category', $values);
+        $connection->insert('sys_category', $values, [ 'l10n_diffsource' => Connection::PARAM_LOB ]);
         $this->categoryUid = $connection->lastInsertId('sys_category');
     }
 
@@ -351,16 +354,17 @@ class CategoryCollectionTest extends \TYPO3\TestingFramework\Core\Functional\Fun
     {
         $connection = $this->getConnectionPool()
             ->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME);
-        $currentSchema = $connection->getSchemaManager()->createSchema();
-        $targetSchema = clone $currentSchema;
 
         foreach ($this->tables as $table) {
-            $targetSchema->getTable($table)->dropColumn('is_dummy_record');
-        }
-
-        $queries = $currentSchema->getMigrateToSql($targetSchema, $connection->getDatabasePlatform());
-        foreach ($queries as $query) {
-            $connection->query($query);
+            $diff = new TableDiff(
+                $table,
+                [],
+                [],
+                [
+                    'is_dummy_record' => new Column('is_dummy_record', Type::getType(Type::SMALLINT))
+                ]
+            );
+            $connection->getSchemaManager()->alterTable($diff);
         }
     }
 }
index 595fbe7..b25eb7a 100644 (file)
@@ -14,6 +14,7 @@ namespace TYPO3\CMS\Core\Tests\Functional\Collection;
  * The TYPO3 project - inspiring people to share!
  */
 
+use Doctrine\DBAL\Platforms\SQLServerPlatform;
 use TYPO3\CMS\Core\Collection\RecordCollectionRepository;
 use TYPO3\CMS\Core\Collection\StaticRecordCollection;
 use TYPO3\CMS\Core\Database\ConnectionPool;
@@ -84,8 +85,8 @@ class RecordCollectionRepositoryTest extends \TYPO3\TestingFramework\Core\Functi
     {
         $type = RecordCollectionRepository::TYPE_Static;
         $this->insertTestData([
-            ['type' => $type, 'table_name' => $this->testTableName],
-            ['type' => $type, 'table_name' => $this->testTableName]
+            ['uid' => 1, 'type' => $type, 'table_name' => $this->testTableName],
+            ['uid' => 2, 'type' => $type, 'table_name' => $this->testTableName]
         ]);
 
         $objects = $this->subject->findByType($type);
@@ -110,8 +111,8 @@ class RecordCollectionRepositoryTest extends \TYPO3\TestingFramework\Core\Functi
     {
         $type = RecordCollectionRepository::TYPE_Static;
         $this->insertTestData([
-            ['type' => $type, 'table_name' => $this->testTableName],
-            ['type' => $type, 'table_name' => $this->testTableName]
+            ['uid' => 1, 'type' => $type, 'table_name' => $this->testTableName],
+            ['uid' => 2, 'type' => $type, 'table_name' => $this->testTableName]
         ]);
         $objects = $this->subject->findByTableName($this->testTableName);
 
@@ -138,8 +139,8 @@ class RecordCollectionRepositoryTest extends \TYPO3\TestingFramework\Core\Functi
     {
         $type = RecordCollectionRepository::TYPE_Static;
         $this->insertTestData([
-            ['type' => $type, 'table_name' => $this->testTableName],
-            ['type' => $type, 'table_name' => $this->testTableName]
+            ['uid' => 1, 'type' => $type, 'table_name' => $this->testTableName],
+            ['uid' => 2, 'type' => $type, 'table_name' => $this->testTableName]
         ]);
         $objects = $this->subject->findByTypeAndTableName($type, $this->testTableName);
 
@@ -305,9 +306,35 @@ class RecordCollectionRepositoryTest extends \TYPO3\TestingFramework\Core\Functi
     protected function insertTestData(array $rows)
     {
         $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('sys_collection');
+        $platform = $connection->getDatabasePlatform();
+        $sqlServerIdentityDisabled = false;
+        if ($platform instanceof SQLServerPlatform) {
+            try {
+                $connection->exec('SET IDENTITY_INSERT sys_collection ON');
+                $sqlServerIdentityDisabled = true;
+            } catch (\Doctrine\DBAL\DBALException $e) {
+                // Some tables like sys_refindex don't have an auto-increment uid field and thus no
+                // IDENTITY column. Instead of testing existance, we just try to set IDENTITY ON
+                // and catch the possible error that occurs.
+            }
+        }
+
+        $types = [];
+        $tableDetails = $connection->getSchemaManager()->listTableDetails('sys_collection');
+        foreach ($rows as $row) {
+            foreach ($row as $columnName => $columnValue) {
+                $types[] = $tableDetails->getColumn($columnName)->getType()->getBindingType();
+            }
+            break;
+        }
 
         foreach ($rows as $row) {
-            $connection->insert('sys_collection', $row);
+            $connection->insert('sys_collection', $row, $types);
+        }
+
+        if ($sqlServerIdentityDisabled) {
+            // Reset identity if it has been changed
+            $connection->exec('SET IDENTITY_INSERT sys_collection OFF');
         }
     }
 }
index acb65d1..84f70d1 100644 (file)
@@ -14,6 +14,7 @@ namespace TYPO3\CMS\Core\Tests\Functional;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Core\Database\Connection;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Registry;
 
@@ -51,6 +52,9 @@ class RegistryTest extends \TYPO3\TestingFramework\Core\Functional\FunctionalTes
                     'entry_namespace' => 'myExtension',
                     'entry_key' => 'myKey',
                     'entry_value' => serialize('myValue'),
+                ],
+                [
+                    'entry_value' => Connection::PARAM_LOB,
                 ]
             );
         $this->assertSame('myValue', (new Registry())->get('myExtension', 'myKey'));
@@ -84,6 +88,9 @@ class RegistryTest extends \TYPO3\TestingFramework\Core\Functional\FunctionalTes
                     'entry_namespace' => 'myExtension',
                     'entry_key' => 'myKey',
                     'entry_value' => serialize('myValue'),
+                ],
+                [
+                    'entry_value' => Connection::PARAM_LOB,
                 ]
             );
         (new Registry())->set('myExtension', 'myKey', 'myNewValue');
@@ -110,7 +117,10 @@ class RegistryTest extends \TYPO3\TestingFramework\Core\Functional\FunctionalTes
                     ['ns1', 'k2', serialize('v2')],
                     ['ns2', 'k1', serialize('v1')],
                 ],
-                ['entry_namespace', 'entry_key', 'entry_value']
+                ['entry_namespace', 'entry_key', 'entry_value'],
+                [
+                    'entry_value' => Connection::PARAM_LOB,
+                ]
             );
 
         (new Registry())->remove('ns1', 'k1');
@@ -133,7 +143,10 @@ class RegistryTest extends \TYPO3\TestingFramework\Core\Functional\FunctionalTes
                 ['ns1', 'k2', serialize('v2')],
                 ['ns2', 'k1', serialize('v1')],
             ],
-            ['entry_namespace', 'entry_key', 'entry_value']
+            ['entry_namespace', 'entry_key', 'entry_value'],
+            [
+                'entry_value' => Connection::PARAM_LOB,
+            ]
         );
 
         (new Registry())->removeAllByNamespace('ns1');
index 295bb3c..1c52da2 100644 (file)
@@ -31,11 +31,6 @@ class ContentObjectRendererTest extends \TYPO3\TestingFramework\Core\Functional\
      */
     protected $subject;
 
-    /**
-     * @var string
-     */
-    protected $quoteChar;
-
     protected function setUp()
     {
         parent::setUp();
@@ -51,10 +46,6 @@ class ContentObjectRendererTest extends \TYPO3\TestingFramework\Core\Functional\
         $GLOBALS['TSFE'] = $typoScriptFrontendController;
 
         $this->subject = GeneralUtility::makeInstance(ContentObjectRenderer::class);
-        $this->quoteChar = GeneralUtility::makeInstance(ConnectionPool::class)
-            ->getConnectionForTable('tt_content')
-            ->getDatabasePlatform()
-            ->getIdentifierQuoteCharacter();
     }
 
     /**
@@ -79,7 +70,7 @@ class ContentObjectRendererTest extends \TYPO3\TestingFramework\Core\Functional\
                     'selectFields' => 'header,bodytext'
                 ],
                 [
-                    'SELECT' => 'header,bodytext, `tt_content`.`uid` AS `uid`, `tt_content`.`pid` AS `pid`, `tt_content`.`t3ver_state` AS `t3ver_state`'
+                    'SELECT' => 'header,bodytext, [tt_content].[uid] AS [uid], [tt_content].[pid] AS [pid], [tt_content].[t3ver_state] AS [t3ver_state]'
                 ]
             ],
             'testing #17284: no need to add' => [
@@ -107,7 +98,7 @@ class ContentObjectRendererTest extends \TYPO3\TestingFramework\Core\Functional\
                     'join' => 'be_users ON tt_content.cruser_id = be_users.uid'
                 ],
                 [
-                    'SELECT' => 'tt_content.header,be_users.username, `tt_content`.`uid` AS `uid`, `tt_content`.`pid` AS `pid`, `tt_content`.`t3ver_state` AS `t3ver_state`'
+                    'SELECT' => 'tt_content.header,be_users.username, [tt_content].[uid] AS [uid], [tt_content].[pid] AS [pid], [tt_content].[t3ver_state] AS [t3ver_state]'
                 ]
             ],
             'testing #34152: single count(*), add nothing' => [
@@ -190,10 +181,16 @@ class ContentObjectRendererTest extends \TYPO3\TestingFramework\Core\Functional\
         ];
 
         $result = $this->subject->getQuery($table, $conf, true);
+
+        $databasePlatform = (new ConnectionPool())->getConnectionForTable('tt_content')->getDatabasePlatform();
         foreach ($expected as $field => $value) {
-            // Replace the MySQL backtick quote character with the actual quote character for the DBMS
-            if ($field === 'SELECT') {
-                $value = str_replace('`', $this->quoteChar, $value);
+            if (!($databasePlatform instanceof \Doctrine\DBAL\Platforms\SQLServerPlatform)) {
+                // Replace the MySQL backtick quote character with the actual quote character for the DBMS,
+                if ($field === 'SELECT') {
+                    $quoteChar = $databasePlatform->getIdentifierQuoteCharacter();
+                    $value = str_replace('[', $quoteChar, $value);
+                    $value = str_replace(']', $quoteChar, $value);
+                }
             }
             $this->assertEquals($value, $result[$field]);
         }
@@ -270,7 +267,7 @@ class ContentObjectRendererTest extends \TYPO3\TestingFramework\Core\Functional\
                     'groupBy' => 'tt_content.title',
                     'orderBy' => 'tt_content.sorting',
                 ],
-                'WHERE (`tt_content`.`uid` IN (42)) AND (`tt_content`.`pid` IN (43)) AND (tt_content.cruser_id=5) GROUP BY `tt_content`.`title` ORDER BY `tt_content`.`sorting`',
+                'WHERE ([tt_content].[uid] IN (42)) AND ([tt_content].[pid] IN (43)) AND (tt_content.cruser_id=5) GROUP BY [tt_content].[title] ORDER BY [tt_content].[sorting]',
             ],
             [
                 [
@@ -297,7 +294,7 @@ class ContentObjectRendererTest extends \TYPO3\TestingFramework\Core\Functional\
                     'groupBy' => 'tt_content.title',
                     'orderBy' => 'tt_content.sorting',
                 ],
-                'WHERE (`tt_content`.`uid` IN (42)) AND (`tt_content`.`pid` IN (43)) AND (tt_content.cruser_id=5) AND (`tt_content`.`sys_language_uid` = 13) AND ((`tt_content`.`deleted` = 0) AND (`tt_content`.`hidden` = 0) AND (`tt_content`.`startdate` <= 4242) AND ((`tt_content`.`enddate` = 0) OR (`tt_content`.`enddate` > 4242))) GROUP BY `tt_content`.`title` ORDER BY `tt_content`.`sorting`',
+                'WHERE ([tt_content].[uid] IN (42)) AND ([tt_content].[pid] IN (43)) AND (tt_content.cruser_id=5) AND ([tt_content].[sys_language_uid] = 13) AND (([tt_content].[deleted] = 0) AND ([tt_content].[hidden] = 0) AND ([tt_content].[startdate] <= 4242) AND (([tt_content].[enddate] = 0) OR ([tt_content].[enddate] > 4242))) GROUP BY [tt_content].[title] ORDER BY [tt_content].[sorting]',
             ],
             [
                 [
@@ -317,7 +314,7 @@ class ContentObjectRendererTest extends \TYPO3\TestingFramework\Core\Functional\
                     'where' => 'tt_content.cruser_id=5',
                     'languageField' => 0,
                 ],
-                'WHERE (`tt_content`.`uid` IN (42)) AND (`tt_content`.`pid` IN (43)) AND (tt_content.cruser_id=5)',
+                'WHERE ([tt_content].[uid] IN (42)) AND ([tt_content].[pid] IN (43)) AND (tt_content.cruser_id=5)',
             ],
         ];
     }
@@ -343,8 +340,13 @@ class ContentObjectRendererTest extends \TYPO3\TestingFramework\Core\Functional\
             ->method('checkPidArray')
             ->willReturn(explode(',', $configuration['pidInList']));
 
-        // Replace the MySQL backtick quote character with the actual quote character for the DBMS
-        $expectedResult = str_replace('`', $this->quoteChar, $expectedResult);
+        // Replace the [] quote chars of mssql with the actual quote character of other DBMS
+        $databasePlatform = (new ConnectionPool())->getConnectionForTable('tt_content')->getDatabasePlatform();
+        if (!($databasePlatform instanceof \Doctrine\DBAL\Platforms\SQLServerPlatform)) {
+            $quoteChar = $databasePlatform->getIdentifierQuoteCharacter();
+            $expectedResult = str_replace('[', $quoteChar, $expectedResult);
+            $expectedResult = str_replace(']', $quoteChar, $expectedResult);
+        }
 
         // Embed the enable fields string into the expected result as the database
         // connection is still unconfigured when the data provider is being run.
index d5fe1bd..03ab52e 100644 (file)
@@ -14,6 +14,7 @@ namespace TYPO3\CMS\Frontend\Tests\Functional\Controller;
  * The TYPO3 project - inspiring people to share!
  */
 
+use Doctrine\DBAL\Platforms\SQLServerPlatform;
 use TYPO3\CMS\Core\Cache\CacheManager;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -115,13 +116,25 @@ class TypoScriptFrontendControllerTest extends \TYPO3\TestingFramework\Core\Func
             ],
         ];
 
+        $connection = (new ConnectionPool())->getConnectionForTable('sys_domain');
+
+        $sqlServerIdentityDisabled = false;
+        if ($connection->getDatabasePlatform() instanceof SQLServerPlatform) {
+            $connection->exec('SET IDENTITY_INSERT sys_domain ON');
+            $sqlServerIdentityDisabled = true;
+        }
+
         foreach ($domainRecords as $domainRecord) {
-            (new ConnectionPool())->getConnectionForTable('sys_domain')->insert(
+            $connection->insert(
                 'sys_domain',
                 $domainRecord
             );
         }
 
+        if ($sqlServerIdentityDisabled) {
+            $connection->exec('SET IDENTITY_INSERT sys_domain OFF');
+        }
+
         GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_runtime')->flush();
         $expectedResult = [
             $domainRecords[$currentDomain]['pid'] => $domainRecords[$currentDomain],
@@ -162,13 +175,25 @@ class TypoScriptFrontendControllerTest extends \TYPO3\TestingFramework\Core\Func
             ],
         ];
 
+        $connection = (new ConnectionPool())->getConnectionForTable('sys_domain');
+
+        $sqlServerIdentityDisabled = false;
+        if ($connection->getDatabasePlatform() instanceof SQLServerPlatform) {
+            $connection->exec('SET IDENTITY_INSERT sys_domain ON');
+            $sqlServerIdentityDisabled = true;
+        }
+
         foreach ($domainRecords as $domainRecord) {
-            (new ConnectionPool())->getConnectionForTable('sys_domain')->insert(
+            $connection->insert(
                 'sys_domain',
                 $domainRecord
             );
         }
 
+        if ($sqlServerIdentityDisabled) {
+            $connection->exec('SET IDENTITY_INSERT sys_domain OFF');
+        }
+
         GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_runtime')->flush();
         $expectedResult = [
             $domainRecords[$currentDomain]['pid'] => $domainRecords['foo.bar'],