From 12889be788aed073c917e636071ec9a73b78e3d7 Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Fri, 17 Dec 2021 12:46:01 -0600 Subject: [PATCH] Fixes v0.4.19! (#855) * Fixed OPDS urls to work with new Filtering schema * Fixed a rendering issue with Language tag when it's null * Fixed a bug where locked covers were resetting during refresh metadata. * Redid all the migrations and put some extra checks due to a bad migration from previous release (EF Core was producing an error). * Fixed a bug which didn't take sort direction when not changing sort field * Default installs now backup daily --- API/API.csproj | 6 +- API/Controllers/OPDSController.cs | 21 +- .../20211214000230_SeriesIncludes.Designer.cs | 1228 --------------- .../20211214000230_SeriesIncludes.cs | 57 - ...216150752_seriesAndChapterTags.Designer.cs | 1311 ----------------- .../20211216191436_seriesLanguage.cs | 25 - ...211217180457_filteringChanges.Designer.cs} | 6 +- ....cs => 20211217180457_filteringChanges.cs} | 54 +- .../Migrations/DataContextModelSnapshot.cs | 2 +- API/Data/Seed.cs | 2 +- .../ApplicationServiceExtensions.cs | 1 + API/Helpers/CacheHelper.cs | 2 +- API/Program.cs | 20 +- .../StartupTasksHostedService.cs | 2 +- API/Services/TaskScheduler.cs | 8 +- .../card-detail-layout.component.ts | 9 +- .../library-detail.component.html | 2 +- .../series-metadata-detail.component.html | 2 +- 18 files changed, 110 insertions(+), 2648 deletions(-) delete mode 100644 API/Data/Migrations/20211214000230_SeriesIncludes.Designer.cs delete mode 100644 API/Data/Migrations/20211214000230_SeriesIncludes.cs delete mode 100644 API/Data/Migrations/20211216150752_seriesAndChapterTags.Designer.cs delete mode 100644 API/Data/Migrations/20211216191436_seriesLanguage.cs rename API/Data/Migrations/{20211216191436_seriesLanguage.Designer.cs => 20211217180457_filteringChanges.Designer.cs} (99%) rename API/Data/Migrations/{20211216150752_seriesAndChapterTags.cs => 20211217180457_filteringChanges.cs} (67%) diff --git a/API/API.csproj b/API/API.csproj index 05c3fa130..92671bce9 100644 --- a/API/API.csproj +++ b/API/API.csproj @@ -49,13 +49,13 @@ - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/API/Controllers/OPDSController.cs b/API/Controllers/OPDSController.cs index 57a5c13d5..68b9c14a2 100644 --- a/API/Controllers/OPDSController.cs +++ b/API/Controllers/OPDSController.cs @@ -34,7 +34,26 @@ public class OpdsController : BaseApiController private const string Prefix = "/api/opds/"; private readonly FilterDto _filterDto = new FilterDto() { - Formats = new List() + Formats = new List(), + Character = new List(), + Colorist = new List(), + Editor = new List(), + Genres = new List(), + Inker = new List(), + Languages = new List(), + Letterer = new List(), + Penciller = new List(), + Libraries = new List(), + Publisher = new List(), + Rating = 0, + Tags = new List(), + Translators = new List(), + Writers = new List(), + AgeRating = new List(), + CollectionTags = new List(), + CoverArtist = new List(), + ReadStatus = new ReadStatus(), + SortOptions = null }; private readonly ChapterSortComparer _chapterSortComparer = new ChapterSortComparer(); diff --git a/API/Data/Migrations/20211214000230_SeriesIncludes.Designer.cs b/API/Data/Migrations/20211214000230_SeriesIncludes.Designer.cs deleted file mode 100644 index 64a21a956..000000000 --- a/API/Data/Migrations/20211214000230_SeriesIncludes.Designer.cs +++ /dev/null @@ -1,1228 +0,0 @@ -// -using System; -using API.Data; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace API.Data.Migrations -{ - [DbContext(typeof(DataContext))] - [Migration("20211214000230_SeriesIncludes")] - partial class SeriesIncludes - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); - - modelBuilder.Entity("API.Entities.AppRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("TEXT"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("TEXT"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex"); - - b.ToTable("AspNetRoles", (string)null); - }); - - modelBuilder.Entity("API.Entities.AppUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AccessFailedCount") - .HasColumnType("INTEGER"); - - b.Property("ApiKey") - .HasColumnType("TEXT"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("TEXT"); - - b.Property("Created") - .HasColumnType("TEXT"); - - b.Property("Email") - .HasMaxLength(256) - .HasColumnType("TEXT"); - - b.Property("EmailConfirmed") - .HasColumnType("INTEGER"); - - b.Property("LastActive") - .HasColumnType("TEXT"); - - b.Property("LockoutEnabled") - .HasColumnType("INTEGER"); - - b.Property("LockoutEnd") - .HasColumnType("TEXT"); - - b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("TEXT"); - - b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("TEXT"); - - b.Property("PasswordHash") - .HasColumnType("TEXT"); - - b.Property("PhoneNumber") - .HasColumnType("TEXT"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("INTEGER"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .HasColumnType("INTEGER"); - - b.Property("SecurityStamp") - .HasColumnType("TEXT"); - - b.Property("TwoFactorEnabled") - .HasColumnType("INTEGER"); - - b.Property("UserName") - .HasMaxLength(256) - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex"); - - b.ToTable("AspNetUsers", (string)null); - }); - - modelBuilder.Entity("API.Entities.AppUserBookmark", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AppUserId") - .HasColumnType("INTEGER"); - - b.Property("ChapterId") - .HasColumnType("INTEGER"); - - b.Property("Page") - .HasColumnType("INTEGER"); - - b.Property("SeriesId") - .HasColumnType("INTEGER"); - - b.Property("VolumeId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("AppUserId"); - - b.ToTable("AppUserBookmark"); - }); - - modelBuilder.Entity("API.Entities.AppUserPreferences", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AppUserId") - .HasColumnType("INTEGER"); - - b.Property("AutoCloseMenu") - .HasColumnType("INTEGER"); - - b.Property("BookReaderDarkMode") - .HasColumnType("INTEGER"); - - b.Property("BookReaderFontFamily") - .HasColumnType("TEXT"); - - b.Property("BookReaderFontSize") - .HasColumnType("INTEGER"); - - b.Property("BookReaderLineSpacing") - .HasColumnType("INTEGER"); - - b.Property("BookReaderMargin") - .HasColumnType("INTEGER"); - - b.Property("BookReaderReadingDirection") - .HasColumnType("INTEGER"); - - b.Property("BookReaderTapToPaginate") - .HasColumnType("INTEGER"); - - b.Property("PageSplitOption") - .HasColumnType("INTEGER"); - - b.Property("ReaderMode") - .HasColumnType("INTEGER"); - - b.Property("ReadingDirection") - .HasColumnType("INTEGER"); - - b.Property("ScalingOption") - .HasColumnType("INTEGER"); - - b.Property("SiteDarkMode") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("AppUserId") - .IsUnique(); - - b.ToTable("AppUserPreferences"); - }); - - modelBuilder.Entity("API.Entities.AppUserProgress", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AppUserId") - .HasColumnType("INTEGER"); - - b.Property("BookScrollId") - .HasColumnType("TEXT"); - - b.Property("ChapterId") - .HasColumnType("INTEGER"); - - b.Property("Created") - .HasColumnType("TEXT"); - - b.Property("LastModified") - .HasColumnType("TEXT"); - - b.Property("PagesRead") - .HasColumnType("INTEGER"); - - b.Property("SeriesId") - .HasColumnType("INTEGER"); - - b.Property("VolumeId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("AppUserId"); - - b.HasIndex("SeriesId"); - - b.ToTable("AppUserProgresses"); - }); - - modelBuilder.Entity("API.Entities.AppUserRating", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AppUserId") - .HasColumnType("INTEGER"); - - b.Property("Rating") - .HasColumnType("INTEGER"); - - b.Property("Review") - .HasColumnType("TEXT"); - - b.Property("SeriesId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("AppUserId"); - - b.HasIndex("SeriesId"); - - b.ToTable("AppUserRating"); - }); - - modelBuilder.Entity("API.Entities.AppUserRole", b => - { - b.Property("UserId") - .HasColumnType("INTEGER"); - - b.Property("RoleId") - .HasColumnType("INTEGER"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("API.Entities.Chapter", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AgeRating") - .HasColumnType("INTEGER"); - - b.Property("CoverImage") - .HasColumnType("TEXT"); - - b.Property("CoverImageLocked") - .HasColumnType("INTEGER"); - - b.Property("Created") - .HasColumnType("TEXT"); - - b.Property("GenreId") - .HasColumnType("INTEGER"); - - b.Property("IsSpecial") - .HasColumnType("INTEGER"); - - b.Property("LastModified") - .HasColumnType("TEXT"); - - b.Property("Number") - .HasColumnType("TEXT"); - - b.Property("Pages") - .HasColumnType("INTEGER"); - - b.Property("Range") - .HasColumnType("TEXT"); - - b.Property("ReleaseDate") - .HasColumnType("TEXT"); - - b.Property("Title") - .HasColumnType("TEXT"); - - b.Property("TitleName") - .HasColumnType("TEXT"); - - b.Property("VolumeId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("GenreId"); - - b.HasIndex("VolumeId"); - - b.ToTable("Chapter"); - }); - - modelBuilder.Entity("API.Entities.CollectionTag", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CoverImage") - .HasColumnType("TEXT"); - - b.Property("CoverImageLocked") - .HasColumnType("INTEGER"); - - b.Property("NormalizedTitle") - .HasColumnType("TEXT"); - - b.Property("Promoted") - .HasColumnType("INTEGER"); - - b.Property("RowVersion") - .HasColumnType("INTEGER"); - - b.Property("Summary") - .HasColumnType("TEXT"); - - b.Property("Title") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("Id", "Promoted") - .IsUnique(); - - b.ToTable("CollectionTag"); - }); - - modelBuilder.Entity("API.Entities.FolderPath", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("LastScanned") - .HasColumnType("TEXT"); - - b.Property("LibraryId") - .HasColumnType("INTEGER"); - - b.Property("Path") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("LibraryId"); - - b.ToTable("FolderPath"); - }); - - modelBuilder.Entity("API.Entities.Genre", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ExternalTag") - .HasColumnType("INTEGER"); - - b.Property("NormalizedTitle") - .HasColumnType("TEXT"); - - b.Property("Title") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedTitle", "ExternalTag") - .IsUnique(); - - b.ToTable("Genre"); - }); - - modelBuilder.Entity("API.Entities.Library", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CoverImage") - .HasColumnType("TEXT"); - - b.Property("Created") - .HasColumnType("TEXT"); - - b.Property("LastModified") - .HasColumnType("TEXT"); - - b.Property("LastScanned") - .HasColumnType("TEXT"); - - b.Property("Name") - .HasColumnType("TEXT"); - - b.Property("Type") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.ToTable("Library"); - }); - - modelBuilder.Entity("API.Entities.MangaFile", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ChapterId") - .HasColumnType("INTEGER"); - - b.Property("FilePath") - .HasColumnType("TEXT"); - - b.Property("Format") - .HasColumnType("INTEGER"); - - b.Property("LastModified") - .HasColumnType("TEXT"); - - b.Property("Pages") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("ChapterId"); - - b.ToTable("MangaFile"); - }); - - modelBuilder.Entity("API.Entities.Metadata.SeriesMetadata", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AgeRating") - .HasColumnType("INTEGER"); - - b.Property("ReleaseYear") - .HasColumnType("INTEGER"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .HasColumnType("INTEGER"); - - b.Property("SeriesId") - .HasColumnType("INTEGER"); - - b.Property("Summary") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("SeriesId") - .IsUnique(); - - b.HasIndex("Id", "SeriesId") - .IsUnique(); - - b.ToTable("SeriesMetadata"); - }); - - modelBuilder.Entity("API.Entities.Person", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Name") - .HasColumnType("TEXT"); - - b.Property("NormalizedName") - .HasColumnType("TEXT"); - - b.Property("Role") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.ToTable("Person"); - }); - - modelBuilder.Entity("API.Entities.ReadingList", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AppUserId") - .HasColumnType("INTEGER"); - - b.Property("Created") - .HasColumnType("TEXT"); - - b.Property("LastModified") - .HasColumnType("TEXT"); - - b.Property("Promoted") - .HasColumnType("INTEGER"); - - b.Property("Summary") - .HasColumnType("TEXT"); - - b.Property("Title") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("AppUserId"); - - b.ToTable("ReadingList"); - }); - - modelBuilder.Entity("API.Entities.ReadingListItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ChapterId") - .HasColumnType("INTEGER"); - - b.Property("Order") - .HasColumnType("INTEGER"); - - b.Property("ReadingListId") - .HasColumnType("INTEGER"); - - b.Property("SeriesId") - .HasColumnType("INTEGER"); - - b.Property("VolumeId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("ChapterId"); - - b.HasIndex("ReadingListId"); - - b.HasIndex("SeriesId"); - - b.HasIndex("VolumeId"); - - b.ToTable("ReadingListItem"); - }); - - modelBuilder.Entity("API.Entities.Series", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CoverImage") - .HasColumnType("TEXT"); - - b.Property("CoverImageLocked") - .HasColumnType("INTEGER"); - - b.Property("Created") - .HasColumnType("TEXT"); - - b.Property("Format") - .HasColumnType("INTEGER"); - - b.Property("LastModified") - .HasColumnType("TEXT"); - - b.Property("LibraryId") - .HasColumnType("INTEGER"); - - b.Property("LocalizedName") - .HasColumnType("TEXT"); - - b.Property("Name") - .HasColumnType("TEXT"); - - b.Property("NormalizedName") - .HasColumnType("TEXT"); - - b.Property("OriginalName") - .HasColumnType("TEXT"); - - b.Property("Pages") - .HasColumnType("INTEGER"); - - b.Property("SortName") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("LibraryId"); - - b.HasIndex("Name", "NormalizedName", "LocalizedName", "LibraryId", "Format") - .IsUnique(); - - b.ToTable("Series"); - }); - - modelBuilder.Entity("API.Entities.ServerSetting", b => - { - b.Property("Key") - .HasColumnType("INTEGER"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .HasColumnType("INTEGER"); - - b.Property("Value") - .HasColumnType("TEXT"); - - b.HasKey("Key"); - - b.ToTable("ServerSetting"); - }); - - modelBuilder.Entity("API.Entities.Volume", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CoverImage") - .HasColumnType("TEXT"); - - b.Property("Created") - .HasColumnType("TEXT"); - - b.Property("LastModified") - .HasColumnType("TEXT"); - - b.Property("Name") - .HasColumnType("TEXT"); - - b.Property("Number") - .HasColumnType("INTEGER"); - - b.Property("Pages") - .HasColumnType("INTEGER"); - - b.Property("SeriesId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("SeriesId"); - - b.ToTable("Volume"); - }); - - modelBuilder.Entity("AppUserLibrary", b => - { - b.Property("AppUsersId") - .HasColumnType("INTEGER"); - - b.Property("LibrariesId") - .HasColumnType("INTEGER"); - - b.HasKey("AppUsersId", "LibrariesId"); - - b.HasIndex("LibrariesId"); - - b.ToTable("AppUserLibrary"); - }); - - modelBuilder.Entity("ChapterPerson", b => - { - b.Property("ChapterMetadatasId") - .HasColumnType("INTEGER"); - - b.Property("PeopleId") - .HasColumnType("INTEGER"); - - b.HasKey("ChapterMetadatasId", "PeopleId"); - - b.HasIndex("PeopleId"); - - b.ToTable("ChapterPerson"); - }); - - modelBuilder.Entity("CollectionTagSeriesMetadata", b => - { - b.Property("CollectionTagsId") - .HasColumnType("INTEGER"); - - b.Property("SeriesMetadatasId") - .HasColumnType("INTEGER"); - - b.HasKey("CollectionTagsId", "SeriesMetadatasId"); - - b.HasIndex("SeriesMetadatasId"); - - b.ToTable("CollectionTagSeriesMetadata"); - }); - - modelBuilder.Entity("GenreSeriesMetadata", b => - { - b.Property("GenresId") - .HasColumnType("INTEGER"); - - b.Property("SeriesMetadatasId") - .HasColumnType("INTEGER"); - - b.HasKey("GenresId", "SeriesMetadatasId"); - - b.HasIndex("SeriesMetadatasId"); - - b.ToTable("GenreSeriesMetadata"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ClaimType") - .HasColumnType("TEXT"); - - b.Property("ClaimValue") - .HasColumnType("TEXT"); - - b.Property("RoleId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ClaimType") - .HasColumnType("TEXT"); - - b.Property("ClaimValue") - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("TEXT"); - - b.Property("ProviderKey") - .HasColumnType("TEXT"); - - b.Property("ProviderDisplayName") - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("INTEGER"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("INTEGER"); - - b.Property("LoginProvider") - .HasColumnType("TEXT"); - - b.Property("Name") - .HasColumnType("TEXT"); - - b.Property("Value") - .HasColumnType("TEXT"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("PersonSeriesMetadata", b => - { - b.Property("PeopleId") - .HasColumnType("INTEGER"); - - b.Property("SeriesMetadatasId") - .HasColumnType("INTEGER"); - - b.HasKey("PeopleId", "SeriesMetadatasId"); - - b.HasIndex("SeriesMetadatasId"); - - b.ToTable("PersonSeriesMetadata"); - }); - - modelBuilder.Entity("API.Entities.AppUserBookmark", b => - { - b.HasOne("API.Entities.AppUser", "AppUser") - .WithMany("Bookmarks") - .HasForeignKey("AppUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("AppUser"); - }); - - modelBuilder.Entity("API.Entities.AppUserPreferences", b => - { - b.HasOne("API.Entities.AppUser", "AppUser") - .WithOne("UserPreferences") - .HasForeignKey("API.Entities.AppUserPreferences", "AppUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("AppUser"); - }); - - modelBuilder.Entity("API.Entities.AppUserProgress", b => - { - b.HasOne("API.Entities.AppUser", "AppUser") - .WithMany("Progresses") - .HasForeignKey("AppUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Series", null) - .WithMany("Progress") - .HasForeignKey("SeriesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("AppUser"); - }); - - modelBuilder.Entity("API.Entities.AppUserRating", b => - { - b.HasOne("API.Entities.AppUser", "AppUser") - .WithMany("Ratings") - .HasForeignKey("AppUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Series", null) - .WithMany("Ratings") - .HasForeignKey("SeriesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("AppUser"); - }); - - modelBuilder.Entity("API.Entities.AppUserRole", b => - { - b.HasOne("API.Entities.AppRole", "Role") - .WithMany("UserRoles") - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.AppUser", "User") - .WithMany("UserRoles") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Role"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("API.Entities.Chapter", b => - { - b.HasOne("API.Entities.Genre", null) - .WithMany("Chapters") - .HasForeignKey("GenreId"); - - b.HasOne("API.Entities.Volume", "Volume") - .WithMany("Chapters") - .HasForeignKey("VolumeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Volume"); - }); - - modelBuilder.Entity("API.Entities.FolderPath", b => - { - b.HasOne("API.Entities.Library", "Library") - .WithMany("Folders") - .HasForeignKey("LibraryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Library"); - }); - - modelBuilder.Entity("API.Entities.MangaFile", b => - { - b.HasOne("API.Entities.Chapter", "Chapter") - .WithMany("Files") - .HasForeignKey("ChapterId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Chapter"); - }); - - modelBuilder.Entity("API.Entities.Metadata.SeriesMetadata", b => - { - b.HasOne("API.Entities.Series", "Series") - .WithOne("Metadata") - .HasForeignKey("API.Entities.Metadata.SeriesMetadata", "SeriesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Series"); - }); - - modelBuilder.Entity("API.Entities.ReadingList", b => - { - b.HasOne("API.Entities.AppUser", "AppUser") - .WithMany("ReadingLists") - .HasForeignKey("AppUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("AppUser"); - }); - - modelBuilder.Entity("API.Entities.ReadingListItem", b => - { - b.HasOne("API.Entities.Chapter", "Chapter") - .WithMany() - .HasForeignKey("ChapterId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.ReadingList", "ReadingList") - .WithMany("Items") - .HasForeignKey("ReadingListId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Series", "Series") - .WithMany() - .HasForeignKey("SeriesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Volume", "Volume") - .WithMany() - .HasForeignKey("VolumeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Chapter"); - - b.Navigation("ReadingList"); - - b.Navigation("Series"); - - b.Navigation("Volume"); - }); - - modelBuilder.Entity("API.Entities.Series", b => - { - b.HasOne("API.Entities.Library", "Library") - .WithMany("Series") - .HasForeignKey("LibraryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Library"); - }); - - modelBuilder.Entity("API.Entities.Volume", b => - { - b.HasOne("API.Entities.Series", "Series") - .WithMany("Volumes") - .HasForeignKey("SeriesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Series"); - }); - - modelBuilder.Entity("AppUserLibrary", b => - { - b.HasOne("API.Entities.AppUser", null) - .WithMany() - .HasForeignKey("AppUsersId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Library", null) - .WithMany() - .HasForeignKey("LibrariesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("ChapterPerson", b => - { - b.HasOne("API.Entities.Chapter", null) - .WithMany() - .HasForeignKey("ChapterMetadatasId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Person", null) - .WithMany() - .HasForeignKey("PeopleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("CollectionTagSeriesMetadata", b => - { - b.HasOne("API.Entities.CollectionTag", null) - .WithMany() - .HasForeignKey("CollectionTagsId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Metadata.SeriesMetadata", null) - .WithMany() - .HasForeignKey("SeriesMetadatasId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("GenreSeriesMetadata", b => - { - b.HasOne("API.Entities.Genre", null) - .WithMany() - .HasForeignKey("GenresId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Metadata.SeriesMetadata", null) - .WithMany() - .HasForeignKey("SeriesMetadatasId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("API.Entities.AppRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("API.Entities.AppUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("API.Entities.AppUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("API.Entities.AppUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("PersonSeriesMetadata", b => - { - b.HasOne("API.Entities.Person", null) - .WithMany() - .HasForeignKey("PeopleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Metadata.SeriesMetadata", null) - .WithMany() - .HasForeignKey("SeriesMetadatasId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("API.Entities.AppRole", b => - { - b.Navigation("UserRoles"); - }); - - modelBuilder.Entity("API.Entities.AppUser", b => - { - b.Navigation("Bookmarks"); - - b.Navigation("Progresses"); - - b.Navigation("Ratings"); - - b.Navigation("ReadingLists"); - - b.Navigation("UserPreferences"); - - b.Navigation("UserRoles"); - }); - - modelBuilder.Entity("API.Entities.Chapter", b => - { - b.Navigation("Files"); - }); - - modelBuilder.Entity("API.Entities.Genre", b => - { - b.Navigation("Chapters"); - }); - - modelBuilder.Entity("API.Entities.Library", b => - { - b.Navigation("Folders"); - - b.Navigation("Series"); - }); - - modelBuilder.Entity("API.Entities.ReadingList", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("API.Entities.Series", b => - { - b.Navigation("Metadata"); - - b.Navigation("Progress"); - - b.Navigation("Ratings"); - - b.Navigation("Volumes"); - }); - - modelBuilder.Entity("API.Entities.Volume", b => - { - b.Navigation("Chapters"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/API/Data/Migrations/20211214000230_SeriesIncludes.cs b/API/Data/Migrations/20211214000230_SeriesIncludes.cs deleted file mode 100644 index 092d9001d..000000000 --- a/API/Data/Migrations/20211214000230_SeriesIncludes.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace API.Data.Migrations -{ - public partial class SeriesIncludes : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateIndex( - name: "IX_AppUserRating_SeriesId", - table: "AppUserRating", - column: "SeriesId"); - - migrationBuilder.CreateIndex( - name: "IX_AppUserProgresses_SeriesId", - table: "AppUserProgresses", - column: "SeriesId"); - - migrationBuilder.AddForeignKey( - name: "FK_AppUserProgresses_Series_SeriesId", - table: "AppUserProgresses", - column: "SeriesId", - principalTable: "Series", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - - migrationBuilder.AddForeignKey( - name: "FK_AppUserRating_Series_SeriesId", - table: "AppUserRating", - column: "SeriesId", - principalTable: "Series", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_AppUserProgresses_Series_SeriesId", - table: "AppUserProgresses"); - - migrationBuilder.DropForeignKey( - name: "FK_AppUserRating_Series_SeriesId", - table: "AppUserRating"); - - migrationBuilder.DropIndex( - name: "IX_AppUserRating_SeriesId", - table: "AppUserRating"); - - migrationBuilder.DropIndex( - name: "IX_AppUserProgresses_SeriesId", - table: "AppUserProgresses"); - } - } -} diff --git a/API/Data/Migrations/20211216150752_seriesAndChapterTags.Designer.cs b/API/Data/Migrations/20211216150752_seriesAndChapterTags.Designer.cs deleted file mode 100644 index 845aa8e7b..000000000 --- a/API/Data/Migrations/20211216150752_seriesAndChapterTags.Designer.cs +++ /dev/null @@ -1,1311 +0,0 @@ -// -using System; -using API.Data; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace API.Data.Migrations -{ - [DbContext(typeof(DataContext))] - [Migration("20211216150752_seriesAndChapterTags")] - partial class seriesAndChapterTags - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "6.0.1"); - - modelBuilder.Entity("API.Entities.AppRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("TEXT"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("TEXT"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex"); - - b.ToTable("AspNetRoles", (string)null); - }); - - modelBuilder.Entity("API.Entities.AppUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AccessFailedCount") - .HasColumnType("INTEGER"); - - b.Property("ApiKey") - .HasColumnType("TEXT"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("TEXT"); - - b.Property("Created") - .HasColumnType("TEXT"); - - b.Property("Email") - .HasMaxLength(256) - .HasColumnType("TEXT"); - - b.Property("EmailConfirmed") - .HasColumnType("INTEGER"); - - b.Property("LastActive") - .HasColumnType("TEXT"); - - b.Property("LockoutEnabled") - .HasColumnType("INTEGER"); - - b.Property("LockoutEnd") - .HasColumnType("TEXT"); - - b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("TEXT"); - - b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("TEXT"); - - b.Property("PasswordHash") - .HasColumnType("TEXT"); - - b.Property("PhoneNumber") - .HasColumnType("TEXT"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("INTEGER"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .HasColumnType("INTEGER"); - - b.Property("SecurityStamp") - .HasColumnType("TEXT"); - - b.Property("TwoFactorEnabled") - .HasColumnType("INTEGER"); - - b.Property("UserName") - .HasMaxLength(256) - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex"); - - b.ToTable("AspNetUsers", (string)null); - }); - - modelBuilder.Entity("API.Entities.AppUserBookmark", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AppUserId") - .HasColumnType("INTEGER"); - - b.Property("ChapterId") - .HasColumnType("INTEGER"); - - b.Property("Page") - .HasColumnType("INTEGER"); - - b.Property("SeriesId") - .HasColumnType("INTEGER"); - - b.Property("VolumeId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("AppUserId"); - - b.ToTable("AppUserBookmark"); - }); - - modelBuilder.Entity("API.Entities.AppUserPreferences", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AppUserId") - .HasColumnType("INTEGER"); - - b.Property("AutoCloseMenu") - .HasColumnType("INTEGER"); - - b.Property("BookReaderDarkMode") - .HasColumnType("INTEGER"); - - b.Property("BookReaderFontFamily") - .HasColumnType("TEXT"); - - b.Property("BookReaderFontSize") - .HasColumnType("INTEGER"); - - b.Property("BookReaderLineSpacing") - .HasColumnType("INTEGER"); - - b.Property("BookReaderMargin") - .HasColumnType("INTEGER"); - - b.Property("BookReaderReadingDirection") - .HasColumnType("INTEGER"); - - b.Property("BookReaderTapToPaginate") - .HasColumnType("INTEGER"); - - b.Property("PageSplitOption") - .HasColumnType("INTEGER"); - - b.Property("ReaderMode") - .HasColumnType("INTEGER"); - - b.Property("ReadingDirection") - .HasColumnType("INTEGER"); - - b.Property("ScalingOption") - .HasColumnType("INTEGER"); - - b.Property("SiteDarkMode") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("AppUserId") - .IsUnique(); - - b.ToTable("AppUserPreferences"); - }); - - modelBuilder.Entity("API.Entities.AppUserProgress", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AppUserId") - .HasColumnType("INTEGER"); - - b.Property("BookScrollId") - .HasColumnType("TEXT"); - - b.Property("ChapterId") - .HasColumnType("INTEGER"); - - b.Property("Created") - .HasColumnType("TEXT"); - - b.Property("LastModified") - .HasColumnType("TEXT"); - - b.Property("PagesRead") - .HasColumnType("INTEGER"); - - b.Property("SeriesId") - .HasColumnType("INTEGER"); - - b.Property("VolumeId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("AppUserId"); - - b.HasIndex("SeriesId"); - - b.ToTable("AppUserProgresses"); - }); - - modelBuilder.Entity("API.Entities.AppUserRating", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AppUserId") - .HasColumnType("INTEGER"); - - b.Property("Rating") - .HasColumnType("INTEGER"); - - b.Property("Review") - .HasColumnType("TEXT"); - - b.Property("SeriesId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("AppUserId"); - - b.HasIndex("SeriesId"); - - b.ToTable("AppUserRating"); - }); - - modelBuilder.Entity("API.Entities.AppUserRole", b => - { - b.Property("UserId") - .HasColumnType("INTEGER"); - - b.Property("RoleId") - .HasColumnType("INTEGER"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("API.Entities.Chapter", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AgeRating") - .HasColumnType("INTEGER"); - - b.Property("CoverImage") - .HasColumnType("TEXT"); - - b.Property("CoverImageLocked") - .HasColumnType("INTEGER"); - - b.Property("Created") - .HasColumnType("TEXT"); - - b.Property("GenreId") - .HasColumnType("INTEGER"); - - b.Property("IsSpecial") - .HasColumnType("INTEGER"); - - b.Property("LastModified") - .HasColumnType("TEXT"); - - b.Property("Number") - .HasColumnType("TEXT"); - - b.Property("Pages") - .HasColumnType("INTEGER"); - - b.Property("Range") - .HasColumnType("TEXT"); - - b.Property("ReleaseDate") - .HasColumnType("TEXT"); - - b.Property("Title") - .HasColumnType("TEXT"); - - b.Property("TitleName") - .HasColumnType("TEXT"); - - b.Property("VolumeId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("GenreId"); - - b.HasIndex("VolumeId"); - - b.ToTable("Chapter"); - }); - - modelBuilder.Entity("API.Entities.CollectionTag", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CoverImage") - .HasColumnType("TEXT"); - - b.Property("CoverImageLocked") - .HasColumnType("INTEGER"); - - b.Property("NormalizedTitle") - .HasColumnType("TEXT"); - - b.Property("Promoted") - .HasColumnType("INTEGER"); - - b.Property("RowVersion") - .HasColumnType("INTEGER"); - - b.Property("Summary") - .HasColumnType("TEXT"); - - b.Property("Title") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("Id", "Promoted") - .IsUnique(); - - b.ToTable("CollectionTag"); - }); - - modelBuilder.Entity("API.Entities.FolderPath", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("LastScanned") - .HasColumnType("TEXT"); - - b.Property("LibraryId") - .HasColumnType("INTEGER"); - - b.Property("Path") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("LibraryId"); - - b.ToTable("FolderPath"); - }); - - modelBuilder.Entity("API.Entities.Genre", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ExternalTag") - .HasColumnType("INTEGER"); - - b.Property("NormalizedTitle") - .HasColumnType("TEXT"); - - b.Property("Title") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedTitle", "ExternalTag") - .IsUnique(); - - b.ToTable("Genre"); - }); - - modelBuilder.Entity("API.Entities.Library", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CoverImage") - .HasColumnType("TEXT"); - - b.Property("Created") - .HasColumnType("TEXT"); - - b.Property("LastModified") - .HasColumnType("TEXT"); - - b.Property("LastScanned") - .HasColumnType("TEXT"); - - b.Property("Name") - .HasColumnType("TEXT"); - - b.Property("Type") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.ToTable("Library"); - }); - - modelBuilder.Entity("API.Entities.MangaFile", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ChapterId") - .HasColumnType("INTEGER"); - - b.Property("FilePath") - .HasColumnType("TEXT"); - - b.Property("Format") - .HasColumnType("INTEGER"); - - b.Property("LastModified") - .HasColumnType("TEXT"); - - b.Property("Pages") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("ChapterId"); - - b.ToTable("MangaFile"); - }); - - modelBuilder.Entity("API.Entities.Metadata.SeriesMetadata", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AgeRating") - .HasColumnType("INTEGER"); - - b.Property("ReleaseYear") - .HasColumnType("INTEGER"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .HasColumnType("INTEGER"); - - b.Property("SeriesId") - .HasColumnType("INTEGER"); - - b.Property("Summary") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("SeriesId") - .IsUnique(); - - b.HasIndex("Id", "SeriesId") - .IsUnique(); - - b.ToTable("SeriesMetadata"); - }); - - modelBuilder.Entity("API.Entities.Person", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Name") - .HasColumnType("TEXT"); - - b.Property("NormalizedName") - .HasColumnType("TEXT"); - - b.Property("Role") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.ToTable("Person"); - }); - - modelBuilder.Entity("API.Entities.ReadingList", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AppUserId") - .HasColumnType("INTEGER"); - - b.Property("Created") - .HasColumnType("TEXT"); - - b.Property("LastModified") - .HasColumnType("TEXT"); - - b.Property("Promoted") - .HasColumnType("INTEGER"); - - b.Property("Summary") - .HasColumnType("TEXT"); - - b.Property("Title") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("AppUserId"); - - b.ToTable("ReadingList"); - }); - - modelBuilder.Entity("API.Entities.ReadingListItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ChapterId") - .HasColumnType("INTEGER"); - - b.Property("Order") - .HasColumnType("INTEGER"); - - b.Property("ReadingListId") - .HasColumnType("INTEGER"); - - b.Property("SeriesId") - .HasColumnType("INTEGER"); - - b.Property("VolumeId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("ChapterId"); - - b.HasIndex("ReadingListId"); - - b.HasIndex("SeriesId"); - - b.HasIndex("VolumeId"); - - b.ToTable("ReadingListItem"); - }); - - modelBuilder.Entity("API.Entities.Series", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CoverImage") - .HasColumnType("TEXT"); - - b.Property("CoverImageLocked") - .HasColumnType("INTEGER"); - - b.Property("Created") - .HasColumnType("TEXT"); - - b.Property("Format") - .HasColumnType("INTEGER"); - - b.Property("LastModified") - .HasColumnType("TEXT"); - - b.Property("LibraryId") - .HasColumnType("INTEGER"); - - b.Property("LocalizedName") - .HasColumnType("TEXT"); - - b.Property("Name") - .HasColumnType("TEXT"); - - b.Property("NormalizedName") - .HasColumnType("TEXT"); - - b.Property("OriginalName") - .HasColumnType("TEXT"); - - b.Property("Pages") - .HasColumnType("INTEGER"); - - b.Property("SortName") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("LibraryId"); - - b.HasIndex("Name", "NormalizedName", "LocalizedName", "LibraryId", "Format") - .IsUnique(); - - b.ToTable("Series"); - }); - - modelBuilder.Entity("API.Entities.ServerSetting", b => - { - b.Property("Key") - .HasColumnType("INTEGER"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .HasColumnType("INTEGER"); - - b.Property("Value") - .HasColumnType("TEXT"); - - b.HasKey("Key"); - - b.ToTable("ServerSetting"); - }); - - modelBuilder.Entity("API.Entities.Tag", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ExternalTag") - .HasColumnType("INTEGER"); - - b.Property("NormalizedTitle") - .HasColumnType("TEXT"); - - b.Property("Title") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedTitle", "ExternalTag") - .IsUnique(); - - b.ToTable("Tag"); - }); - - modelBuilder.Entity("API.Entities.Volume", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CoverImage") - .HasColumnType("TEXT"); - - b.Property("Created") - .HasColumnType("TEXT"); - - b.Property("LastModified") - .HasColumnType("TEXT"); - - b.Property("Name") - .HasColumnType("TEXT"); - - b.Property("Number") - .HasColumnType("INTEGER"); - - b.Property("Pages") - .HasColumnType("INTEGER"); - - b.Property("SeriesId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("SeriesId"); - - b.ToTable("Volume"); - }); - - modelBuilder.Entity("AppUserLibrary", b => - { - b.Property("AppUsersId") - .HasColumnType("INTEGER"); - - b.Property("LibrariesId") - .HasColumnType("INTEGER"); - - b.HasKey("AppUsersId", "LibrariesId"); - - b.HasIndex("LibrariesId"); - - b.ToTable("AppUserLibrary"); - }); - - modelBuilder.Entity("ChapterPerson", b => - { - b.Property("ChapterMetadatasId") - .HasColumnType("INTEGER"); - - b.Property("PeopleId") - .HasColumnType("INTEGER"); - - b.HasKey("ChapterMetadatasId", "PeopleId"); - - b.HasIndex("PeopleId"); - - b.ToTable("ChapterPerson"); - }); - - modelBuilder.Entity("ChapterTag", b => - { - b.Property("ChaptersId") - .HasColumnType("INTEGER"); - - b.Property("TagsId") - .HasColumnType("INTEGER"); - - b.HasKey("ChaptersId", "TagsId"); - - b.HasIndex("TagsId"); - - b.ToTable("ChapterTag"); - }); - - modelBuilder.Entity("CollectionTagSeriesMetadata", b => - { - b.Property("CollectionTagsId") - .HasColumnType("INTEGER"); - - b.Property("SeriesMetadatasId") - .HasColumnType("INTEGER"); - - b.HasKey("CollectionTagsId", "SeriesMetadatasId"); - - b.HasIndex("SeriesMetadatasId"); - - b.ToTable("CollectionTagSeriesMetadata"); - }); - - modelBuilder.Entity("GenreSeriesMetadata", b => - { - b.Property("GenresId") - .HasColumnType("INTEGER"); - - b.Property("SeriesMetadatasId") - .HasColumnType("INTEGER"); - - b.HasKey("GenresId", "SeriesMetadatasId"); - - b.HasIndex("SeriesMetadatasId"); - - b.ToTable("GenreSeriesMetadata"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ClaimType") - .HasColumnType("TEXT"); - - b.Property("ClaimValue") - .HasColumnType("TEXT"); - - b.Property("RoleId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ClaimType") - .HasColumnType("TEXT"); - - b.Property("ClaimValue") - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("TEXT"); - - b.Property("ProviderKey") - .HasColumnType("TEXT"); - - b.Property("ProviderDisplayName") - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("INTEGER"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("INTEGER"); - - b.Property("LoginProvider") - .HasColumnType("TEXT"); - - b.Property("Name") - .HasColumnType("TEXT"); - - b.Property("Value") - .HasColumnType("TEXT"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("PersonSeriesMetadata", b => - { - b.Property("PeopleId") - .HasColumnType("INTEGER"); - - b.Property("SeriesMetadatasId") - .HasColumnType("INTEGER"); - - b.HasKey("PeopleId", "SeriesMetadatasId"); - - b.HasIndex("SeriesMetadatasId"); - - b.ToTable("PersonSeriesMetadata"); - }); - - modelBuilder.Entity("SeriesMetadataTag", b => - { - b.Property("SeriesMetadatasId") - .HasColumnType("INTEGER"); - - b.Property("TagsId") - .HasColumnType("INTEGER"); - - b.HasKey("SeriesMetadatasId", "TagsId"); - - b.HasIndex("TagsId"); - - b.ToTable("SeriesMetadataTag"); - }); - - modelBuilder.Entity("API.Entities.AppUserBookmark", b => - { - b.HasOne("API.Entities.AppUser", "AppUser") - .WithMany("Bookmarks") - .HasForeignKey("AppUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("AppUser"); - }); - - modelBuilder.Entity("API.Entities.AppUserPreferences", b => - { - b.HasOne("API.Entities.AppUser", "AppUser") - .WithOne("UserPreferences") - .HasForeignKey("API.Entities.AppUserPreferences", "AppUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("AppUser"); - }); - - modelBuilder.Entity("API.Entities.AppUserProgress", b => - { - b.HasOne("API.Entities.AppUser", "AppUser") - .WithMany("Progresses") - .HasForeignKey("AppUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Series", null) - .WithMany("Progress") - .HasForeignKey("SeriesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("AppUser"); - }); - - modelBuilder.Entity("API.Entities.AppUserRating", b => - { - b.HasOne("API.Entities.AppUser", "AppUser") - .WithMany("Ratings") - .HasForeignKey("AppUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Series", null) - .WithMany("Ratings") - .HasForeignKey("SeriesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("AppUser"); - }); - - modelBuilder.Entity("API.Entities.AppUserRole", b => - { - b.HasOne("API.Entities.AppRole", "Role") - .WithMany("UserRoles") - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.AppUser", "User") - .WithMany("UserRoles") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Role"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("API.Entities.Chapter", b => - { - b.HasOne("API.Entities.Genre", null) - .WithMany("Chapters") - .HasForeignKey("GenreId"); - - b.HasOne("API.Entities.Volume", "Volume") - .WithMany("Chapters") - .HasForeignKey("VolumeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Volume"); - }); - - modelBuilder.Entity("API.Entities.FolderPath", b => - { - b.HasOne("API.Entities.Library", "Library") - .WithMany("Folders") - .HasForeignKey("LibraryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Library"); - }); - - modelBuilder.Entity("API.Entities.MangaFile", b => - { - b.HasOne("API.Entities.Chapter", "Chapter") - .WithMany("Files") - .HasForeignKey("ChapterId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Chapter"); - }); - - modelBuilder.Entity("API.Entities.Metadata.SeriesMetadata", b => - { - b.HasOne("API.Entities.Series", "Series") - .WithOne("Metadata") - .HasForeignKey("API.Entities.Metadata.SeriesMetadata", "SeriesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Series"); - }); - - modelBuilder.Entity("API.Entities.ReadingList", b => - { - b.HasOne("API.Entities.AppUser", "AppUser") - .WithMany("ReadingLists") - .HasForeignKey("AppUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("AppUser"); - }); - - modelBuilder.Entity("API.Entities.ReadingListItem", b => - { - b.HasOne("API.Entities.Chapter", "Chapter") - .WithMany() - .HasForeignKey("ChapterId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.ReadingList", "ReadingList") - .WithMany("Items") - .HasForeignKey("ReadingListId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Series", "Series") - .WithMany() - .HasForeignKey("SeriesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Volume", "Volume") - .WithMany() - .HasForeignKey("VolumeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Chapter"); - - b.Navigation("ReadingList"); - - b.Navigation("Series"); - - b.Navigation("Volume"); - }); - - modelBuilder.Entity("API.Entities.Series", b => - { - b.HasOne("API.Entities.Library", "Library") - .WithMany("Series") - .HasForeignKey("LibraryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Library"); - }); - - modelBuilder.Entity("API.Entities.Volume", b => - { - b.HasOne("API.Entities.Series", "Series") - .WithMany("Volumes") - .HasForeignKey("SeriesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Series"); - }); - - modelBuilder.Entity("AppUserLibrary", b => - { - b.HasOne("API.Entities.AppUser", null) - .WithMany() - .HasForeignKey("AppUsersId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Library", null) - .WithMany() - .HasForeignKey("LibrariesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("ChapterPerson", b => - { - b.HasOne("API.Entities.Chapter", null) - .WithMany() - .HasForeignKey("ChapterMetadatasId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Person", null) - .WithMany() - .HasForeignKey("PeopleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("ChapterTag", b => - { - b.HasOne("API.Entities.Chapter", null) - .WithMany() - .HasForeignKey("ChaptersId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Tag", null) - .WithMany() - .HasForeignKey("TagsId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("CollectionTagSeriesMetadata", b => - { - b.HasOne("API.Entities.CollectionTag", null) - .WithMany() - .HasForeignKey("CollectionTagsId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Metadata.SeriesMetadata", null) - .WithMany() - .HasForeignKey("SeriesMetadatasId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("GenreSeriesMetadata", b => - { - b.HasOne("API.Entities.Genre", null) - .WithMany() - .HasForeignKey("GenresId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Metadata.SeriesMetadata", null) - .WithMany() - .HasForeignKey("SeriesMetadatasId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("API.Entities.AppRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("API.Entities.AppUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("API.Entities.AppUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("API.Entities.AppUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("PersonSeriesMetadata", b => - { - b.HasOne("API.Entities.Person", null) - .WithMany() - .HasForeignKey("PeopleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Metadata.SeriesMetadata", null) - .WithMany() - .HasForeignKey("SeriesMetadatasId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("SeriesMetadataTag", b => - { - b.HasOne("API.Entities.Metadata.SeriesMetadata", null) - .WithMany() - .HasForeignKey("SeriesMetadatasId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("API.Entities.Tag", null) - .WithMany() - .HasForeignKey("TagsId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("API.Entities.AppRole", b => - { - b.Navigation("UserRoles"); - }); - - modelBuilder.Entity("API.Entities.AppUser", b => - { - b.Navigation("Bookmarks"); - - b.Navigation("Progresses"); - - b.Navigation("Ratings"); - - b.Navigation("ReadingLists"); - - b.Navigation("UserPreferences"); - - b.Navigation("UserRoles"); - }); - - modelBuilder.Entity("API.Entities.Chapter", b => - { - b.Navigation("Files"); - }); - - modelBuilder.Entity("API.Entities.Genre", b => - { - b.Navigation("Chapters"); - }); - - modelBuilder.Entity("API.Entities.Library", b => - { - b.Navigation("Folders"); - - b.Navigation("Series"); - }); - - modelBuilder.Entity("API.Entities.ReadingList", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("API.Entities.Series", b => - { - b.Navigation("Metadata"); - - b.Navigation("Progress"); - - b.Navigation("Ratings"); - - b.Navigation("Volumes"); - }); - - modelBuilder.Entity("API.Entities.Volume", b => - { - b.Navigation("Chapters"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/API/Data/Migrations/20211216191436_seriesLanguage.cs b/API/Data/Migrations/20211216191436_seriesLanguage.cs deleted file mode 100644 index 8b48546cf..000000000 --- a/API/Data/Migrations/20211216191436_seriesLanguage.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace API.Data.Migrations -{ - public partial class seriesLanguage : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "Language", - table: "SeriesMetadata", - type: "TEXT", - nullable: true); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "Language", - table: "SeriesMetadata"); - } - } -} diff --git a/API/Data/Migrations/20211216191436_seriesLanguage.Designer.cs b/API/Data/Migrations/20211217180457_filteringChanges.Designer.cs similarity index 99% rename from API/Data/Migrations/20211216191436_seriesLanguage.Designer.cs rename to API/Data/Migrations/20211217180457_filteringChanges.Designer.cs index 5f53e0c6d..39377a6c3 100644 --- a/API/Data/Migrations/20211216191436_seriesLanguage.Designer.cs +++ b/API/Data/Migrations/20211217180457_filteringChanges.Designer.cs @@ -11,13 +11,13 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace API.Data.Migrations { [DbContext(typeof(DataContext))] - [Migration("20211216191436_seriesLanguage")] - partial class seriesLanguage + [Migration("20211217180457_filteringChanges")] + partial class filteringChanges { protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "6.0.1"); + modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); modelBuilder.Entity("API.Entities.AppRole", b => { diff --git a/API/Data/Migrations/20211216150752_seriesAndChapterTags.cs b/API/Data/Migrations/20211217180457_filteringChanges.cs similarity index 67% rename from API/Data/Migrations/20211216150752_seriesAndChapterTags.cs rename to API/Data/Migrations/20211217180457_filteringChanges.cs index 4203068bd..28c4d00b3 100644 --- a/API/Data/Migrations/20211216150752_seriesAndChapterTags.cs +++ b/API/Data/Migrations/20211217180457_filteringChanges.cs @@ -4,10 +4,16 @@ namespace API.Data.Migrations { - public partial class seriesAndChapterTags : Migration + public partial class filteringChanges : Migration { protected override void Up(MigrationBuilder migrationBuilder) { + migrationBuilder.AddColumn( + name: "Language", + table: "SeriesMetadata", + type: "TEXT", + nullable: true); + migrationBuilder.CreateTable( name: "Tag", columns: table => new @@ -71,6 +77,16 @@ namespace API.Data.Migrations onDelete: ReferentialAction.Cascade); }); + migrationBuilder.CreateIndex( + name: "IX_AppUserRating_SeriesId", + table: "AppUserRating", + column: "SeriesId"); + + migrationBuilder.CreateIndex( + name: "IX_AppUserProgresses_SeriesId", + table: "AppUserProgresses", + column: "SeriesId"); + migrationBuilder.CreateIndex( name: "IX_ChapterTag_TagsId", table: "ChapterTag", @@ -86,10 +102,34 @@ namespace API.Data.Migrations table: "Tag", columns: new[] { "NormalizedTitle", "ExternalTag" }, unique: true); + + migrationBuilder.AddForeignKey( + name: "FK_AppUserProgresses_Series_SeriesId", + table: "AppUserProgresses", + column: "SeriesId", + principalTable: "Series", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_AppUserRating_Series_SeriesId", + table: "AppUserRating", + column: "SeriesId", + principalTable: "Series", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); } protected override void Down(MigrationBuilder migrationBuilder) { + migrationBuilder.DropForeignKey( + name: "FK_AppUserProgresses_Series_SeriesId", + table: "AppUserProgresses"); + + migrationBuilder.DropForeignKey( + name: "FK_AppUserRating_Series_SeriesId", + table: "AppUserRating"); + migrationBuilder.DropTable( name: "ChapterTag"); @@ -98,6 +138,18 @@ namespace API.Data.Migrations migrationBuilder.DropTable( name: "Tag"); + + migrationBuilder.DropIndex( + name: "IX_AppUserRating_SeriesId", + table: "AppUserRating"); + + migrationBuilder.DropIndex( + name: "IX_AppUserProgresses_SeriesId", + table: "AppUserProgresses"); + + migrationBuilder.DropColumn( + name: "Language", + table: "SeriesMetadata"); } } } diff --git a/API/Data/Migrations/DataContextModelSnapshot.cs b/API/Data/Migrations/DataContextModelSnapshot.cs index 9b08b4a74..963a4f815 100644 --- a/API/Data/Migrations/DataContextModelSnapshot.cs +++ b/API/Data/Migrations/DataContextModelSnapshot.cs @@ -15,7 +15,7 @@ namespace API.Data.Migrations protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "6.0.1"); + modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); modelBuilder.Entity("API.Entities.AppRole", b => { diff --git a/API/Data/Seed.cs b/API/Data/Seed.cs index b03f1fec1..e6b758f33 100644 --- a/API/Data/Seed.cs +++ b/API/Data/Seed.cs @@ -44,7 +44,7 @@ namespace API.Data new () {Key = ServerSettingKey.CacheDirectory, Value = directoryService.CacheDirectory}, new () {Key = ServerSettingKey.TaskScan, Value = "daily"}, new () {Key = ServerSettingKey.LoggingLevel, Value = "Information"}, // Not used from DB, but DB is sync with appSettings.json - new () {Key = ServerSettingKey.TaskBackup, Value = "weekly"}, + new () {Key = ServerSettingKey.TaskBackup, Value = "daily"}, new () {Key = ServerSettingKey.BackupDirectory, Value = Path.GetFullPath(DirectoryService.BackupDirectory)}, new () {Key = ServerSettingKey.Port, Value = "5000"}, // Not used from DB, but DB is sync with appSettings.json new () {Key = ServerSettingKey.AllowStatCollection, Value = "true"}, diff --git a/API/Extensions/ApplicationServiceExtensions.cs b/API/Extensions/ApplicationServiceExtensions.cs index ef2525547..fd0c5f5ca 100644 --- a/API/Extensions/ApplicationServiceExtensions.cs +++ b/API/Extensions/ApplicationServiceExtensions.cs @@ -56,6 +56,7 @@ namespace API.Extensions services.AddDbContext(options => { options.UseSqlite(config.GetConnectionString("DefaultConnection")); + options.EnableDetailedErrors(); options.EnableSensitiveDataLogging(env.IsDevelopment() || Configuration.LogLevel.Equals("Debug")); }); } diff --git a/API/Helpers/CacheHelper.cs b/API/Helpers/CacheHelper.cs index 382c0dac7..de663e0b5 100644 --- a/API/Helpers/CacheHelper.cs +++ b/API/Helpers/CacheHelper.cs @@ -38,7 +38,7 @@ public class CacheHelper : ICacheHelper public bool ShouldUpdateCoverImage(string coverPath, MangaFile firstFile, DateTime chapterCreated, bool forceUpdate = false, bool isCoverLocked = false) { - if (firstFile == null) return true; + if (firstFile == null) return false; var fileExists = !string.IsNullOrEmpty(coverPath) && _fileService.Exists(coverPath); if (isCoverLocked && fileExists) return false; diff --git a/API/Program.cs b/API/Program.cs index daea7490d..b114bbcac 100644 --- a/API/Program.cs +++ b/API/Program.cs @@ -1,11 +1,13 @@ using System; using System.IO; using System.IO.Abstractions; +using System.Linq; using System.Security.Cryptography; using System.Threading.Tasks; using API.Data; using API.Entities; using API.Services; +using API.Services.Tasks; using Kavita.Common; using Kavita.Common.EnvironmentInfo; using Microsoft.AspNetCore.Hosting; @@ -64,12 +66,6 @@ namespace API return; } - // This doesn't work either - //var directoryService = services.GetRequiredService(); - - - - var requiresCoverImageMigration = !Directory.Exists(directoryService.CoverImageDirectory); try { @@ -85,6 +81,16 @@ namespace API } // Apply all migrations on startup + // If we have pending migrations, make a backup first + var pendingMigrations = await context.Database.GetPendingMigrationsAsync(); + if (pendingMigrations.Any()) + { + var logger = services.GetRequiredService>(); + logger.LogInformation("Performing backup as migrations are needed"); + // var backupService = services.GetRequiredService(); + // await backupService.BackupDatabase(); + } + await context.Database.MigrateAsync(); if (requiresCoverImageMigration) @@ -99,7 +105,7 @@ namespace API catch (Exception ex) { var logger = services.GetRequiredService>(); - logger.LogError(ex, "An error occurred during migration"); + logger.LogCritical(ex, "An error occurred during migration"); } await host.RunAsync(); diff --git a/API/Services/HostedServices/StartupTasksHostedService.cs b/API/Services/HostedServices/StartupTasksHostedService.cs index 866a90332..099c44cc8 100644 --- a/API/Services/HostedServices/StartupTasksHostedService.cs +++ b/API/Services/HostedServices/StartupTasksHostedService.cs @@ -20,7 +20,7 @@ namespace API.Services.HostedServices using var scope = _provider.CreateScope(); var taskScheduler = scope.ServiceProvider.GetRequiredService(); - taskScheduler.ScheduleTasks(); + await taskScheduler.ScheduleTasks(); taskScheduler.ScheduleUpdaterTasks(); try diff --git a/API/Services/TaskScheduler.cs b/API/Services/TaskScheduler.cs index 6bf10a5da..9f91bf75c 100644 --- a/API/Services/TaskScheduler.cs +++ b/API/Services/TaskScheduler.cs @@ -12,7 +12,7 @@ namespace API.Services; public interface ITaskScheduler { - void ScheduleTasks(); + Task ScheduleTasks(); Task ScheduleStatsTasks(); void ScheduleUpdaterTasks(); void ScanLibrary(int libraryId, bool forceUpdate = false); @@ -58,11 +58,11 @@ public class TaskScheduler : ITaskScheduler _directoryService = directoryService; } - public void ScheduleTasks() + public async Task ScheduleTasks() { _logger.LogInformation("Scheduling reoccurring tasks"); - var setting = Task.Run(() => _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.TaskScan)).GetAwaiter().GetResult().Value; + var setting = (await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.TaskScan)).Value; if (setting != null) { var scanLibrarySetting = setting; @@ -75,7 +75,7 @@ public class TaskScheduler : ITaskScheduler RecurringJob.AddOrUpdate("scan-libraries", () => _scannerService.ScanLibraries(), Cron.Daily, TimeZoneInfo.Local); } - setting = Task.Run(() => _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.TaskBackup)).Result.Value; + setting = (await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.TaskBackup)).Value; if (setting != null) { _logger.LogDebug("Scheduling Backup Task for {Setting}", setting); diff --git a/UI/Web/src/app/cards/card-detail-layout/card-detail-layout.component.ts b/UI/Web/src/app/cards/card-detail-layout/card-detail-layout.component.ts index d3cb24235..eb301641d 100644 --- a/UI/Web/src/app/cards/card-detail-layout/card-detail-layout.component.ts +++ b/UI/Web/src/app/cards/card-detail-layout/card-detail-layout.component.ts @@ -529,9 +529,14 @@ export class CardDetailLayoutComponent implements OnInit, OnDestroy { updateSortOrder() { this.isAscendingSort = !this.isAscendingSort; - if (this.filter.sortOptions !== null) { - this.filter.sortOptions.isAscending = this.isAscendingSort; + if (this.filter.sortOptions === null) { + this.filter.sortOptions = { + isAscending: this.isAscendingSort, + sortField: SortField.SortName + } } + + this.filter.sortOptions.isAscending = this.isAscendingSort; } getPersonsSettings(role: PersonRole) { diff --git a/UI/Web/src/app/library-detail/library-detail.component.html b/UI/Web/src/app/library-detail/library-detail.component.html index 003475563..cebeac178 100644 --- a/UI/Web/src/app/library-detail/library-detail.component.html +++ b/UI/Web/src/app/library-detail/library-detail.component.html @@ -1,5 +1,5 @@ - {{seriesMetadata.releaseYear}} - {{seriesMetadata.language}} + {{seriesMetadata.language}} {{utilityService.mangaFormat(series.format)}}