diff --git a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultCreateNewDatabaseUseCase.java b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultCreateNewDatabaseUseCase.java index 2ed78de..c574dc9 100644 --- a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultCreateNewDatabaseUseCase.java +++ b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultCreateNewDatabaseUseCase.java @@ -41,7 +41,9 @@ import de.gecheckt.pdf.umbenenner.application.port.out.DatabaseCreationPort; * Aktive DB und Zielpfad werden über {@link Path#toRealPath(java.nio.file.LinkOption...)} * normalisiert verglichen. Für noch nicht existierende Dateien wird das Elternverzeichnis * real aufgelöst und der Dateiname normalisiert verglichen. Auf Windows erfolgt der - * Vergleich case-insensitive. + * Vergleich case-insensitive. Ist aktuell keine aktive Datenbank in Betrieb (der + * {@link ActiveDatabasePathSupplier} liefert {@code null}), entfällt die Prüfung und die + * Anlage fährt fort – es gibt dann keine in Benutzung befindliche Datei zu schützen. */ public class DefaultCreateNewDatabaseUseCase implements CreateNewDatabaseUseCase { @@ -66,7 +68,9 @@ public class DefaultCreateNewDatabaseUseCase implements CreateNewDatabaseUseCase /** * Liefert den Pfad der aktuell aktiven SQLite-Datei. * - * @return den absoluten Pfad der aktiven Datei; nie {@code null} + * @return den absoluten Pfad der aktiven Datei oder {@code null}, wenn aktuell keine + * aktive Datenbank in Betrieb ist. Bei {@code null} entfällt die + * Selbst-Überschreib-Prüfung und die Anlage darf fortfahren. */ Path get(); } @@ -95,6 +99,9 @@ public class DefaultCreateNewDatabaseUseCase implements CreateNewDatabaseUseCase /** * Orchestriert den vollständigen Anlage- und Wechselvorgang. + *
+ * Liefert der {@link ActiveDatabasePathSupplier} {@code null} (keine aktive Datenbank in
+ * Betrieb), entfällt die Selbst-Überschreib-Prüfung und die Anlage fährt fort.
*
* @param targetFile der vom Benutzer ausgewählte Zielpfad; darf nicht {@code null} sein
* @return strukturiertes Ergebnis mit Erfolg oder klassifiziertem Fehler; nie {@code null}
@@ -106,29 +113,29 @@ public class DefaultCreateNewDatabaseUseCase implements CreateNewDatabaseUseCase
LOG.info("Neue Datenbank anlegen: angeforderter Zielpfad = {}", absoluteTarget);
// Schritt 1: Pfad-Sicherheitsprüfung
+ // Ohne aktive Datenbank (Supplier liefert null) gibt es nichts zu schützen; die
+ // Selbst-Überschreib-Prüfung entfällt und die Anlage darf fortfahren.
Path activeDb = activeDatabasePathSupplier.get();
if (activeDb == null) {
- LOG.error("Aktiver Datenbankpfad ist nicht ermittelbar – Anlage abgebrochen.");
- return new CreateNewDatabaseResult.CreationFailed(
- CreateNewDatabaseResult.Phase.PATH_RESOLUTION,
- "Aktiver Datenbankpfad konnte nicht ermittelt werden.",
- null);
- }
- Path absoluteActive = activeDb.toAbsolutePath().normalize();
- boolean sameFile;
- try {
- sameFile = isSameFile(absoluteActive, absoluteTarget);
- } catch (IOException e) {
- LOG.error("Pfad-Sicherheitsprüfung fehlgeschlagen: {}", e.getMessage(), e);
- return new CreateNewDatabaseResult.CreationFailed(
- CreateNewDatabaseResult.Phase.PATH_RESOLUTION,
- "Pfad-Sicherheitsprüfung fehlgeschlagen: " + e.getMessage(),
- e);
- }
- if (sameFile) {
- LOG.warn("Anlage abgelehnt: Zielpfad entspricht der aktuell aktiven Datenbank: {}",
- absoluteTarget);
- return new CreateNewDatabaseResult.SameAsActiveDatabase(absoluteTarget);
+ LOG.info("Keine aktive Datenbank in Betrieb – Selbst-Überschreib-Prüfung entfällt, "
+ + "Anlage fährt fort.");
+ } else {
+ Path absoluteActive = activeDb.toAbsolutePath().normalize();
+ boolean sameFile;
+ try {
+ sameFile = isSameFile(absoluteActive, absoluteTarget);
+ } catch (IOException e) {
+ LOG.error("Pfad-Sicherheitsprüfung fehlgeschlagen: {}", e.getMessage(), e);
+ return new CreateNewDatabaseResult.CreationFailed(
+ CreateNewDatabaseResult.Phase.PATH_RESOLUTION,
+ "Pfad-Sicherheitsprüfung fehlgeschlagen: " + e.getMessage(),
+ e);
+ }
+ if (sameFile) {
+ LOG.warn("Anlage abgelehnt: Zielpfad entspricht der aktuell aktiven Datenbank: {}",
+ absoluteTarget);
+ return new CreateNewDatabaseResult.SameAsActiveDatabase(absoluteTarget);
+ }
}
// Schritt 2: Temp-Datei im Zielverzeichnis vorbereiten
diff --git a/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultCreateNewDatabaseUseCaseTest.java b/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultCreateNewDatabaseUseCaseTest.java
index bbdd1d0..1b80dc6 100644
--- a/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultCreateNewDatabaseUseCaseTest.java
+++ b/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultCreateNewDatabaseUseCaseTest.java
@@ -168,6 +168,63 @@ class DefaultCreateNewDatabaseUseCaseTest {
assertThat(contextOverride.get()).isEqualTo(target.toAbsolutePath().normalize());
}
+ @Test
+ void createNewDatabase_shouldProceed_whenNoActiveDatabase(@TempDir Path tempDir) throws IOException {
+ // Szenario: GUI ohne geladene Konfiguration und ohne Override → Supplier liefert null.
+ // Es gibt keine aktive DB zu schützen; die Anlage muss durchlaufen.
+ Path target = tempDir.resolve("neu.sqlite");
+
+ AtomicReference
* Pfad-Validierungs- und Move-Schritte verbleiben im Use-Case; der Adapter führt
* Anlage, Migration und Verbindungstest aus.
@@ -2061,9 +2064,10 @@ public class BootstrapRunner {
return override.get();
}
if (configFilePath == null || !Files.exists(configFilePath)) {
- // Ohne Konfiguration und ohne Override: Zielpfad selbst als „aktiv" werten,
- // damit die Pfadprüfung nur das Selbst-Überschreiben verhindert.
- return targetFile.toAbsolutePath().normalize();
+ // Ohne Override und ohne geladene Konfiguration existiert keine aktive
+ // Datenbank. null signalisiert dem Use-Case: keine Selbst-Überschreib-Prüfung
+ // nötig, die Anlage darf fortfahren.
+ return null;
}
try {
migrateConfigurationIfNeeded(configFilePath);
@@ -2071,9 +2075,9 @@ public class BootstrapRunner {
return config.sqliteFile().toAbsolutePath().normalize();
} catch (Exception e) {
LOG.warn("GUI-Datenbankanlage: aktive DB konnte nicht aus {} ermittelt werden: {} — "
- + "Zielpfad wird stattdessen als aktiv angenommen.",
+ + "es wird keine aktive DB angenommen.",
configFilePath, e.getMessage());
- return targetFile.toAbsolutePath().normalize();
+ return null;
}
};
DefaultCreateNewDatabaseUseCase useCase = new DefaultCreateNewDatabaseUseCase(