Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions Classes/Core/Functional/Framework/DataHandling/DataSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
}
}
}

Expand Down
23 changes: 18 additions & 5 deletions Classes/Core/Testbase.php
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down