Restrcutured the database, and updated pipeline to include cover art.
This commit is contained in:
@@ -7,7 +7,7 @@ public class Manga
|
||||
|
||||
public virtual ICollection<MangaCover> Covers { get; set; } = [];
|
||||
public virtual ICollection<MangaTitle> Titles { get; set; } = [];
|
||||
//public virtual ICollection<MangaDescription> Descriptions { get; set; } = [];
|
||||
public virtual ICollection<MangaDescription> Descriptions { get; set; } = [];
|
||||
public virtual ICollection<MangaSource> Sources { get; set; } = [];
|
||||
public virtual ICollection<MangaContributor> Contributors { get; set; } = [];
|
||||
public virtual ICollection<MangaGenre> Genres { get; set; } = [];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -6,9 +6,9 @@ public class MangaDescription
|
||||
{
|
||||
public int MangaDescriptionId { get; set; }
|
||||
|
||||
public int MangaSourceId { get; set; }
|
||||
public required MangaSource MangaSource { get; set; }
|
||||
public int MangaId { get; set; }
|
||||
public required Manga Manga { get; set; }
|
||||
|
||||
public required string Name { get; set; }
|
||||
public required string Text { get; set; }
|
||||
public required Language Language { get; set; }
|
||||
}
|
||||
@@ -12,6 +12,8 @@ public class MangaSource
|
||||
|
||||
public required string Url { get; set; }
|
||||
|
||||
public virtual ICollection<MangaDescription> Descriptions { get; set; } = [];
|
||||
public virtual ICollection<SourceTitle> Titles { get; set; } = [];
|
||||
public virtual ICollection<SourceDescription> Descriptions { get; set; } = [];
|
||||
public virtual ICollection<SourceCover> Covers { get; set; } = [];
|
||||
public virtual ICollection<SourceChapter> Chapters { get; set; } = [];
|
||||
}
|
||||
14
MangaReader.Core/Data/SourceCover.cs
Normal file
14
MangaReader.Core/Data/SourceCover.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace MangaReader.Core.Data;
|
||||
|
||||
public class SourceCover
|
||||
{
|
||||
public int SourceCoverId { get; set; }
|
||||
|
||||
public int MangaSourceId { get; set; }
|
||||
public required MangaSource MangaSource { get; set; }
|
||||
|
||||
public required string Url { get; set; }
|
||||
|
||||
public int? MangaCoverId { get; set; }
|
||||
public MangaCover? MangaCover { get; set; }
|
||||
}
|
||||
14
MangaReader.Core/Data/SourceDescription.cs
Normal file
14
MangaReader.Core/Data/SourceDescription.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using MangaReader.Core.Common;
|
||||
|
||||
namespace MangaReader.Core.Data;
|
||||
|
||||
public class SourceDescription
|
||||
{
|
||||
public int SourceDescriptionId { get; set; }
|
||||
|
||||
public int MangaSourceId { get; set; }
|
||||
public required MangaSource MangaSource { get; set; }
|
||||
|
||||
public required string Text { get; set; }
|
||||
public required Language Language { get; set; }
|
||||
}
|
||||
15
MangaReader.Core/Data/SourceTitle.cs
Normal file
15
MangaReader.Core/Data/SourceTitle.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using MangaReader.Core.Common;
|
||||
|
||||
namespace MangaReader.Core.Data;
|
||||
|
||||
public class SourceTitle
|
||||
{
|
||||
public int SourceTitleId { get; set; }
|
||||
|
||||
public int MangaSourceId { get; set; }
|
||||
public required MangaSource MangaSource { get; set; }
|
||||
|
||||
public required string Name { get; set; }
|
||||
public required Language Language { get; set; }
|
||||
public bool IsPrimary { get; set; }
|
||||
}
|
||||
Reference in New Issue
Block a user