diff --git a/API/API.csproj b/API/API.csproj index a9eb97e..24d1e9c 100644 --- a/API/API.csproj +++ b/API/API.csproj @@ -19,6 +19,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/API/Program.cs b/API/Program.cs index f4b4b24..ef4da11 100644 --- a/API/Program.cs +++ b/API/Program.cs @@ -122,12 +122,9 @@ using (IServiceScope scope = app.Services.CreateScope()) context.LocalLibraries.Add(new LocalLibrary(TrangaSettings.downloadLocation, "Default Library")); context.Jobs.AddRange(context.Jobs.Where(j => j.JobType == JobType.DownloadAvailableChaptersJob) - .AsEnumerable() - .Select(dacj => - { - DownloadAvailableChaptersJob? j = dacj as DownloadAvailableChaptersJob; - return new UpdateChaptersDownloadedJob(j!.Manga, 0); - })); + .Include(downloadAvailableChaptersJob => ((DownloadAvailableChaptersJob)downloadAvailableChaptersJob).Manga) + .ToList() + .Select(dacj => new UpdateChaptersDownloadedJob(((DownloadAvailableChaptersJob)dacj).Manga, 0))); context.Jobs.RemoveRange(context.Jobs.Where(j => j.state == JobState.Completed && j.RecurrenceMs < 1)); foreach (Job job in context.Jobs.Where(j => j.state == JobState.Running)) { @@ -153,7 +150,7 @@ using (IServiceScope scope = app.Services.CreateScope()) TrangaSettings.Load(); Tranga.StartLogger(); Tranga.JobStarterThread.Start(app.Services); -Tranga.NotificationSenderThread.Start(app.Services); +//Tranga.NotificationSenderThread.Start(app.Services); //TODO RE-ENABLE app.UseCors("AllowAll"); diff --git a/API/Schema/Contexts/PgsqlContext.cs b/API/Schema/Contexts/PgsqlContext.cs index 1ca0fed..594c9c9 100644 --- a/API/Schema/Contexts/PgsqlContext.cs +++ b/API/Schema/Contexts/PgsqlContext.cs @@ -50,7 +50,7 @@ public class PgsqlContext(DbContextOptions options) : DbContext(op .OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity() .Navigation(j => j.Manga) - .AutoInclude(); + .EnableLazyLoading(); modelBuilder.Entity() .HasOne(j => j.Manga) .WithMany() @@ -59,7 +59,7 @@ public class PgsqlContext(DbContextOptions options) : DbContext(op .OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity() .Navigation(j => j.Manga) - .AutoInclude(); + .EnableLazyLoading(); modelBuilder.Entity() .HasOne(j => j.Chapter) .WithMany() @@ -68,7 +68,7 @@ public class PgsqlContext(DbContextOptions options) : DbContext(op .OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity() .Navigation(j => j.Chapter) - .AutoInclude(); + .EnableLazyLoading(); modelBuilder.Entity() .HasOne(j => j.Manga) .WithMany() @@ -77,7 +77,7 @@ public class PgsqlContext(DbContextOptions options) : DbContext(op .OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity() .Navigation(j => j.Manga) - .AutoInclude(); + .EnableLazyLoading(); modelBuilder.Entity() .HasOne(j => j.ToLibrary) .WithMany() @@ -86,7 +86,7 @@ public class PgsqlContext(DbContextOptions options) : DbContext(op .OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity() .Navigation(j => j.ToLibrary) - .AutoInclude(); + .EnableLazyLoading(); modelBuilder.Entity() .HasOne(j => j.Manga) .WithMany() @@ -95,7 +95,7 @@ public class PgsqlContext(DbContextOptions options) : DbContext(op .OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity() .Navigation(j => j.Manga) - .AutoInclude(); + .EnableLazyLoading(); modelBuilder.Entity() .HasOne(j => j.Manga) .WithMany() @@ -104,14 +104,13 @@ public class PgsqlContext(DbContextOptions options) : DbContext(op .OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity() .Navigation(j => j.Manga) - .AutoInclude(); + .EnableLazyLoading(); //Job has possible ParentJob modelBuilder.Entity() - .HasMany() - .WithOne(childJob => childJob.ParentJob) + .HasOne(childJob => childJob.ParentJob) + .WithMany() .HasForeignKey(childjob => childjob.ParentJobId) - .IsRequired(false) .OnDelete(DeleteBehavior.Cascade); //Job might be dependent on other Jobs modelBuilder.Entity() diff --git a/API/Schema/Jobs/DownloadAvailableChaptersJob.cs b/API/Schema/Jobs/DownloadAvailableChaptersJob.cs index 1e45cfa..4b1ae44 100644 --- a/API/Schema/Jobs/DownloadAvailableChaptersJob.cs +++ b/API/Schema/Jobs/DownloadAvailableChaptersJob.cs @@ -1,5 +1,6 @@ using System.ComponentModel.DataAnnotations; using API.Schema.Contexts; +using Microsoft.EntityFrameworkCore.Infrastructure; using Newtonsoft.Json; namespace API.Schema.Jobs; @@ -7,7 +8,15 @@ namespace API.Schema.Jobs; public class DownloadAvailableChaptersJob : Job { [StringLength(64)] [Required] public string MangaId { get; init; } - [JsonIgnore] public Manga Manga { get; init; } = null!; + + private Manga _manga = null!; + + [JsonIgnore] + public Manga Manga + { + get => LazyLoader.Load(this, ref _manga); + init => _manga = value; + } public DownloadAvailableChaptersJob(Manga manga, ulong recurrenceMs, Job? parentJob = null, ICollection? dependsOnJobs = null) : base(TokenGen.CreateToken(typeof(DownloadAvailableChaptersJob)), JobType.DownloadAvailableChaptersJob, recurrenceMs, parentJob, dependsOnJobs) @@ -19,8 +28,8 @@ public class DownloadAvailableChaptersJob : Job /// /// EF ONLY!!! /// - internal DownloadAvailableChaptersJob(string mangaId, ulong recurrenceMs, string? parentJobId) - : base(TokenGen.CreateToken(typeof(DownloadAvailableChaptersJob)), JobType.DownloadAvailableChaptersJob, recurrenceMs, parentJobId) + internal DownloadAvailableChaptersJob(ILazyLoader lazyLoader, string mangaId, ulong recurrenceMs, string? parentJobId) + : base(lazyLoader, TokenGen.CreateToken(typeof(DownloadAvailableChaptersJob)), JobType.DownloadAvailableChaptersJob, recurrenceMs, parentJobId) { this.MangaId = mangaId; } diff --git a/API/Schema/Jobs/DownloadMangaCoverJob.cs b/API/Schema/Jobs/DownloadMangaCoverJob.cs index d748fa3..1400d65 100644 --- a/API/Schema/Jobs/DownloadMangaCoverJob.cs +++ b/API/Schema/Jobs/DownloadMangaCoverJob.cs @@ -1,6 +1,7 @@ using System.ComponentModel.DataAnnotations; using API.Schema.Contexts; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; using Newtonsoft.Json; namespace API.Schema.Jobs; @@ -8,7 +9,15 @@ namespace API.Schema.Jobs; public class DownloadMangaCoverJob : Job { [StringLength(64)] [Required] public string MangaId { get; init; } - [JsonIgnore] public Manga Manga { get; init; } = null!; + + private Manga _manga = null!; + + [JsonIgnore] + public Manga Manga + { + get => LazyLoader.Load(this, ref _manga); + init => _manga = value; + } public DownloadMangaCoverJob(Manga manga, Job? parentJob = null, ICollection? dependsOnJobs = null) : base(TokenGen.CreateToken(typeof(DownloadMangaCoverJob)), JobType.DownloadMangaCoverJob, 0, parentJob, dependsOnJobs) @@ -20,8 +29,8 @@ public class DownloadMangaCoverJob : Job /// /// EF ONLY!!! /// - internal DownloadMangaCoverJob(string mangaId, string? parentJobId) - : base(TokenGen.CreateToken(typeof(DownloadMangaCoverJob)), JobType.DownloadMangaCoverJob, 0, parentJobId) + internal DownloadMangaCoverJob(ILazyLoader lazyLoader, string mangaId, string? parentJobId) + : base(lazyLoader, TokenGen.CreateToken(typeof(DownloadMangaCoverJob)), JobType.DownloadMangaCoverJob, 0, parentJobId) { this.MangaId = mangaId; } diff --git a/API/Schema/Jobs/DownloadSingleChapterJob.cs b/API/Schema/Jobs/DownloadSingleChapterJob.cs index 5a84e7e..1f1bc70 100644 --- a/API/Schema/Jobs/DownloadSingleChapterJob.cs +++ b/API/Schema/Jobs/DownloadSingleChapterJob.cs @@ -4,6 +4,7 @@ using System.Runtime.InteropServices; using API.MangaDownloadClients; using API.Schema.Contexts; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; using Newtonsoft.Json; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Formats.Jpeg; @@ -17,7 +18,14 @@ public class DownloadSingleChapterJob : Job { [StringLength(64)] [Required] public string ChapterId { get; init; } - [JsonIgnore] public Chapter Chapter { get; init; } = null!; + private Chapter _chapter = null!; + + [JsonIgnore] + public Chapter Chapter + { + get => LazyLoader.Load(this, ref _chapter); + init => _chapter = value; + } public DownloadSingleChapterJob(Chapter chapter, Job? parentJob = null, ICollection? dependsOnJobs = null) : base(TokenGen.CreateToken(typeof(DownloadSingleChapterJob)), JobType.DownloadSingleChapterJob, 0, parentJob, dependsOnJobs) @@ -29,8 +37,8 @@ public class DownloadSingleChapterJob : Job /// /// EF ONLY!!! /// - internal DownloadSingleChapterJob(string chapterId, string? parentJobId) - : base(TokenGen.CreateToken(typeof(DownloadSingleChapterJob)), JobType.DownloadSingleChapterJob, 0, parentJobId) + internal DownloadSingleChapterJob(ILazyLoader lazyLoader, string chapterId, string? parentJobId) + : base(lazyLoader, TokenGen.CreateToken(typeof(DownloadSingleChapterJob)), JobType.DownloadSingleChapterJob, 0, parentJobId) { this.ChapterId = chapterId; } diff --git a/API/Schema/Jobs/Job.cs b/API/Schema/Jobs/Job.cs index fbb36c3..100c536 100644 --- a/API/Schema/Jobs/Job.cs +++ b/API/Schema/Jobs/Job.cs @@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations.Schema; using API.Schema.Contexts; using log4net; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; using Newtonsoft.Json; namespace API.Schema.Jobs; @@ -32,6 +33,7 @@ public abstract class Job [JsonIgnore] [NotMapped] internal bool DependenciesFulfilled => DependsOnJobs.All(j => j.IsCompleted); [NotMapped] [JsonIgnore] protected ILog Log { get; init; } + [NotMapped] [JsonIgnore] protected ILazyLoader LazyLoader { get; init; } protected Job(string jobId, JobType jobType, ulong recurrenceMs, Job? parentJob = null, ICollection? dependsOnJobs = null) { @@ -48,8 +50,9 @@ public abstract class Job /// /// EF ONLY!!! /// - protected internal Job(string jobId, JobType jobType, ulong recurrenceMs, string? parentJobId) + protected internal Job(ILazyLoader lazyLoader, string jobId, JobType jobType, ulong recurrenceMs, string? parentJobId) { + this.LazyLoader = lazyLoader; this.JobId = jobId; this.JobType = jobType; this.RecurrenceMs = recurrenceMs; diff --git a/API/Schema/Jobs/MoveFileOrFolderJob.cs b/API/Schema/Jobs/MoveFileOrFolderJob.cs index ef71104..dbd9c71 100644 --- a/API/Schema/Jobs/MoveFileOrFolderJob.cs +++ b/API/Schema/Jobs/MoveFileOrFolderJob.cs @@ -1,5 +1,6 @@ using System.ComponentModel.DataAnnotations; using API.Schema.Contexts; +using Microsoft.EntityFrameworkCore.Infrastructure; namespace API.Schema.Jobs; @@ -22,8 +23,8 @@ public class MoveFileOrFolderJob : Job /// /// EF ONLY!!! /// - internal MoveFileOrFolderJob(string jobId, string fromLocation, string toLocation, string? parentJobId) - : base(jobId, JobType.MoveFileOrFolderJob, 0, parentJobId) + internal MoveFileOrFolderJob(ILazyLoader lazyLoader, string jobId, string fromLocation, string toLocation, string? parentJobId) + : base(lazyLoader, jobId, JobType.MoveFileOrFolderJob, 0, parentJobId) { this.FromLocation = fromLocation; this.ToLocation = toLocation; diff --git a/API/Schema/Jobs/MoveMangaLibraryJob.cs b/API/Schema/Jobs/MoveMangaLibraryJob.cs index 76dcafa..2b044c1 100644 --- a/API/Schema/Jobs/MoveMangaLibraryJob.cs +++ b/API/Schema/Jobs/MoveMangaLibraryJob.cs @@ -1,6 +1,7 @@ using System.ComponentModel.DataAnnotations; using API.Schema.Contexts; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; using Newtonsoft.Json; namespace API.Schema.Jobs; @@ -8,7 +9,15 @@ namespace API.Schema.Jobs; public class MoveMangaLibraryJob : Job { [StringLength(64)] [Required] public string MangaId { get; init; } - [JsonIgnore] public Manga Manga { get; init; } = null!; + + private Manga _manga = null!; + + [JsonIgnore] + public Manga Manga + { + get => LazyLoader.Load(this, ref _manga); + init => _manga = value; + } [StringLength(64)] [Required] public string ToLibraryId { get; init; } public LocalLibrary ToLibrary { get; init; } = null!; @@ -24,8 +33,8 @@ public class MoveMangaLibraryJob : Job /// /// EF ONLY!!! /// - internal MoveMangaLibraryJob(string mangaId, string toLibraryId, string? parentJobId) - : base(TokenGen.CreateToken(typeof(MoveMangaLibraryJob)), JobType.MoveMangaLibraryJob, 0, parentJobId) + internal MoveMangaLibraryJob(ILazyLoader lazyLoader, string mangaId, string toLibraryId, string? parentJobId) + : base(lazyLoader, TokenGen.CreateToken(typeof(MoveMangaLibraryJob)), JobType.MoveMangaLibraryJob, 0, parentJobId) { this.MangaId = mangaId; this.ToLibraryId = toLibraryId; diff --git a/API/Schema/Jobs/RetrieveChaptersJob.cs b/API/Schema/Jobs/RetrieveChaptersJob.cs index d304af8..d0b37d7 100644 --- a/API/Schema/Jobs/RetrieveChaptersJob.cs +++ b/API/Schema/Jobs/RetrieveChaptersJob.cs @@ -1,6 +1,7 @@ using System.ComponentModel.DataAnnotations; using API.Schema.Contexts; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; using Newtonsoft.Json; namespace API.Schema.Jobs; @@ -8,7 +9,15 @@ namespace API.Schema.Jobs; public class RetrieveChaptersJob : Job { [StringLength(64)] [Required] public string MangaId { get; init; } - [JsonIgnore] public Manga Manga { get; init; } = null!; + + private Manga _manga = null!; + + [JsonIgnore] + public Manga Manga + { + get => LazyLoader.Load(this, ref _manga); + init => _manga = value; + } [StringLength(8)] [Required] public string Language { get; private set; } public RetrieveChaptersJob(Manga manga, string language, ulong recurrenceMs, Job? parentJob = null, ICollection? dependsOnJobs = null) @@ -22,8 +31,8 @@ public class RetrieveChaptersJob : Job /// /// EF ONLY!!! /// - internal RetrieveChaptersJob(string mangaId, string language, ulong recurrenceMs, string? parentJobId) - : base(TokenGen.CreateToken(typeof(RetrieveChaptersJob)), JobType.RetrieveChaptersJob, recurrenceMs, parentJobId) + internal RetrieveChaptersJob(ILazyLoader lazyLoader, string mangaId, string language, ulong recurrenceMs, string? parentJobId) + : base(lazyLoader, TokenGen.CreateToken(typeof(RetrieveChaptersJob)), JobType.RetrieveChaptersJob, recurrenceMs, parentJobId) { this.MangaId = mangaId; this.Language = language; diff --git a/API/Schema/Jobs/UpdateChaptersDownloadedJob.cs b/API/Schema/Jobs/UpdateChaptersDownloadedJob.cs index a3d3859..14dea49 100644 --- a/API/Schema/Jobs/UpdateChaptersDownloadedJob.cs +++ b/API/Schema/Jobs/UpdateChaptersDownloadedJob.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; using API.Schema.Contexts; -using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; using Newtonsoft.Json; namespace API.Schema.Jobs; @@ -8,7 +8,15 @@ namespace API.Schema.Jobs; public class UpdateChaptersDownloadedJob : Job { [StringLength(64)] [Required] public string MangaId { get; init; } - [JsonIgnore] public Manga Manga { get; init; } = null!; + + private Manga _manga = null!; + + [JsonIgnore] + public Manga Manga + { + get => LazyLoader.Load(this, ref _manga); + init => _manga = value; + } public UpdateChaptersDownloadedJob(Manga manga, ulong recurrenceMs, Job? parentJob = null, ICollection? dependsOnJobs = null) : base(TokenGen.CreateToken(typeof(UpdateChaptersDownloadedJob)), JobType.UpdateChaptersDownloadedJob, recurrenceMs, parentJob, dependsOnJobs) @@ -20,8 +28,8 @@ public class UpdateChaptersDownloadedJob : Job /// /// EF ONLY!!! /// - internal UpdateChaptersDownloadedJob(string mangaId, ulong recurrenceMs, string? parentJobId) - : base(TokenGen.CreateToken(typeof(UpdateChaptersDownloadedJob)), JobType.UpdateChaptersDownloadedJob, recurrenceMs, parentJobId) + internal UpdateChaptersDownloadedJob(ILazyLoader lazyLoader, string mangaId, ulong recurrenceMs, string? parentJobId) + : base(lazyLoader, TokenGen.CreateToken(typeof(UpdateChaptersDownloadedJob)), JobType.UpdateChaptersDownloadedJob, recurrenceMs, parentJobId) { this.MangaId = mangaId; } diff --git a/API/Schema/Jobs/UpdateSingleChapterDownloadedJob.cs b/API/Schema/Jobs/UpdateSingleChapterDownloadedJob.cs index 15638c4..fa787cc 100644 --- a/API/Schema/Jobs/UpdateSingleChapterDownloadedJob.cs +++ b/API/Schema/Jobs/UpdateSingleChapterDownloadedJob.cs @@ -1,6 +1,7 @@ using System.ComponentModel.DataAnnotations; using API.Schema.Contexts; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; using Newtonsoft.Json; namespace API.Schema.Jobs; @@ -8,7 +9,15 @@ namespace API.Schema.Jobs; public class UpdateSingleChapterDownloadedJob : Job { [StringLength(64)] [Required] public string ChapterId { get; init; } - [JsonIgnore] public Chapter Chapter { get; init; } = null!; + + private Chapter _chapter = null!; + + [JsonIgnore] + public Chapter Chapter + { + get => LazyLoader.Load(this, ref _chapter); + init => _chapter = value; + } public UpdateSingleChapterDownloadedJob(Chapter chapter, Job? parentJob = null, ICollection? dependsOnJobs = null) : base(TokenGen.CreateToken(typeof(UpdateSingleChapterDownloadedJob)), JobType.UpdateSingleChapterDownloadedJob, 0, parentJob, dependsOnJobs) @@ -20,8 +29,8 @@ public class UpdateSingleChapterDownloadedJob : Job /// /// EF ONLY!!! /// - internal UpdateSingleChapterDownloadedJob(string chapterId, string? parentJobId) - : base(TokenGen.CreateToken(typeof(UpdateSingleChapterDownloadedJob)), JobType.UpdateSingleChapterDownloadedJob, 0, parentJobId) + internal UpdateSingleChapterDownloadedJob(ILazyLoader lazyLoader, string chapterId, string? parentJobId) + : base(lazyLoader, TokenGen.CreateToken(typeof(UpdateSingleChapterDownloadedJob)), JobType.UpdateSingleChapterDownloadedJob, 0, parentJobId) { this.ChapterId = chapterId; }