importer 4
This commit is contained in:
@@ -429,19 +429,18 @@ final class SchemaManager
|
|||||||
$this->pdo->beginTransaction();
|
$this->pdo->beginTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
$executed = 0;
|
$normalizedStatements = [];
|
||||||
foreach ($statements as $statement) {
|
foreach ($statements as $statement) {
|
||||||
$trimmed = trim($statement);
|
$trimmed = trim($statement);
|
||||||
if ($trimmed === '') {
|
if ($trimmed === '') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$normalizedStatement = $this->normalizeImportStatement($trimmed);
|
$normalizedStatements[] = $this->normalizeImportStatement($trimmed);
|
||||||
$currentStatement = $normalizedStatement;
|
|
||||||
$this->pdo->exec($normalizedStatement);
|
|
||||||
$executed++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$executed = $this->executeImportPass($normalizedStatements, $currentStatement);
|
||||||
|
|
||||||
if ($useTransaction && $this->pdo->inTransaction()) {
|
if ($useTransaction && $this->pdo->inTransaction()) {
|
||||||
$this->pdo->commit();
|
$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
|
private function normalizeImportStatement(string $statement): string
|
||||||
{
|
{
|
||||||
if ($this->driver !== 'pgsql') {
|
if ($this->driver !== 'pgsql') {
|
||||||
|
|||||||
Reference in New Issue
Block a user