diff --git a/API/API.csproj b/API/API.csproj
index fbf15067e..759f1ae86 100644
--- a/API/API.csproj
+++ b/API/API.csproj
@@ -49,13 +49,13 @@
-
+
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/API/Program.cs b/API/Program.cs
index 4ed8ce56a..286a0f0cd 100644
--- a/API/Program.cs
+++ b/API/Program.cs
@@ -62,7 +62,15 @@ namespace API
if (pendingMigrations.Any())
{
logger.LogInformation("Performing backup as migrations are needed. Backup will be kavita.db in temp folder");
- directoryService.CopyFileToDirectory(directoryService.FileSystem.Path.Join(directoryService.ConfigDirectory, "kavita.db"), directoryService.TempDirectory);
+ var migrationDirectory = await GetMigrationDirectory(context, directoryService);
+ directoryService.ExistOrCreate(migrationDirectory);
+
+ if (!directoryService.FileSystem.File.Exists(
+ directoryService.FileSystem.Path.Join(migrationDirectory, "kavita.db")))
+ {
+ directoryService.CopyFileToDirectory(directoryService.FileSystem.Path.Join(directoryService.ConfigDirectory, "kavita.db"), migrationDirectory);
+ logger.LogInformation("Database backed up to {MigrationDirectory}", migrationDirectory);
+ }
}
await context.Database.MigrateAsync();
@@ -82,12 +90,42 @@ namespace API
catch (Exception ex)
{
var logger = services.GetRequiredService>();
- logger.LogCritical(ex, "An error occurred during migration");
+ var context = services.GetRequiredService();
+ var migrationDirectory = await GetMigrationDirectory(context, directoryService);
+
+ logger.LogCritical(ex, "A migration failed during startup. Restoring backup from {MigrationDirectory} and exiting", migrationDirectory);
+ directoryService.CopyFileToDirectory(directoryService.FileSystem.Path.Join(migrationDirectory, "kavita.db"), directoryService.ConfigDirectory);
+
+ return;
}
await host.RunAsync();
}
+ private static async Task GetMigrationDirectory(DataContext context, IDirectoryService directoryService)
+ {
+ string currentVersion = null;
+ try
+ {
+ currentVersion =
+ (await context.ServerSetting.SingleOrDefaultAsync(s =>
+ s.Key == ServerSettingKey.InstallVersion))?.Value;
+ }
+ catch
+ {
+ // ignored
+ }
+
+ if (string.IsNullOrEmpty(currentVersion))
+ {
+ currentVersion = "vUnknown";
+ }
+
+ var migrationDirectory = directoryService.FileSystem.Path.Join(directoryService.TempDirectory,
+ "migration", currentVersion);
+ return migrationDirectory;
+ }
+
private static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>