Restrcutured the database, and updated pipeline to include cover art.

This commit is contained in:
2025-10-14 00:06:31 -04:00
parent 33e521e8bb
commit 4797d3c559
29 changed files with 488 additions and 95 deletions

View File

@@ -17,6 +17,10 @@ public class MangaContext(DbContextOptions options) : DbContext(options)
//public DbSet<MangaChapter> MangaChapters { get; set; }
//public DbSet<ChapterSource> ChapterSources { get; set; }
//public DbSet<ChapterPage> ChapterPages { get; set; }
public DbSet<SourceTitle> SourceTitles { get; set; }
public DbSet<SourceDescription> SourceDescriptions { get; set; }
public DbSet<SourceCover> SourceCovers { get; set; }
public DbSet<SourceChapter> SourceChapters { get; set; }
public DbSet<SourcePage> SourcePages { get; set; }
@@ -37,6 +41,9 @@ public class MangaContext(DbContextOptions options) : DbContext(options)
//ConfigureMangaChapter(modelBuilder);
//ConfigureChapterSource(modelBuilder);
//ConfigureChapterPage(modelBuilder);
ConfigureSourceTitle(modelBuilder);
ConfigureSourceDescription(modelBuilder);
ConfigureMangaSourceCover(modelBuilder);
ConfigureMangaSourceChapter(modelBuilder);
ConfigureSourcePage(modelBuilder);
}
@@ -117,7 +124,7 @@ public class MangaContext(DbContextOptions options) : DbContext(options)
.HasKey(mangaDescription => mangaDescription.MangaDescriptionId);
modelBuilder.Entity<MangaDescription>()
.Property(mangaDescription => mangaDescription.Name)
.Property(mangaDescription => mangaDescription.Text)
.IsRequired();
modelBuilder.Entity<MangaDescription>()
@@ -125,18 +132,18 @@ public class MangaContext(DbContextOptions options) : DbContext(options)
.IsRequired();
modelBuilder.Entity<MangaDescription>()
.HasIndex(mangaDescription => new { mangaDescription.MangaSourceId, mangaDescription.Name, mangaDescription.Language })
.HasIndex(mangaDescription => new { mangaDescription.MangaId, mangaDescription.Text, mangaDescription.Language })
.IsUnique();
modelBuilder
.Entity<MangaDescription>()
.HasIndex(mangaDescription => mangaDescription.Name);
.HasIndex(mangaDescription => mangaDescription.Text);
modelBuilder
.Entity<MangaDescription>()
.HasOne(x => x.MangaSource)
.HasOne(x => x.Manga)
.WithMany(x => x.Descriptions)
.HasForeignKey(x => x.MangaSourceId)
.HasForeignKey(x => x.MangaId)
.OnDelete(DeleteBehavior.Cascade);
}
@@ -273,6 +280,95 @@ public class MangaContext(DbContextOptions options) : DbContext(options)
// .OnDelete(DeleteBehavior.Cascade);
//}
private static void ConfigureSourceTitle(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<SourceTitle>()
.HasKey(x => x.SourceTitleId);
modelBuilder
.Entity<SourceTitle>()
.Property(x => x.Name)
.IsRequired()
.HasMaxLength(512);
// Avoid duplicate rows coming from the same source record
modelBuilder
.Entity<SourceTitle>()
.HasIndex(x => new { x.MangaSourceId, x.Language, x.Name })
.IsUnique();
modelBuilder
.Entity<SourceTitle>()
.HasOne(x => x.MangaSource)
.WithMany(x => x.Titles)
.HasForeignKey(x => x.MangaSourceId)
.OnDelete(DeleteBehavior.Cascade);
}
private static void ConfigureSourceDescription(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<SourceDescription>()
.HasKey(x => x.SourceDescriptionId);
modelBuilder
.Entity<SourceDescription>()
.Property(x => x.Text)
.IsRequired();
// If sources can emit multiple descriptions per language, keep it non-unique.
// If not, uncomment:
//modelBuilder
// .Entity<SourceDescription>()
// .HasIndex(x => new { x.MangaSourceId, x.Language })
// .IsUnique();
modelBuilder
.Entity<SourceDescription>()
.HasOne(x => x.MangaSource)
.WithMany(x => x.Descriptions)
.HasForeignKey(x => x.MangaSourceId)
.OnDelete(DeleteBehavior.Cascade);
}
private static void ConfigureMangaSourceCover(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<SourceCover>()
.HasKey(sourceCover => sourceCover.SourceCoverId);
modelBuilder
.Entity<SourceCover>()
.Property(x => x.Url)
.IsRequired()
.HasMaxLength(2048);
modelBuilder
.Entity<SourceCover>()
.HasIndex(sourceCover => new { sourceCover.MangaSourceId, sourceCover.Url })
.IsUnique(true);
modelBuilder
.Entity<SourceCover>()
.HasOne(x => x.MangaSource)
.WithMany(x => x.Covers)
.HasForeignKey(x => x.MangaSourceId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder
.Entity<SourceCover>()
.HasOne(x => x.MangaCover)
.WithMany() // or .WithMany(c => c.SourceCovers) if you add a collection nav on MangaCover
.HasForeignKey(x => x.MangaCoverId)
.OnDelete(DeleteBehavior.SetNull);
// Helpful for lookups when you dedupe/file-link after download
modelBuilder
.Entity<SourceCover>()
.HasIndex(x => x.MangaCoverId);
}
private static void ConfigureMangaSourceChapter(ModelBuilder modelBuilder)
{
modelBuilder