diff --git a/partials/landingpages/modules/index.php b/partials/landingpages/modules/index.php
index 62570b2..6d7d371 100644
--- a/partials/landingpages/modules/index.php
+++ b/partials/landingpages/modules/index.php
@@ -23,6 +23,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
Module
Module verwalten
Hier siehst du nur aktive Module. Installierte Module kannst du unten verwalten.
+
+ Zentralen SQL-Import oeffnen
+
diff --git a/src/App/SqlDataImporter.php b/src/App/SqlDataImporter.php
index 90e2af3..0bfd26b 100644
--- a/src/App/SqlDataImporter.php
+++ b/src/App/SqlDataImporter.php
@@ -74,7 +74,7 @@ final class SqlDataImporter
foreach ($pendingStatements as $statement) {
try {
- $this->pdo->exec($statement);
+ $this->execStatementWithRecovery($statement);
$executed++;
$progressMade = true;
} catch (\Throwable $exception) {
@@ -93,7 +93,7 @@ final class SqlDataImporter
if (!$progressMade) {
try {
- $this->pdo->exec($deferredStatements[0]);
+ $this->execStatementWithRecovery($deferredStatements[0]);
} catch (\Throwable $exception) {
throw new \RuntimeException($deferredStatements[0], 0, $exception);
}
@@ -105,6 +105,30 @@ final class SqlDataImporter
return $executed;
}
+ private function execStatementWithRecovery(string $statement): void
+ {
+ if ($this->driver !== 'pgsql' || !$this->pdo->inTransaction()) {
+ $this->pdo->exec($statement);
+ return;
+ }
+
+ $savepoint = 'sql_import_' . substr(sha1($statement . microtime(true)), 0, 12);
+ $this->pdo->exec('SAVEPOINT ' . $savepoint);
+
+ try {
+ $this->pdo->exec($statement);
+ $this->pdo->exec('RELEASE SAVEPOINT ' . $savepoint);
+ } catch (\Throwable $exception) {
+ try {
+ $this->pdo->exec('ROLLBACK TO SAVEPOINT ' . $savepoint);
+ $this->pdo->exec('RELEASE SAVEPOINT ' . $savepoint);
+ } catch (\Throwable) {
+ }
+
+ throw $exception;
+ }
+ }
+
private function shouldRetryDeferredImportStatement(\Throwable $exception, string $statement): bool
{
if ($this->driver !== 'pgsql') {