diff --git a/pkgs/servers/web-apps/kavita/default.nix b/pkgs/servers/web-apps/kavita/default.nix index 44c0ad59cda2..7873ee684014 100644 --- a/pkgs/servers/web-apps/kavita/default.nix +++ b/pkgs/servers/web-apps/kavita/default.nix @@ -34,6 +34,12 @@ stdenvNoCC.mkDerivation (finalAttrs: { }) # The webroot is hardcoded as ./wwwroot ./change-webroot.diff + # Upstream removes database migrations between versions + # Restore them to avoid breaking on updates + # Info: Restores migrations for versions between v0.7.1.4 and v0.7.9 + # On update: check if more migrations need to be restored! + # Migrations should at least allow updates from previous NixOS versions + ./restore-migrations.diff ]; postPatch = '' substituteInPlace API/Services/DirectoryService.cs --subst-var out diff --git a/pkgs/servers/web-apps/kavita/restore-migrations.diff b/pkgs/servers/web-apps/kavita/restore-migrations.diff new file mode 100644 index 000000000000..d158f503e329 --- /dev/null +++ b/pkgs/servers/web-apps/kavita/restore-migrations.diff @@ -0,0 +1,147 @@ +diff --git a/API/Data/ManualMigrations/MigrateDisableScrobblingOnComicLibraries.cs b/API/Data/ManualMigrations/MigrateDisableScrobblingOnComicLibraries.cs +new file mode 100644 +index 00000000..0de7bf5d +--- /dev/null ++++ b/API/Data/ManualMigrations/MigrateDisableScrobblingOnComicLibraries.cs +@@ -0,0 +1,38 @@ ++using System.Linq; ++using System.Threading.Tasks; ++using API.Entities.Enums; ++using Microsoft.EntityFrameworkCore; ++using Microsoft.Extensions.Logging; ++ ++namespace API.Data.ManualMigrations; ++ ++/// ++/// v0.7.4 introduced Scrobbling with Kavita+. By default, it is on, but Comic libraries have no scrobble providers, so disable ++/// ++public static class MigrateDisableScrobblingOnComicLibraries ++{ ++ public static async Task Migrate(IUnitOfWork unitOfWork, DataContext dataContext, ILogger logger) ++ { ++ if (!await dataContext.Library.Where(s => s.Type == LibraryType.Comic).Where(l => l.AllowScrobbling).AnyAsync()) ++ { ++ return; ++ } ++ logger.LogInformation("Running MigrateDisableScrobblingOnComicLibraries migration. Please be patient, this may take some time"); ++ ++ ++ foreach (var lib in await dataContext.Library.Where(s => s.Type == LibraryType.Comic).Where(l => l.AllowScrobbling).ToListAsync()) ++ { ++ lib.AllowScrobbling = false; ++ unitOfWork.LibraryRepository.Update(lib); ++ } ++ ++ if (unitOfWork.HasChanges()) ++ { ++ await unitOfWork.CommitAsync(); ++ } ++ ++ logger.LogInformation("MigrateDisableScrobblingOnComicLibraries migration finished"); ++ ++ } ++ ++} +diff --git a/API/Data/ManualMigrations/MigrateLoginRoles.cs b/API/Data/ManualMigrations/MigrateLoginRoles.cs +new file mode 100644 +index 00000000..f649908a +--- /dev/null ++++ b/API/Data/ManualMigrations/MigrateLoginRoles.cs +@@ -0,0 +1,36 @@ ++using System.Threading.Tasks; ++using API.Constants; ++using API.Entities; ++using Microsoft.AspNetCore.Identity; ++using Microsoft.Extensions.Logging; ++ ++namespace API.Data.ManualMigrations; ++ ++/// ++/// Added in v0.7.1.18 ++/// ++public static class MigrateLoginRoles ++{ ++ /// ++ /// Will not run if any users have the role already ++ /// ++ /// ++ /// ++ /// ++ public static async Task Migrate(IUnitOfWork unitOfWork, UserManager userManager, ILogger logger) ++ { ++ var usersWithRole = await userManager.GetUsersInRoleAsync(PolicyConstants.LoginRole); ++ if (usersWithRole.Count != 0) return; ++ ++ logger.LogCritical("Running MigrateLoginRoles migration"); ++ ++ var allUsers = await unitOfWork.UserRepository.GetAllUsersAsync(); ++ foreach (var user in allUsers) ++ { ++ await userManager.RemoveFromRoleAsync(user, PolicyConstants.LoginRole); ++ await userManager.AddToRoleAsync(user, PolicyConstants.LoginRole); ++ } ++ ++ logger.LogInformation("MigrateLoginRoles migration complete"); ++ } ++} +diff --git a/API/Data/ManualMigrations/MigrateRemoveWebPSettingRows.cs b/API/Data/ManualMigrations/MigrateRemoveWebPSettingRows.cs +new file mode 100644 +index 00000000..07e98ef6 +--- /dev/null ++++ b/API/Data/ManualMigrations/MigrateRemoveWebPSettingRows.cs +@@ -0,0 +1,31 @@ ++using System.Threading.Tasks; ++using API.Entities.Enums; ++using Microsoft.Extensions.Logging; ++ ++namespace API.Data.ManualMigrations; ++ ++/// ++/// Added in v0.7.2.7/v0.7.3 in which the ConvertXToWebP Setting keys were removed. This migration will remove them. ++/// ++public static class MigrateRemoveWebPSettingRows ++{ ++ public static async Task Migrate(IUnitOfWork unitOfWork, ILogger logger) ++ { ++ logger.LogCritical("Running MigrateRemoveWebPSettingRows migration - Please be patient, this may take some time. This is not an error"); ++ ++ var key = await unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.ConvertBookmarkToWebP); ++ var key2 = await unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.ConvertCoverToWebP); ++ if (key == null && key2 == null) ++ { ++ logger.LogCritical("Running MigrateRemoveWebPSettingRows migration - complete. Nothing to do"); ++ return; ++ } ++ ++ unitOfWork.SettingsRepository.Remove(key); ++ unitOfWork.SettingsRepository.Remove(key2); ++ ++ await unitOfWork.CommitAsync(); ++ ++ logger.LogCritical("Running MigrateRemoveWebPSettingRows migration - Completed. This is not an error"); ++ } ++} +diff --git a/API/Startup.cs b/API/Startup.cs +index 21c4fa45..04f4a077 100644 +--- a/API/Startup.cs ++++ b/API/Startup.cs +@@ -232,11 +232,19 @@ public class Startup + Task.Run(async () => + { + // Apply all migrations on startup ++ var userManager = serviceProvider.GetRequiredService>(); + var dataContext = serviceProvider.GetRequiredService(); + + + logger.LogInformation("Running Migrations"); + ++ // v0.7.2 ++ await MigrateLoginRoles.Migrate(unitOfWork, userManager, logger); ++ // v0.7.3 ++ await MigrateRemoveWebPSettingRows.Migrate(unitOfWork, logger); ++ // v0.7.4 ++ await MigrateDisableScrobblingOnComicLibraries.Migrate(unitOfWork, dataContext, logger); ++ + // v0.7.9 + await MigrateUserLibrarySideNavStream.Migrate(unitOfWork, dataContext, logger); +