Metadata Optimizations (#910)

* Added a tooltip to inform user that format and collection filter selections do not only show for the selected library.

* Refactored a lot of code around when we update chapter cover images. Applied an optimization for when we re-calculate volume/series covers, such that it only occurs when the first chapter's image updates.

* Updated code to ensure only lastmodified gets refreshed in metadata since it always follows a scan

* Optimized how metadata is populated on the series. Instead of re-reading the comicInfos, instead I read the data from the underlying chapter entities. This reduces N additional reads AND enables the ability in the future to show/edit chapter level metadata.

* Spelling mistake

* Fixed a concurency issue by not selecting Genres from DB. Added a test for long paths.

* Fixed a bug in filter where collection tag wasn't populating on load

* Cleaned up the logic for changelog to better compare against the installed verison. For nightly users, show the last stable as installed.

* Removed some demo code

* SplitQuery to allow loading tags much faster for series metadata load.
This commit is contained in:
Joseph Milazzo 2022-01-08 06:41:47 -08:00 committed by GitHub
parent c215d5b7a8
commit 0be0e294aa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 1671 additions and 90 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,108 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace API.Data.Migrations
{
public partial class ChapterMetadataOptimization : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Chapter_Genre_GenreId",
table: "Chapter");
migrationBuilder.DropIndex(
name: "IX_Chapter_GenreId",
table: "Chapter");
migrationBuilder.DropColumn(
name: "GenreId",
table: "Chapter");
migrationBuilder.DropColumn(
name: "FullscreenMode",
table: "AppUserPreferences");
migrationBuilder.AddColumn<string>(
name: "Language",
table: "Chapter",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "Summary",
table: "Chapter",
type: "TEXT",
nullable: true);
migrationBuilder.CreateTable(
name: "ChapterGenre",
columns: table => new
{
ChaptersId = table.Column<int>(type: "INTEGER", nullable: false),
GenresId = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ChapterGenre", x => new { x.ChaptersId, x.GenresId });
table.ForeignKey(
name: "FK_ChapterGenre_Chapter_ChaptersId",
column: x => x.ChaptersId,
principalTable: "Chapter",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ChapterGenre_Genre_GenresId",
column: x => x.GenresId,
principalTable: "Genre",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_ChapterGenre_GenresId",
table: "ChapterGenre",
column: "GenresId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ChapterGenre");
migrationBuilder.DropColumn(
name: "Language",
table: "Chapter");
migrationBuilder.DropColumn(
name: "Summary",
table: "Chapter");
migrationBuilder.AddColumn<int>(
name: "GenreId",
table: "Chapter",
type: "INTEGER",
nullable: true);
migrationBuilder.AddColumn<int>(
name: "FullscreenMode",
table: "AppUserPreferences",
type: "INTEGER",
nullable: false,
defaultValue: 0);
migrationBuilder.CreateIndex(
name: "IX_Chapter_GenreId",
table: "Chapter",
column: "GenreId");
migrationBuilder.AddForeignKey(
name: "FK_Chapter_Genre_GenreId",
table: "Chapter",
column: "GenreId",
principalTable: "Genre",
principalColumn: "Id");
}
}
}

View file

@ -186,9 +186,6 @@ namespace API.Data.Migrations
b.Property<bool>("BookReaderTapToPaginate")
.HasColumnType("INTEGER");
b.Property<int>("FullscreenMode")
.HasColumnType("INTEGER");
b.Property<int>("PageSplitOption")
.HasColumnType("INTEGER");
@ -311,12 +308,12 @@ namespace API.Data.Migrations
b.Property<DateTime>("Created")
.HasColumnType("TEXT");
b.Property<int?>("GenreId")
.HasColumnType("INTEGER");
b.Property<bool>("IsSpecial")
.HasColumnType("INTEGER");
b.Property<string>("Language")
.HasColumnType("TEXT");
b.Property<DateTime>("LastModified")
.HasColumnType("TEXT");
@ -332,6 +329,9 @@ namespace API.Data.Migrations
b.Property<DateTime>("ReleaseDate")
.HasColumnType("TEXT");
b.Property<string>("Summary")
.HasColumnType("TEXT");
b.Property<string>("Title")
.HasColumnType("TEXT");
@ -343,8 +343,6 @@ namespace API.Data.Migrations
b.HasKey("Id");
b.HasIndex("GenreId");
b.HasIndex("VolumeId");
b.ToTable("Chapter");
@ -749,6 +747,21 @@ namespace API.Data.Migrations
b.ToTable("AppUserLibrary");
});
modelBuilder.Entity("ChapterGenre", b =>
{
b.Property<int>("ChaptersId")
.HasColumnType("INTEGER");
b.Property<int>("GenresId")
.HasColumnType("INTEGER");
b.HasKey("ChaptersId", "GenresId");
b.HasIndex("GenresId");
b.ToTable("ChapterGenre");
});
modelBuilder.Entity("ChapterPerson", b =>
{
b.Property<int>("ChapterMetadatasId")
@ -1000,10 +1013,6 @@ namespace API.Data.Migrations
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")
@ -1129,6 +1138,21 @@ namespace API.Data.Migrations
.IsRequired();
});
modelBuilder.Entity("ChapterGenre", b =>
{
b.HasOne("API.Entities.Chapter", null)
.WithMany()
.HasForeignKey("ChaptersId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("API.Entities.Genre", null)
.WithMany()
.HasForeignKey("GenresId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("ChapterPerson", b =>
{
b.HasOne("API.Entities.Chapter", null)
@ -1280,11 +1304,6 @@ namespace API.Data.Migrations
b.Navigation("Files");
});
modelBuilder.Entity("API.Entities.Genre", b =>
{
b.Navigation("Chapters");
});
modelBuilder.Entity("API.Entities.Library", b =>
{
b.Navigation("Folders");