diff --git a/Classes/Core/Functional/Framework/DataHandling/DataSet.php b/Classes/Core/Functional/Framework/DataHandling/DataSet.php index e079ddc0..ade2f3d1 100644 --- a/Classes/Core/Functional/Framework/DataHandling/DataSet.php +++ b/Classes/Core/Functional/Framework/DataHandling/DataSet.php @@ -69,14 +69,20 @@ public static function import(string $path): void foreach ($dataSet->getTableNames() as $tableName) { $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($tableName); $platform = $connection->getDatabasePlatform(); - // @todo Check if we can use the cached schema information here instead. - $tableDetails = $connection->createSchemaManager()->introspectTable($tableName); + $columnInfos = $connection->getSchemaInformation()->listTableColumnInfos($tableName); + $autoIncrementColumnName = null; + foreach ($columnInfos as $columnInfo) { + if ($columnInfo->autoincrement) { + $autoIncrementColumnName = $columnInfo->name; + break; + } + } foreach ($dataSet->getElements($tableName) as $element) { // Some DBMS like postgresql are picky about inserting blob types with correct cast, setting // types correctly (like Connection::PARAM_LOB) allows doctrine to create valid SQL $types = []; foreach ($element as $columnName => $columnValue) { - $types[$columnName] = $columnType = $tableDetails->getColumn($columnName)->getType(); + $types[$columnName] = $columnType = $columnInfos[$columnName]->getType(); // JSON-Field data is converted (json-encode'd) within $connection->insert(), and since json field // data can only be provided json encoded in the csv dataset files, we need to decode them here. if ($columnValue !== null && $columnType instanceof JsonType) { @@ -86,7 +92,9 @@ public static function import(string $path): void // Insert the row $connection->insert($tableName, $element, $types); } - Testbase::resetTableSequences($connection, $tableName); + if ($autoIncrementColumnName !== null) { + Testbase::resetTableSequences($connection, $tableName, $autoIncrementColumnName); + } } } diff --git a/Classes/Core/Testbase.php b/Classes/Core/Testbase.php index 9fc1f898..ffbc2a0a 100644 --- a/Classes/Core/Testbase.php +++ b/Classes/Core/Testbase.php @@ -929,14 +929,27 @@ public function createDatabaseStructure(ContainerInterface $container): void } /** - * Perform post processing of database tables after an insert has been performed. - * Doing this once per insert is rather slow, but due to the soft reference behavior - * this needs to be done after every row to ensure consistent results. + * Synchronize an auto-increment sequence after inserting records with explicit IDs. */ - public static function resetTableSequences(Connection $connection, string $tableName): void - { + public static function resetTableSequences( + Connection $connection, + string $tableName, + ?string $autoIncrementColumnName = null + ): void { $platform = $connection->getDatabasePlatform(); if ($platform instanceof DoctrinePostgreSQLPlatform) { + if ($autoIncrementColumnName !== null) { + $connection->executeStatement( + sprintf( + 'SELECT SETVAL(PG_GET_SERIAL_SEQUENCE(%s, %s), COALESCE(MAX(%s), 0)+1, FALSE) FROM %s', + $connection->quote($connection->quoteIdentifier($tableName)), + $connection->quote($autoIncrementColumnName), + $connection->quoteIdentifier($autoIncrementColumnName), + $connection->quoteIdentifier($tableName) + ) + ); + return; + } $queryBuilder = $connection->createQueryBuilder(); $queryBuilder->getRestrictions()->removeAll(); $row = $queryBuilder->select('PGT.schemaname', 'S.relname', 'C.attname', 'T.relname AS tablename')