From e54b86b16a8fc42b150a4efbfc13c50ec8374fc8 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Thu, 23 Apr 2020 22:35:50 +0200 Subject: [PATCH] Finishing the rework of providers in the db --- Kyoo.Common/Kyoo.Common.csproj | 2 +- Kyoo.Common/Models/Library.cs | 7 +- Kyoo.Common/Models/ProviderLink.cs | 17 +++ Kyoo.Common/Models/Show.cs | 2 +- Kyoo/Controllers/ProviderManager.cs | 16 +-- Kyoo/Models/DatabaseContext.cs | 2 +- ....cs => 20200423203356_Initial.Designer.cs} | 110 +++++++++++++++-- ...5_Initial.cs => 20200423203356_Initial.cs} | 115 +++++++++++++++++- .../Internal/DatabaseContextModelSnapshot.cs | 108 +++++++++++++++- 9 files changed, 348 insertions(+), 31 deletions(-) create mode 100644 Kyoo.Common/Models/ProviderLink.cs rename Kyoo/Models/DatabaseMigrations/Internal/{20200414223325_Initial.Designer.cs => 20200423203356_Initial.Designer.cs} (83%) rename Kyoo/Models/DatabaseMigrations/Internal/{20200414223325_Initial.cs => 20200423203356_Initial.cs} (80%) diff --git a/Kyoo.Common/Kyoo.Common.csproj b/Kyoo.Common/Kyoo.Common.csproj index c0ffcb47..904c40f5 100644 --- a/Kyoo.Common/Kyoo.Common.csproj +++ b/Kyoo.Common/Kyoo.Common.csproj @@ -11,7 +11,7 @@ SDG GPL-3.0-or-later true - 1.0.17 + 1.0.18 diff --git a/Kyoo.Common/Models/Library.cs b/Kyoo.Common/Models/Library.cs index d9d5c7ca..883a2f37 100644 --- a/Kyoo.Common/Models/Library.cs +++ b/Kyoo.Common/Models/Library.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using System.Collections.Generic; +using Newtonsoft.Json; namespace Kyoo.Models { @@ -8,11 +9,11 @@ namespace Kyoo.Models public string Slug { get; set; } public string Name { get; set; } public string[] Paths { get; set; } - public ProviderID[] Providers { get; set; } + public virtual IEnumerable Providers { get; set; } public Library() { } - public Library(string slug, string name, string[] paths, ProviderID[] providers) + public Library(string slug, string name, string[] paths, IEnumerable providers) { Slug = slug; Name = name; diff --git a/Kyoo.Common/Models/ProviderLink.cs b/Kyoo.Common/Models/ProviderLink.cs new file mode 100644 index 00000000..ce98b00c --- /dev/null +++ b/Kyoo.Common/Models/ProviderLink.cs @@ -0,0 +1,17 @@ +namespace Kyoo.Models +{ + public class ProviderLink + { + public long ID { get; set; } + public long ProviderID { get; set; } + public virtual ProviderID Provider { get; set; } + public long? ShowID { get; set; } + public virtual Show Show { get; set; } + public long? LibraryID { get; set; } + public virtual Library Library { get; set; } + + public string Name => Provider.Name; + + public ProviderLink() { } + } +} \ No newline at end of file diff --git a/Kyoo.Common/Models/Show.cs b/Kyoo.Common/Models/Show.cs index a4fa2804..00cb0ce8 100644 --- a/Kyoo.Common/Models/Show.cs +++ b/Kyoo.Common/Models/Show.cs @@ -24,7 +24,7 @@ namespace Kyoo.Models [JsonIgnore] public string ImgLogo { get; set; } [JsonIgnore] public string ImgBackdrop { get; set; } - public IEnumerable ExternalIDs { get; set; } + public virtual IEnumerable ExternalIDs { get; set; } public bool IsMovie { get; set; } diff --git a/Kyoo/Controllers/ProviderManager.cs b/Kyoo/Controllers/ProviderManager.cs index 6e4d536d..2751c793 100644 --- a/Kyoo/Controllers/ProviderManager.cs +++ b/Kyoo/Controllers/ProviderManager.cs @@ -20,10 +20,10 @@ namespace Kyoo.Controllers { T ret = new T(); - IEnumerable providers = library?.Providers != null - ? _providers.Where(x => library.Providers.Contains(x.Provider)) - .OrderBy(provider => Array.IndexOf(library.Providers, provider.Provider)) - : _providers; + IEnumerable providers = library?.Providers + .Select(x => _providers.FirstOrDefault(y => y.Provider.Name == x.Name)) + .Where(x => x != null) + ?? _providers; foreach (IMetadataProvider provider in providers) { @@ -41,10 +41,10 @@ namespace Kyoo.Controllers { List ret = new List(); - IEnumerable providers = library?.Providers != null - ? _providers.Where(x => library.Providers.Contains(x.Provider)) - .OrderBy(provider => Array.IndexOf(library.Providers, provider.Provider)) - : _providers; + IEnumerable providers = library?.Providers + .Select(x => _providers.FirstOrDefault(y => y.Provider.Name == x.Name)) + .Where(x => x != null) + ?? _providers; foreach (IMetadataProvider provider in providers) { diff --git a/Kyoo/Models/DatabaseContext.cs b/Kyoo/Models/DatabaseContext.cs index ac6ed62d..391fba31 100644 --- a/Kyoo/Models/DatabaseContext.cs +++ b/Kyoo/Models/DatabaseContext.cs @@ -85,6 +85,7 @@ namespace Kyoo // This is used because EF doesn't support Many-To-Many relationships so for now we need to override the getter/setters to store this. public DbSet GenreLinks { get; set; } + public DbSet ProviderLinks { get; set; } private ValueConverter stringArrayConverter = new ValueConverter( @@ -101,7 +102,6 @@ namespace Kyoo base.OnModelCreating(modelBuilder); modelBuilder.Entity().Property(e => e.Paths).HasConversion(stringArrayConverter).Metadata.SetValueComparer(stringArrayComparer); - modelBuilder.Entity().Property(e => e.Providers).HasConversion(stringArrayConverter).Metadata.SetValueComparer(stringArrayComparer); modelBuilder.Entity().Property(e => e.Aliases).HasConversion(stringArrayConverter).Metadata.SetValueComparer(stringArrayComparer); modelBuilder.Entity() diff --git a/Kyoo/Models/DatabaseMigrations/Internal/20200414223325_Initial.Designer.cs b/Kyoo/Models/DatabaseMigrations/Internal/20200423203356_Initial.Designer.cs similarity index 83% rename from Kyoo/Models/DatabaseMigrations/Internal/20200414223325_Initial.Designer.cs rename to Kyoo/Models/DatabaseMigrations/Internal/20200423203356_Initial.Designer.cs index b99b1e99..bdb1e824 100644 --- a/Kyoo/Models/DatabaseMigrations/Internal/20200414223325_Initial.Designer.cs +++ b/Kyoo/Models/DatabaseMigrations/Internal/20200423203356_Initial.Designer.cs @@ -9,7 +9,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace Kyoo.Models.DatabaseMigrations.Internal { [DbContext(typeof(DatabaseContext))] - [Migration("20200414223325_Initial")] + [Migration("20200423203356_Initial")] partial class Initial { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -166,9 +166,6 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.Property("Paths") .HasColumnType("TEXT"); - b.Property("Providers") - .HasColumnType("TEXT"); - b.Property("Slug") .HasColumnType("TEXT"); @@ -206,6 +203,33 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.ToTable("LibraryLinks"); }); + modelBuilder.Entity("Kyoo.Models.MetadataID", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DataID") + .HasColumnType("TEXT"); + + b.Property("Link") + .HasColumnType("TEXT"); + + b.Property("ProviderID") + .HasColumnType("INTEGER"); + + b.Property("ShowID") + .HasColumnType("INTEGER"); + + b.HasKey("ID"); + + b.HasIndex("ProviderID"); + + b.HasIndex("ShowID"); + + b.ToTable("MetadataIds"); + }); + modelBuilder.Entity("Kyoo.Models.People", b => { b.Property("Slug") @@ -255,6 +279,49 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.ToTable("PeopleLinks"); }); + modelBuilder.Entity("Kyoo.Models.ProviderID", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Logo") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.ToTable("ProviderIds"); + }); + + modelBuilder.Entity("Kyoo.Models.ProviderLink", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("LibraryID") + .HasColumnType("INTEGER"); + + b.Property("ProviderID") + .HasColumnType("INTEGER"); + + b.Property("ShowID") + .HasColumnType("INTEGER"); + + b.HasKey("ID"); + + b.HasIndex("LibraryID"); + + b.HasIndex("ProviderID"); + + b.HasIndex("ShowID"); + + b.ToTable("ProviderLinks"); + }); + modelBuilder.Entity("Kyoo.Models.Season", b => { b.Property("ID") @@ -301,9 +368,6 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.Property("EndYear") .HasColumnType("INTEGER"); - b.Property("ExternalIDs") - .HasColumnType("TEXT"); - b.Property("ImgBackdrop") .HasColumnType("TEXT"); @@ -471,6 +535,21 @@ namespace Kyoo.Models.DatabaseMigrations.Internal .HasForeignKey("ShowID"); }); + modelBuilder.Entity("Kyoo.Models.MetadataID", b => + { + b.HasOne("Kyoo.Models.ProviderID", "Provider") + .WithMany() + .HasForeignKey("ProviderID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Show", "Show") + .WithMany("ExternalIDs") + .HasForeignKey("ShowID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + modelBuilder.Entity("Kyoo.Models.PeopleLink", b => { b.HasOne("Kyoo.Models.People", "People") @@ -484,6 +563,23 @@ namespace Kyoo.Models.DatabaseMigrations.Internal .IsRequired(); }); + modelBuilder.Entity("Kyoo.Models.ProviderLink", b => + { + b.HasOne("Kyoo.Models.Library", "Library") + .WithMany("Providers") + .HasForeignKey("LibraryID"); + + b.HasOne("Kyoo.Models.ProviderID", "Provider") + .WithMany() + .HasForeignKey("ProviderID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Show", "Show") + .WithMany() + .HasForeignKey("ShowID"); + }); + modelBuilder.Entity("Kyoo.Models.Season", b => { b.HasOne("Kyoo.Models.Show", "Show") diff --git a/Kyoo/Models/DatabaseMigrations/Internal/20200414223325_Initial.cs b/Kyoo/Models/DatabaseMigrations/Internal/20200423203356_Initial.cs similarity index 80% rename from Kyoo/Models/DatabaseMigrations/Internal/20200414223325_Initial.cs rename to Kyoo/Models/DatabaseMigrations/Internal/20200423203356_Initial.cs index 7cb6e284..491bb24d 100644 --- a/Kyoo/Models/DatabaseMigrations/Internal/20200414223325_Initial.cs +++ b/Kyoo/Models/DatabaseMigrations/Internal/20200423203356_Initial.cs @@ -46,8 +46,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal .Annotation("Sqlite:Autoincrement", true), Slug = table.Column(nullable: true), Name = table.Column(nullable: true), - Paths = table.Column(nullable: true), - Providers = table.Column(nullable: true) + Paths = table.Column(nullable: true) }, constraints: table => { @@ -68,6 +67,20 @@ namespace Kyoo.Models.DatabaseMigrations.Internal table.PrimaryKey("PK_Peoples", x => x.Slug); }); + migrationBuilder.CreateTable( + name: "ProviderIds", + columns: table => new + { + ID = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Name = table.Column(nullable: true), + Logo = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ProviderIds", x => x.ID); + }); + migrationBuilder.CreateTable( name: "Studios", columns: table => new @@ -101,7 +114,6 @@ namespace Kyoo.Models.DatabaseMigrations.Internal ImgThumb = table.Column(nullable: true), ImgLogo = table.Column(nullable: true), ImgBackdrop = table.Column(nullable: true), - ExternalIDs = table.Column(nullable: true), IsMovie = table.Column(nullable: false), StudioID = table.Column(nullable: true) }, @@ -199,6 +211,34 @@ namespace Kyoo.Models.DatabaseMigrations.Internal onDelete: ReferentialAction.Restrict); }); + migrationBuilder.CreateTable( + name: "MetadataIds", + columns: table => new + { + ID = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + ShowID = table.Column(nullable: false), + ProviderID = table.Column(nullable: false), + DataID = table.Column(nullable: true), + Link = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_MetadataIds", x => x.ID); + table.ForeignKey( + name: "FK_MetadataIds_ProviderIds_ProviderID", + column: x => x.ProviderID, + principalTable: "ProviderIds", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_MetadataIds_Shows_ShowID", + column: x => x.ShowID, + principalTable: "Shows", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + migrationBuilder.CreateTable( name: "PeopleLinks", columns: table => new @@ -227,6 +267,39 @@ namespace Kyoo.Models.DatabaseMigrations.Internal onDelete: ReferentialAction.Cascade); }); + migrationBuilder.CreateTable( + name: "ProviderLinks", + columns: table => new + { + ID = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + ProviderID = table.Column(nullable: false), + ShowID = table.Column(nullable: true), + LibraryID = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ProviderLinks", x => x.ID); + table.ForeignKey( + name: "FK_ProviderLinks_Libraries_LibraryID", + column: x => x.LibraryID, + principalTable: "Libraries", + principalColumn: "ID", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_ProviderLinks_ProviderIds_ProviderID", + column: x => x.ProviderID, + principalTable: "ProviderIds", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ProviderLinks_Shows_ShowID", + column: x => x.ShowID, + principalTable: "Shows", + principalColumn: "ID", + onDelete: ReferentialAction.Restrict); + }); + migrationBuilder.CreateTable( name: "Seasons", columns: table => new @@ -373,6 +446,16 @@ namespace Kyoo.Models.DatabaseMigrations.Internal table: "LibraryLinks", column: "ShowID"); + migrationBuilder.CreateIndex( + name: "IX_MetadataIds_ProviderID", + table: "MetadataIds", + column: "ProviderID"); + + migrationBuilder.CreateIndex( + name: "IX_MetadataIds_ShowID", + table: "MetadataIds", + column: "ShowID"); + migrationBuilder.CreateIndex( name: "IX_PeopleLinks_PeopleID", table: "PeopleLinks", @@ -389,6 +472,21 @@ namespace Kyoo.Models.DatabaseMigrations.Internal column: "Slug", unique: true); + migrationBuilder.CreateIndex( + name: "IX_ProviderLinks_LibraryID", + table: "ProviderLinks", + column: "LibraryID"); + + migrationBuilder.CreateIndex( + name: "IX_ProviderLinks_ProviderID", + table: "ProviderLinks", + column: "ProviderID"); + + migrationBuilder.CreateIndex( + name: "IX_ProviderLinks_ShowID", + table: "ProviderLinks", + column: "ShowID"); + migrationBuilder.CreateIndex( name: "IX_Seasons_ShowID", table: "Seasons", @@ -428,9 +526,15 @@ namespace Kyoo.Models.DatabaseMigrations.Internal migrationBuilder.DropTable( name: "LibraryLinks"); + migrationBuilder.DropTable( + name: "MetadataIds"); + migrationBuilder.DropTable( name: "PeopleLinks"); + migrationBuilder.DropTable( + name: "ProviderLinks"); + migrationBuilder.DropTable( name: "Tracks"); @@ -440,11 +544,14 @@ namespace Kyoo.Models.DatabaseMigrations.Internal migrationBuilder.DropTable( name: "Collections"); + migrationBuilder.DropTable( + name: "Peoples"); + migrationBuilder.DropTable( name: "Libraries"); migrationBuilder.DropTable( - name: "Peoples"); + name: "ProviderIds"); migrationBuilder.DropTable( name: "Episodes"); diff --git a/Kyoo/Models/DatabaseMigrations/Internal/DatabaseContextModelSnapshot.cs b/Kyoo/Models/DatabaseMigrations/Internal/DatabaseContextModelSnapshot.cs index 24fbf303..a40fda67 100644 --- a/Kyoo/Models/DatabaseMigrations/Internal/DatabaseContextModelSnapshot.cs +++ b/Kyoo/Models/DatabaseMigrations/Internal/DatabaseContextModelSnapshot.cs @@ -164,9 +164,6 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.Property("Paths") .HasColumnType("TEXT"); - b.Property("Providers") - .HasColumnType("TEXT"); - b.Property("Slug") .HasColumnType("TEXT"); @@ -204,6 +201,33 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.ToTable("LibraryLinks"); }); + modelBuilder.Entity("Kyoo.Models.MetadataID", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DataID") + .HasColumnType("TEXT"); + + b.Property("Link") + .HasColumnType("TEXT"); + + b.Property("ProviderID") + .HasColumnType("INTEGER"); + + b.Property("ShowID") + .HasColumnType("INTEGER"); + + b.HasKey("ID"); + + b.HasIndex("ProviderID"); + + b.HasIndex("ShowID"); + + b.ToTable("MetadataIds"); + }); + modelBuilder.Entity("Kyoo.Models.People", b => { b.Property("Slug") @@ -253,6 +277,49 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.ToTable("PeopleLinks"); }); + modelBuilder.Entity("Kyoo.Models.ProviderID", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Logo") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.ToTable("ProviderIds"); + }); + + modelBuilder.Entity("Kyoo.Models.ProviderLink", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("LibraryID") + .HasColumnType("INTEGER"); + + b.Property("ProviderID") + .HasColumnType("INTEGER"); + + b.Property("ShowID") + .HasColumnType("INTEGER"); + + b.HasKey("ID"); + + b.HasIndex("LibraryID"); + + b.HasIndex("ProviderID"); + + b.HasIndex("ShowID"); + + b.ToTable("ProviderLinks"); + }); + modelBuilder.Entity("Kyoo.Models.Season", b => { b.Property("ID") @@ -299,9 +366,6 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.Property("EndYear") .HasColumnType("INTEGER"); - b.Property("ExternalIDs") - .HasColumnType("TEXT"); - b.Property("ImgBackdrop") .HasColumnType("TEXT"); @@ -469,6 +533,21 @@ namespace Kyoo.Models.DatabaseMigrations.Internal .HasForeignKey("ShowID"); }); + modelBuilder.Entity("Kyoo.Models.MetadataID", b => + { + b.HasOne("Kyoo.Models.ProviderID", "Provider") + .WithMany() + .HasForeignKey("ProviderID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Show", "Show") + .WithMany("ExternalIDs") + .HasForeignKey("ShowID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + modelBuilder.Entity("Kyoo.Models.PeopleLink", b => { b.HasOne("Kyoo.Models.People", "People") @@ -482,6 +561,23 @@ namespace Kyoo.Models.DatabaseMigrations.Internal .IsRequired(); }); + modelBuilder.Entity("Kyoo.Models.ProviderLink", b => + { + b.HasOne("Kyoo.Models.Library", "Library") + .WithMany("Providers") + .HasForeignKey("LibraryID"); + + b.HasOne("Kyoo.Models.ProviderID", "Provider") + .WithMany() + .HasForeignKey("ProviderID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Show", "Show") + .WithMany() + .HasForeignKey("ShowID"); + }); + modelBuilder.Entity("Kyoo.Models.Season", b => { b.HasOne("Kyoo.Models.Show", "Show")