importer 4
All checks were successful
Deploy / deploy-staging (push) Successful in 5s
Deploy / deploy-production (push) Has been skipped

This commit is contained in:
2026-04-11 03:13:37 +02:00
parent e2e87016ad
commit 7d0ad8eb29

View File

@@ -429,19 +429,18 @@ final class SchemaManager
$this->pdo->beginTransaction();
}
$executed = 0;
$normalizedStatements = [];
foreach ($statements as $statement) {
$trimmed = trim($statement);
if ($trimmed === '') {
continue;
}
$normalizedStatement = $this->normalizeImportStatement($trimmed);
$currentStatement = $normalizedStatement;
$this->pdo->exec($normalizedStatement);
$executed++;
$normalizedStatements[] = $this->normalizeImportStatement($trimmed);
}
$executed = $this->executeImportPass($normalizedStatements, $currentStatement);
if ($useTransaction && $this->pdo->inTransaction()) {
$this->pdo->commit();
}
@@ -464,6 +463,65 @@ final class SchemaManager
}
}
/**
* @param list<string> $statements
*/
private function executeImportPass(array $statements, ?string &$currentStatement): int
{
$pendingStatements = $statements;
$executed = 0;
$maxPasses = max(1, count($pendingStatements));
for ($pass = 0; $pass < $maxPasses && $pendingStatements !== []; $pass++) {
$deferredStatements = [];
$progressMade = false;
foreach ($pendingStatements as $statement) {
$currentStatement = $statement;
try {
$this->pdo->exec($statement);
$executed++;
$progressMade = true;
} catch (\Throwable $exception) {
if ($this->shouldRetryDeferredImportStatement($exception, $statement)) {
$deferredStatements[] = $statement;
continue;
}
throw $exception;
}
}
if ($deferredStatements === []) {
return $executed;
}
if (!$progressMade) {
$currentStatement = $deferredStatements[0];
$this->pdo->exec($deferredStatements[0]);
}
$pendingStatements = $deferredStatements;
}
return $executed;
}
private function shouldRetryDeferredImportStatement(\Throwable $exception, string $statement): bool
{
if ($this->driver !== 'pgsql') {
return false;
}
if (!preg_match('/^(INSERT|COPY)\\b/i', ltrim($statement))) {
return false;
}
$errorCode = (string) $exception->getCode();
return $errorCode === '23503';
}
private function normalizeImportStatement(string $statement): string
{
if ($this->driver !== 'pgsql') {