From 45a8f7a038f66dbe72660fc5767379b8a59677f3 Mon Sep 17 00:00:00 2001 From: Glax Date: Fri, 14 Mar 2025 00:39:52 +0100 Subject: [PATCH] Logging --- API/Controllers/SearchController.cs | 30 +- .../20250313233529_dev-130325-9.Designer.cs | 787 ++++++++++++++++++ API/Migrations/20250313233529_dev-130325-9.cs | 103 +++ API/Migrations/PgsqlContextModelSnapshot.cs | 47 +- API/Schema/Link.cs | 7 - API/Schema/PgsqlContext.cs | 6 +- API/TrangaSettings.cs | 2 +- API/appsettings.Development.json | 2 +- API/appsettings.json | 2 +- 9 files changed, 943 insertions(+), 43 deletions(-) create mode 100644 API/Migrations/20250313233529_dev-130325-9.Designer.cs create mode 100644 API/Migrations/20250313233529_dev-130325-9.cs diff --git a/API/Controllers/SearchController.cs b/API/Controllers/SearchController.cs index 4b9ccdc..08d6c1a 100644 --- a/API/Controllers/SearchController.cs +++ b/API/Controllers/SearchController.cs @@ -130,19 +130,19 @@ public class SearchController(PgsqlContext context) : Controller { if (manga is null) return null; - - Manga? existing = context.Manga.FirstOrDefault(m => - m.MangaId == manga.MangaId); + + Manga? existing = context.Manga.Find(manga.MangaId); if (tags is not null) { IEnumerable mergedTags = tags.Select(mt => { - MangaTag? inDb = context.Tags.FirstOrDefault(t => t.Equals(mt)); + MangaTag? inDb = context.Tags.Find(mt.Tag); return inDb ?? mt; }); manga.MangaTags = mergedTags.ToList(); - IEnumerable newTags = manga.MangaTags.Where(mt => !context.Tags.Any(t => t.Tag.Equals(mt.Tag))); + IEnumerable newTags = manga.MangaTags + .Where(mt => !context.Tags.Select(t => t.Tag).Contains(mt.Tag)); context.Tags.AddRange(newTags); } @@ -150,12 +150,12 @@ public class SearchController(PgsqlContext context) : Controller { IEnumerable mergedAuthors = authors.Select(ma => { - Author? inDb = context.Authors.FirstOrDefault(a => a.AuthorName == ma.AuthorName); + Author? inDb = context.Authors.Find(ma.AuthorId); return inDb ?? ma; }); manga.Authors = mergedAuthors.ToList(); - IEnumerable newAuthors = manga.Authors.Where(ma => !context.Authors.Any(a => - a.AuthorName == ma.AuthorName)); + IEnumerable newAuthors = manga.Authors + .Where(ma => !context.Authors.Select(a => a.AuthorId).Contains(ma.AuthorId)); context.Authors.AddRange(newAuthors); } @@ -163,13 +163,12 @@ public class SearchController(PgsqlContext context) : Controller { IEnumerable mergedLinks = links.Select(ml => { - Link? inDb = context.Link.FirstOrDefault(l => - l.LinkProvider == ml.LinkProvider && l.LinkUrl == ml.LinkUrl); + Link? inDb = context.Link.Find(ml.LinkId); return inDb ?? ml; }); manga.Links = mergedLinks.ToList(); - IEnumerable newLinks = manga.Links.Where(ml => !context.Link.Any(l => - l.LinkProvider == ml.LinkProvider && l.LinkUrl == ml.LinkUrl)); + IEnumerable newLinks = manga.Links + .Where(ml => !context.Link.Select(l => l.LinkId).Contains(ml.LinkId)); context.Link.AddRange(newLinks); } @@ -177,13 +176,12 @@ public class SearchController(PgsqlContext context) : Controller { IEnumerable mergedAltTitles = altTitles.Select(mat => { - MangaAltTitle? inDb = context.AltTitles.FirstOrDefault(at => - at.Language == mat.Language && at.Title == mat.Title); + MangaAltTitle? inDb = context.AltTitles.Find(mat.AltTitleId); return inDb ?? mat; }); manga.AltTitles = mergedAltTitles.ToList(); - IEnumerable newAltTitles = manga.AltTitles.Where(mat => - !context.AltTitles.Any(at => at.Language == mat.Language && at.Title == mat.Title)); + IEnumerable newAltTitles = manga.AltTitles + .Where(mat => !context.AltTitles.Select(at => at.AltTitleId).Contains(mat.AltTitleId)); context.AltTitles.AddRange(newAltTitles); } diff --git a/API/Migrations/20250313233529_dev-130325-9.Designer.cs b/API/Migrations/20250313233529_dev-130325-9.Designer.cs new file mode 100644 index 0000000..897905f --- /dev/null +++ b/API/Migrations/20250313233529_dev-130325-9.Designer.cs @@ -0,0 +1,787 @@ +// +using System; +using System.Collections.Generic; +using API.Schema; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace API.Migrations +{ + [DbContext(typeof(PgsqlContext))] + [Migration("20250313233529_dev-130325-9")] + partial class dev1303259 + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "hstore"); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("API.Schema.Author", b => + { + b.Property("AuthorId") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("AuthorName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.HasKey("AuthorId"); + + b.ToTable("Authors"); + }); + + modelBuilder.Entity("API.Schema.Chapter", b => + { + b.Property("ChapterId") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("ArchiveFileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChapterNumber") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.Property("Downloaded") + .HasColumnType("boolean"); + + b.Property("ParentMangaId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Title") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Url") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.Property("VolumeNumber") + .HasColumnType("integer"); + + b.HasKey("ChapterId"); + + b.HasIndex("ParentMangaId"); + + b.ToTable("Chapters"); + }); + + modelBuilder.Entity("API.Schema.Jobs.Job", b => + { + b.Property("JobId") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.PrimitiveCollection("DependsOnJobsIds") + .HasMaxLength(64) + .HasColumnType("text[]"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("JobType") + .HasColumnType("smallint"); + + b.Property("LastExecution") + .HasColumnType("timestamp with time zone"); + + b.Property("ParentJobId") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("RecurrenceMs") + .HasColumnType("numeric(20,0)"); + + b.Property("state") + .HasColumnType("smallint"); + + b.HasKey("JobId"); + + b.HasIndex("ParentJobId"); + + b.ToTable("Jobs"); + + b.HasDiscriminator("JobType"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("API.Schema.LibraryConnectors.LibraryConnector", b => + { + b.Property("LibraryConnectorId") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Auth") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("BaseUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LibraryType") + .HasColumnType("smallint"); + + b.HasKey("LibraryConnectorId"); + + b.ToTable("LibraryConnectors"); + + b.HasDiscriminator("LibraryType"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("API.Schema.Link", b => + { + b.Property("LinkId") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("LinkProvider") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("LinkUrl") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.Property("MangaId") + .HasColumnType("character varying(64)"); + + b.HasKey("LinkId"); + + b.HasIndex("MangaId"); + + b.ToTable("Link"); + }); + + modelBuilder.Entity("API.Schema.Manga", b => + { + b.Property("MangaId") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("CoverFileNameInCache") + .HasColumnType("text"); + + b.Property("CoverUrl") + .IsRequired() + .HasColumnType("text"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("FolderName") + .IsRequired() + .HasColumnType("text"); + + b.Property("IdOnConnectorSite") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("IgnoreChapterBefore") + .HasColumnType("real"); + + b.Property("MangaConnectorId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("OriginalLanguage") + .IsRequired() + .HasMaxLength(8) + .HasColumnType("character varying(8)"); + + b.Property("ReleaseStatus") + .HasColumnType("smallint"); + + b.Property("WebsiteUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Year") + .HasColumnType("bigint"); + + b.HasKey("MangaId"); + + b.HasIndex("MangaConnectorId"); + + b.ToTable("Manga"); + }); + + modelBuilder.Entity("API.Schema.MangaAltTitle", b => + { + b.Property("AltTitleId") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Language") + .IsRequired() + .HasMaxLength(8) + .HasColumnType("character varying(8)"); + + b.Property("MangaId") + .HasColumnType("character varying(64)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("AltTitleId"); + + b.HasIndex("MangaId"); + + b.ToTable("AltTitles"); + }); + + modelBuilder.Entity("API.Schema.MangaConnectors.MangaConnector", b => + { + b.Property("Name") + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.PrimitiveCollection("BaseUris") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("text[]"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("IconUrl") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.PrimitiveCollection("SupportedLanguages") + .IsRequired() + .HasMaxLength(8) + .HasColumnType("text[]"); + + b.HasKey("Name"); + + b.ToTable("MangaConnectors"); + + b.HasDiscriminator("Name").HasValue("MangaConnector"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("API.Schema.MangaTag", b => + { + b.Property("Tag") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.HasKey("Tag"); + + b.ToTable("Tags"); + }); + + modelBuilder.Entity("API.Schema.Notification", b => + { + b.Property("NotificationId") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Date") + .HasColumnType("timestamp with time zone"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Urgency") + .HasColumnType("smallint"); + + b.HasKey("NotificationId"); + + b.ToTable("Notifications"); + }); + + modelBuilder.Entity("API.Schema.NotificationConnectors.NotificationConnector", b => + { + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Body") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("character varying(4096)"); + + b.Property>("Headers") + .IsRequired() + .HasColumnType("hstore"); + + b.Property("HttpMethod") + .IsRequired() + .HasMaxLength(8) + .HasColumnType("character varying(8)"); + + b.Property("Url") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.HasKey("Name"); + + b.ToTable("NotificationConnectors"); + }); + + modelBuilder.Entity("AuthorManga", b => + { + b.Property("AuthorsAuthorId") + .HasColumnType("character varying(64)"); + + b.Property("MangaId") + .HasColumnType("character varying(64)"); + + b.HasKey("AuthorsAuthorId", "MangaId"); + + b.HasIndex("MangaId"); + + b.ToTable("AuthorManga"); + }); + + modelBuilder.Entity("JobJob", b => + { + b.Property("DependsOnJobsJobId") + .HasColumnType("character varying(64)"); + + b.Property("JobId") + .HasColumnType("character varying(64)"); + + b.HasKey("DependsOnJobsJobId", "JobId"); + + b.HasIndex("JobId"); + + b.ToTable("JobJob"); + }); + + modelBuilder.Entity("MangaMangaTag", b => + { + b.Property("MangaId") + .HasColumnType("character varying(64)"); + + b.Property("MangaTagsTag") + .HasColumnType("character varying(64)"); + + b.HasKey("MangaId", "MangaTagsTag"); + + b.HasIndex("MangaTagsTag"); + + b.ToTable("MangaMangaTag"); + }); + + modelBuilder.Entity("API.Schema.Jobs.DownloadAvailableChaptersJob", b => + { + b.HasBaseType("API.Schema.Jobs.Job"); + + b.Property("MangaId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.HasIndex("MangaId"); + + b.ToTable("Jobs", t => + { + t.Property("MangaId") + .HasColumnName("DownloadAvailableChaptersJob_MangaId"); + }); + + b.HasDiscriminator().HasValue((byte)1); + }); + + modelBuilder.Entity("API.Schema.Jobs.DownloadMangaCoverJob", b => + { + b.HasBaseType("API.Schema.Jobs.Job"); + + b.Property("MangaId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.HasIndex("MangaId"); + + b.HasDiscriminator().HasValue((byte)4); + }); + + modelBuilder.Entity("API.Schema.Jobs.DownloadSingleChapterJob", b => + { + b.HasBaseType("API.Schema.Jobs.Job"); + + b.Property("ChapterId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.HasIndex("ChapterId"); + + b.HasDiscriminator().HasValue((byte)0); + }); + + modelBuilder.Entity("API.Schema.Jobs.MoveFileOrFolderJob", b => + { + b.HasBaseType("API.Schema.Jobs.Job"); + + b.Property("FromLocation") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ToLocation") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasDiscriminator().HasValue((byte)3); + }); + + modelBuilder.Entity("API.Schema.Jobs.RetrieveChaptersJob", b => + { + b.HasBaseType("API.Schema.Jobs.Job"); + + b.Property("MangaId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.HasIndex("MangaId"); + + b.ToTable("Jobs", t => + { + t.Property("MangaId") + .HasColumnName("RetrieveChaptersJob_MangaId"); + }); + + b.HasDiscriminator().HasValue((byte)5); + }); + + modelBuilder.Entity("API.Schema.Jobs.UpdateFilesDownloadedJob", b => + { + b.HasBaseType("API.Schema.Jobs.Job"); + + b.Property("MangaId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.HasIndex("MangaId"); + + b.ToTable("Jobs", t => + { + t.Property("MangaId") + .HasColumnName("UpdateFilesDownloadedJob_MangaId"); + }); + + b.HasDiscriminator().HasValue((byte)6); + }); + + modelBuilder.Entity("API.Schema.Jobs.UpdateMetadataJob", b => + { + b.HasBaseType("API.Schema.Jobs.Job"); + + b.Property("MangaId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.HasIndex("MangaId"); + + b.ToTable("Jobs", t => + { + t.Property("MangaId") + .HasColumnName("UpdateMetadataJob_MangaId"); + }); + + b.HasDiscriminator().HasValue((byte)2); + }); + + modelBuilder.Entity("API.Schema.LibraryConnectors.Kavita", b => + { + b.HasBaseType("API.Schema.LibraryConnectors.LibraryConnector"); + + b.HasDiscriminator().HasValue((byte)1); + }); + + modelBuilder.Entity("API.Schema.LibraryConnectors.Komga", b => + { + b.HasBaseType("API.Schema.LibraryConnectors.LibraryConnector"); + + b.HasDiscriminator().HasValue((byte)0); + }); + + modelBuilder.Entity("API.Schema.MangaConnectors.AsuraToon", b => + { + b.HasBaseType("API.Schema.MangaConnectors.MangaConnector"); + + b.HasDiscriminator().HasValue("AsuraToon"); + }); + + modelBuilder.Entity("API.Schema.MangaConnectors.Bato", b => + { + b.HasBaseType("API.Schema.MangaConnectors.MangaConnector"); + + b.HasDiscriminator().HasValue("Bato"); + }); + + modelBuilder.Entity("API.Schema.MangaConnectors.MangaDex", b => + { + b.HasBaseType("API.Schema.MangaConnectors.MangaConnector"); + + b.HasDiscriminator().HasValue("MangaDex"); + }); + + modelBuilder.Entity("API.Schema.MangaConnectors.MangaHere", b => + { + b.HasBaseType("API.Schema.MangaConnectors.MangaConnector"); + + b.HasDiscriminator().HasValue("MangaHere"); + }); + + modelBuilder.Entity("API.Schema.MangaConnectors.MangaKatana", b => + { + b.HasBaseType("API.Schema.MangaConnectors.MangaConnector"); + + b.HasDiscriminator().HasValue("MangaKatana"); + }); + + modelBuilder.Entity("API.Schema.MangaConnectors.Manganato", b => + { + b.HasBaseType("API.Schema.MangaConnectors.MangaConnector"); + + b.HasDiscriminator().HasValue("Manganato"); + }); + + modelBuilder.Entity("API.Schema.MangaConnectors.Mangaworld", b => + { + b.HasBaseType("API.Schema.MangaConnectors.MangaConnector"); + + b.HasDiscriminator().HasValue("Mangaworld"); + }); + + modelBuilder.Entity("API.Schema.MangaConnectors.ManhuaPlus", b => + { + b.HasBaseType("API.Schema.MangaConnectors.MangaConnector"); + + b.HasDiscriminator().HasValue("ManhuaPlus"); + }); + + modelBuilder.Entity("API.Schema.MangaConnectors.Weebcentral", b => + { + b.HasBaseType("API.Schema.MangaConnectors.MangaConnector"); + + b.HasDiscriminator().HasValue("Weebcentral"); + }); + + modelBuilder.Entity("API.Schema.Chapter", b => + { + b.HasOne("API.Schema.Manga", "ParentManga") + .WithMany() + .HasForeignKey("ParentMangaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ParentManga"); + }); + + modelBuilder.Entity("API.Schema.Jobs.Job", b => + { + b.HasOne("API.Schema.Jobs.Job", "ParentJob") + .WithMany() + .HasForeignKey("ParentJobId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("ParentJob"); + }); + + modelBuilder.Entity("API.Schema.Link", b => + { + b.HasOne("API.Schema.Manga", null) + .WithMany("Links") + .HasForeignKey("MangaId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("API.Schema.Manga", b => + { + b.HasOne("API.Schema.MangaConnectors.MangaConnector", "MangaConnector") + .WithMany() + .HasForeignKey("MangaConnectorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MangaConnector"); + }); + + modelBuilder.Entity("API.Schema.MangaAltTitle", b => + { + b.HasOne("API.Schema.Manga", null) + .WithMany("AltTitles") + .HasForeignKey("MangaId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("AuthorManga", b => + { + b.HasOne("API.Schema.Author", null) + .WithMany() + .HasForeignKey("AuthorsAuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("API.Schema.Manga", null) + .WithMany() + .HasForeignKey("MangaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("JobJob", b => + { + b.HasOne("API.Schema.Jobs.Job", null) + .WithMany() + .HasForeignKey("DependsOnJobsJobId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("API.Schema.Jobs.Job", null) + .WithMany() + .HasForeignKey("JobId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("MangaMangaTag", b => + { + b.HasOne("API.Schema.Manga", null) + .WithMany() + .HasForeignKey("MangaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("API.Schema.MangaTag", null) + .WithMany() + .HasForeignKey("MangaTagsTag") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("API.Schema.Jobs.DownloadAvailableChaptersJob", b => + { + b.HasOne("API.Schema.Manga", "Manga") + .WithMany() + .HasForeignKey("MangaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Manga"); + }); + + modelBuilder.Entity("API.Schema.Jobs.DownloadMangaCoverJob", b => + { + b.HasOne("API.Schema.Manga", "Manga") + .WithMany() + .HasForeignKey("MangaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Manga"); + }); + + modelBuilder.Entity("API.Schema.Jobs.DownloadSingleChapterJob", b => + { + b.HasOne("API.Schema.Chapter", "Chapter") + .WithMany() + .HasForeignKey("ChapterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chapter"); + }); + + modelBuilder.Entity("API.Schema.Jobs.RetrieveChaptersJob", b => + { + b.HasOne("API.Schema.Manga", "Manga") + .WithMany() + .HasForeignKey("MangaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Manga"); + }); + + modelBuilder.Entity("API.Schema.Jobs.UpdateFilesDownloadedJob", b => + { + b.HasOne("API.Schema.Manga", "Manga") + .WithMany() + .HasForeignKey("MangaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Manga"); + }); + + modelBuilder.Entity("API.Schema.Jobs.UpdateMetadataJob", b => + { + b.HasOne("API.Schema.Manga", "Manga") + .WithMany() + .HasForeignKey("MangaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Manga"); + }); + + modelBuilder.Entity("API.Schema.Manga", b => + { + b.Navigation("AltTitles"); + + b.Navigation("Links"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/API/Migrations/20250313233529_dev-130325-9.cs b/API/Migrations/20250313233529_dev-130325-9.cs new file mode 100644 index 0000000..dac86dc --- /dev/null +++ b/API/Migrations/20250313233529_dev-130325-9.cs @@ -0,0 +1,103 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace API.Migrations +{ + /// + public partial class dev1303259 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Jobs_Jobs_JobId1", + table: "Jobs"); + + migrationBuilder.DropForeignKey( + name: "FK_Jobs_Jobs_ParentJobId", + table: "Jobs"); + + migrationBuilder.DropIndex( + name: "IX_Jobs_JobId1", + table: "Jobs"); + + migrationBuilder.DropColumn( + name: "JobId1", + table: "Jobs"); + + migrationBuilder.CreateTable( + name: "JobJob", + columns: table => new + { + DependsOnJobsJobId = table.Column(type: "character varying(64)", nullable: false), + JobId = table.Column(type: "character varying(64)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_JobJob", x => new { x.DependsOnJobsJobId, x.JobId }); + table.ForeignKey( + name: "FK_JobJob_Jobs_DependsOnJobsJobId", + column: x => x.DependsOnJobsJobId, + principalTable: "Jobs", + principalColumn: "JobId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_JobJob_Jobs_JobId", + column: x => x.JobId, + principalTable: "Jobs", + principalColumn: "JobId", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_JobJob_JobId", + table: "JobJob", + column: "JobId"); + + migrationBuilder.AddForeignKey( + name: "FK_Jobs_Jobs_ParentJobId", + table: "Jobs", + column: "ParentJobId", + principalTable: "Jobs", + principalColumn: "JobId", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Jobs_Jobs_ParentJobId", + table: "Jobs"); + + migrationBuilder.DropTable( + name: "JobJob"); + + migrationBuilder.AddColumn( + name: "JobId1", + table: "Jobs", + type: "character varying(64)", + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_Jobs_JobId1", + table: "Jobs", + column: "JobId1"); + + migrationBuilder.AddForeignKey( + name: "FK_Jobs_Jobs_JobId1", + table: "Jobs", + column: "JobId1", + principalTable: "Jobs", + principalColumn: "JobId"); + + migrationBuilder.AddForeignKey( + name: "FK_Jobs_Jobs_ParentJobId", + table: "Jobs", + column: "ParentJobId", + principalTable: "Jobs", + principalColumn: "JobId"); + } + } +} diff --git a/API/Migrations/PgsqlContextModelSnapshot.cs b/API/Migrations/PgsqlContextModelSnapshot.cs index b8f7987..e49d53e 100644 --- a/API/Migrations/PgsqlContextModelSnapshot.cs +++ b/API/Migrations/PgsqlContextModelSnapshot.cs @@ -96,9 +96,6 @@ namespace API.Migrations b.Property("Enabled") .HasColumnType("boolean"); - b.Property("JobId1") - .HasColumnType("character varying(64)"); - b.Property("JobType") .HasColumnType("smallint"); @@ -117,8 +114,6 @@ namespace API.Migrations b.HasKey("JobId"); - b.HasIndex("JobId1"); - b.HasIndex("ParentJobId"); b.ToTable("Jobs"); @@ -386,6 +381,21 @@ namespace API.Migrations b.ToTable("AuthorManga"); }); + modelBuilder.Entity("JobJob", b => + { + b.Property("DependsOnJobsJobId") + .HasColumnType("character varying(64)"); + + b.Property("JobId") + .HasColumnType("character varying(64)"); + + b.HasKey("DependsOnJobsJobId", "JobId"); + + b.HasIndex("JobId"); + + b.ToTable("JobJob"); + }); + modelBuilder.Entity("MangaMangaTag", b => { b.Property("MangaId") @@ -616,13 +626,10 @@ namespace API.Migrations modelBuilder.Entity("API.Schema.Jobs.Job", b => { - b.HasOne("API.Schema.Jobs.Job", null) - .WithMany("DependsOnJobs") - .HasForeignKey("JobId1"); - b.HasOne("API.Schema.Jobs.Job", "ParentJob") .WithMany() - .HasForeignKey("ParentJobId"); + .HasForeignKey("ParentJobId") + .OnDelete(DeleteBehavior.Cascade); b.Navigation("ParentJob"); }); @@ -669,6 +676,21 @@ namespace API.Migrations .IsRequired(); }); + modelBuilder.Entity("JobJob", b => + { + b.HasOne("API.Schema.Jobs.Job", null) + .WithMany() + .HasForeignKey("DependsOnJobsJobId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("API.Schema.Jobs.Job", null) + .WithMany() + .HasForeignKey("JobId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + modelBuilder.Entity("MangaMangaTag", b => { b.HasOne("API.Schema.Manga", null) @@ -750,11 +772,6 @@ namespace API.Migrations b.Navigation("Manga"); }); - modelBuilder.Entity("API.Schema.Jobs.Job", b => - { - b.Navigation("DependsOnJobs"); - }); - modelBuilder.Entity("API.Schema.Manga", b => { b.Navigation("AltTitles"); diff --git a/API/Schema/Link.cs b/API/Schema/Link.cs index 054e1b8..e20ac8b 100644 --- a/API/Schema/Link.cs +++ b/API/Schema/Link.cs @@ -16,11 +16,4 @@ public class Link(string linkProvider, string linkUrl) [Required] [Url] public string LinkUrl { get; init; } = linkUrl; - - public override bool Equals(object? obj) - { - if (obj is not Link other) - return false; - return other.LinkProvider == LinkProvider && other.LinkUrl == LinkUrl; - } } \ No newline at end of file diff --git a/API/Schema/PgsqlContext.cs b/API/Schema/PgsqlContext.cs index fa3e842..e829766 100644 --- a/API/Schema/PgsqlContext.cs +++ b/API/Schema/PgsqlContext.cs @@ -50,9 +50,11 @@ public class PgsqlContext(DbContextOptions options) : DbContext(op modelBuilder.Entity() .HasOne(j => j.ParentJob) .WithMany() - .HasForeignKey(j => j.ParentJobId); + .HasForeignKey(j => j.ParentJobId) + .OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity() - .HasMany(j => j.DependsOnJobs); + .HasMany(j => j.DependsOnJobs) + .WithMany(); modelBuilder.Entity() .Navigation(dncj => dncj.Manga) .AutoInclude(); diff --git a/API/TrangaSettings.cs b/API/TrangaSettings.cs index 2ae024f..f0c4e42 100644 --- a/API/TrangaSettings.cs +++ b/API/TrangaSettings.cs @@ -21,7 +21,7 @@ public static class TrangaSettings [JsonIgnore] public static string coverImageCache => Path.Join(workingDirectory, "imageCache"); public static bool aprilFoolsMode { get; private set; } = true; - public static int startNewJobTimeoutMs { get; private set; } = 10000; + public static int startNewJobTimeoutMs { get; private set; } = 1000; [JsonIgnore] internal static readonly Dictionary DefaultRequestLimits = new () { diff --git a/API/appsettings.Development.json b/API/appsettings.Development.json index 0c208ae..6e49124 100644 --- a/API/appsettings.Development.json +++ b/API/appsettings.Development.json @@ -1,7 +1,7 @@ { "Logging": { "LogLevel": { - "Default": "Information", + "Default": "Error", "Microsoft.AspNetCore": "Warning" } } diff --git a/API/appsettings.json b/API/appsettings.json index 10f68b8..b494488 100644 --- a/API/appsettings.json +++ b/API/appsettings.json @@ -1,7 +1,7 @@ { "Logging": { "LogLevel": { - "Default": "Information", + "Default": "Error", "Microsoft.AspNetCore": "Warning" } },