importer 4
This commit is contained in:
@@ -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') {
|
||||
|
||||
Reference in New Issue
Block a user