From 200528cbe935f8f35229e5c2d0c6878ba518013f 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, 15 insertions(+), 8 deletions(-) diff --git a/Classes/Core/Functional/Framework/DataHandling/DataSet.php b/Classes/Core/Functional/Framework/DataHandling/DataSet.php index ade2f3d1..3390c36c 100644 --- a/Classes/Core/Functional/Framework/DataHandling/DataSet.php +++ b/Classes/Core/Functional/Framework/DataHandling/DataSet.php @@ -77,20 +77,27 @@ public static function import(string $path): void break; } } - foreach ($dataSet->getElements($tableName) as $element) { + $fields = $dataSet->getFields($tableName); + $elements = $dataSet->getElements($tableName); + if ($fields !== null && $elements !== []) { // 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) { + foreach ($fields as $columnName) { $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) { - $element[$columnName] = $columnType->convertToPHPValue($columnValue, $platform); + // JSON-Field data is converted (json-encode'd) within $connection->bulkInsert(), and since json + // field data can only be provided json encoded in the csv dataset files, we need to decode them + // here. + if ($columnType instanceof JsonType) { + 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); } if ($autoIncrementColumnName !== null) { Testbase::resetTableSequences($connection, $tableName, $autoIncrementColumnName);