From 21fdf22df6b58a2668cfea317401dc92e6973bb3 Mon Sep 17 00:00:00 2001 From: Wouter Wolters Date: Mon, 17 Aug 2026 20:22:16 +0200 Subject: [PATCH] [TASK] Bulk insert functional test data sets Functional CSV data sets currently execute one INSERT statement for every row. Large fixtures therefore spend most of their setup time on database round trips. Resolve column types once per table, keep the required JSON conversion, and pass all rows to Connection::bulkInsert(). The connection automatically splits statements at the platform parameter limit, while empty data sets and sequence resets retain their existing behavior. For the 743-row RootlineUtility fixture, this reduces runtime by 28% on PostgreSQL, 48% on SQLite, and 80% on MariaDB. --- .../Framework/DataHandling/DataSet.php | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/Classes/Core/Functional/Framework/DataHandling/DataSet.php b/Classes/Core/Functional/Framework/DataHandling/DataSet.php index e079ddc0..623d6499 100644 --- a/Classes/Core/Functional/Framework/DataHandling/DataSet.php +++ b/Classes/Core/Functional/Framework/DataHandling/DataSet.php @@ -71,20 +71,23 @@ public static function import(string $path): void $platform = $connection->getDatabasePlatform(); // @todo Check if we can use the cached schema information here instead. $tableDetails = $connection->createSchemaManager()->introspectTable($tableName); - 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 + $fields = $dataSet->getFields($tableName); + $elements = $dataSet->getElements($tableName); + if ($fields !== null && $elements !== []) { $types = []; - foreach ($element as $columnName => $columnValue) { + foreach ($fields as $columnName) { $types[$columnName] = $columnType = $tableDetails->getColumn($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) { - $element[$columnName] = $columnType->convertToPHPValue($columnValue, $platform); + if ($columnType instanceof JsonType) { + // JSON values in CSV files are encoded and must be converted before insertion. + foreach ($elements as &$element) { + if ($element[$columnName] !== null) { + $element[$columnName] = $columnType->convertToPHPValue($element[$columnName], $platform); + } + } + unset($element); } } - // Insert the row - $connection->insert($tableName, $element, $types); + $connection->bulkInsert($tableName, $elements, $fields, $types); } Testbase::resetTableSequences($connection, $tableName); }