From 19e64e8d72c4017e20d1698ace3541a7c7326d63 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sat, 29 May 2021 14:45:34 +0200 Subject: [PATCH] Adding an sqlite plugin --- Kyoo.Postgresql/Kyoo.Postgresql.csproj | 1 - Kyoo.SqLite/Kyoo.SqLite.csproj | 41 + .../20210529124408_Initial.Designer.cs | 878 ++++++++++++++++++ .../Migrations/20210529124408_Initial.cs | 693 ++++++++++++++ .../Migrations/SqLiteContextModelSnapshot.cs | 876 +++++++++++++++++ Kyoo.SqLite/SqLiteContext.cs | 134 +++ Kyoo.SqLite/SqLiteModule.cs | 72 ++ Kyoo.sln | 6 + 8 files changed, 2700 insertions(+), 1 deletion(-) create mode 100644 Kyoo.SqLite/Kyoo.SqLite.csproj create mode 100644 Kyoo.SqLite/Migrations/20210529124408_Initial.Designer.cs create mode 100644 Kyoo.SqLite/Migrations/20210529124408_Initial.cs create mode 100644 Kyoo.SqLite/Migrations/SqLiteContextModelSnapshot.cs create mode 100644 Kyoo.SqLite/SqLiteContext.cs create mode 100644 Kyoo.SqLite/SqLiteModule.cs diff --git a/Kyoo.Postgresql/Kyoo.Postgresql.csproj b/Kyoo.Postgresql/Kyoo.Postgresql.csproj index 52c9041b..9dcbba0b 100644 --- a/Kyoo.Postgresql/Kyoo.Postgresql.csproj +++ b/Kyoo.Postgresql/Kyoo.Postgresql.csproj @@ -1,5 +1,4 @@ - net5.0 diff --git a/Kyoo.SqLite/Kyoo.SqLite.csproj b/Kyoo.SqLite/Kyoo.SqLite.csproj new file mode 100644 index 00000000..c48664bc --- /dev/null +++ b/Kyoo.SqLite/Kyoo.SqLite.csproj @@ -0,0 +1,41 @@ + + + net5.0 + + SDG + Zoe Roux + https://github.com/AnonymusRaccoon/Kyoo + default + Kyoo.SQLite + + + + ../Kyoo/bin/$(Configuration)/$(TargetFramework)/plugins/sqlite + false + false + false + false + true + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + all + false + runtime + + + all + false + runtime + + + diff --git a/Kyoo.SqLite/Migrations/20210529124408_Initial.Designer.cs b/Kyoo.SqLite/Migrations/20210529124408_Initial.Designer.cs new file mode 100644 index 00000000..ffdeefad --- /dev/null +++ b/Kyoo.SqLite/Migrations/20210529124408_Initial.Designer.cs @@ -0,0 +1,878 @@ +// +using System; +using Kyoo.SqLite; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Kyoo.SQLite.Migrations +{ + [DbContext(typeof(SqLiteContext))] + [Migration("20210529124408_Initial")] + partial class Initial + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.6"); + + modelBuilder.Entity("Kyoo.Models.Collection", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("Poster") + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Collections"); + }); + + modelBuilder.Entity("Kyoo.Models.Episode", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AbsoluteNumber") + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("Runtime") + .HasColumnType("INTEGER"); + + b.Property("SeasonID") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("ShowID") + .HasColumnType("INTEGER"); + + b.Property("Thumb") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("SeasonID"); + + b.HasIndex("ShowID", "SeasonNumber", "EpisodeNumber", "AbsoluteNumber") + .IsUnique(); + + b.ToTable("Episodes"); + }); + + modelBuilder.Entity("Kyoo.Models.Genre", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Genres"); + }); + + modelBuilder.Entity("Kyoo.Models.Library", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Paths") + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Libraries"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.Property("FirstID") + .HasColumnType("INTEGER"); + + b.Property("SecondID") + .HasColumnType("INTEGER"); + + b.HasKey("FirstID", "SecondID"); + + b.HasIndex("SecondID"); + + b.ToTable("Link"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.Property("FirstID") + .HasColumnType("INTEGER"); + + b.Property("SecondID") + .HasColumnType("INTEGER"); + + b.HasKey("FirstID", "SecondID"); + + b.HasIndex("SecondID"); + + b.ToTable("Link"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.Property("FirstID") + .HasColumnType("INTEGER"); + + b.Property("SecondID") + .HasColumnType("INTEGER"); + + b.HasKey("FirstID", "SecondID"); + + b.HasIndex("SecondID"); + + b.ToTable("Link"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.Property("FirstID") + .HasColumnType("INTEGER"); + + b.Property("SecondID") + .HasColumnType("INTEGER"); + + b.HasKey("FirstID", "SecondID"); + + b.HasIndex("SecondID"); + + b.ToTable("Link"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.Property("FirstID") + .HasColumnType("INTEGER"); + + b.Property("SecondID") + .HasColumnType("INTEGER"); + + b.HasKey("FirstID", "SecondID"); + + b.HasIndex("SecondID"); + + b.ToTable("Link"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.Property("FirstID") + .HasColumnType("INTEGER"); + + b.Property("SecondID") + .HasColumnType("INTEGER"); + + b.HasKey("FirstID", "SecondID"); + + b.HasIndex("SecondID"); + + b.ToTable("Link"); + }); + + modelBuilder.Entity("Kyoo.Models.MetadataID", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DataID") + .HasColumnType("TEXT"); + + b.Property("EpisodeID") + .HasColumnType("INTEGER"); + + b.Property("Link") + .HasColumnType("TEXT"); + + b.Property("PeopleID") + .HasColumnType("INTEGER"); + + b.Property("ProviderID") + .HasColumnType("INTEGER"); + + b.Property("SeasonID") + .HasColumnType("INTEGER"); + + b.Property("ShowID") + .HasColumnType("INTEGER"); + + b.HasKey("ID"); + + b.HasIndex("EpisodeID"); + + b.HasIndex("PeopleID"); + + b.HasIndex("ProviderID"); + + b.HasIndex("SeasonID"); + + b.HasIndex("ShowID"); + + b.ToTable("MetadataIds"); + }); + + modelBuilder.Entity("Kyoo.Models.People", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Poster") + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("People"); + }); + + modelBuilder.Entity("Kyoo.Models.PeopleRole", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("PeopleID") + .HasColumnType("INTEGER"); + + b.Property("Role") + .HasColumnType("TEXT"); + + b.Property("ShowID") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("PeopleID"); + + b.HasIndex("ShowID"); + + b.ToTable("PeopleRoles"); + }); + + modelBuilder.Entity("Kyoo.Models.Provider", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Logo") + .HasColumnType("TEXT"); + + b.Property("LogoExtension") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Providers"); + }); + + modelBuilder.Entity("Kyoo.Models.Season", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("Poster") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("ShowID") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("ID"); + + b.HasIndex("ShowID", "SeasonNumber") + .IsUnique(); + + b.ToTable("Seasons"); + }); + + modelBuilder.Entity("Kyoo.Models.Show", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Aliases") + .HasColumnType("TEXT"); + + b.Property("Backdrop") + .HasColumnType("TEXT"); + + b.Property("EndYear") + .HasColumnType("INTEGER"); + + b.Property("IsMovie") + .HasColumnType("INTEGER"); + + b.Property("Logo") + .HasColumnType("TEXT"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.Property("Poster") + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StartYear") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("StudioID") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TrailerUrl") + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("Slug") + .IsUnique(); + + b.HasIndex("StudioID"); + + b.ToTable("Shows"); + }); + + modelBuilder.Entity("Kyoo.Models.Studio", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Studios"); + }); + + modelBuilder.Entity("Kyoo.Models.Track", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Codec") + .HasColumnType("TEXT"); + + b.Property("EpisodeID") + .HasColumnType("INTEGER"); + + b.Property("IsDefault") + .HasColumnType("INTEGER"); + + b.Property("IsExternal") + .HasColumnType("INTEGER"); + + b.Property("IsForced") + .HasColumnType("INTEGER"); + + b.Property("Language") + .HasColumnType("TEXT"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TrackIndex") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("ID"); + + b.HasIndex("EpisodeID", "Type", "Language", "TrackIndex", "IsForced") + .IsUnique(); + + b.ToTable("Tracks"); + }); + + modelBuilder.Entity("Kyoo.Models.User", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Email") + .HasColumnType("TEXT"); + + b.Property("ExtraData") + .HasColumnType("TEXT"); + + b.Property("Password") + .HasColumnType("TEXT"); + + b.Property("Permissions") + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Username") + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Kyoo.Models.WatchedEpisode", b => + { + b.Property("FirstID") + .HasColumnType("INTEGER"); + + b.Property("SecondID") + .HasColumnType("INTEGER"); + + b.Property("WatchedPercentage") + .HasColumnType("INTEGER"); + + b.HasKey("FirstID", "SecondID"); + + b.HasIndex("SecondID"); + + b.ToTable("WatchedEpisodes"); + }); + + modelBuilder.Entity("Kyoo.Models.Episode", b => + { + b.HasOne("Kyoo.Models.Season", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonID"); + + b.HasOne("Kyoo.Models.Show", "Show") + .WithMany("Episodes") + .HasForeignKey("ShowID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + + b.Navigation("Show"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.HasOne("Kyoo.Models.Collection", "First") + .WithMany("ShowLinks") + .HasForeignKey("FirstID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Show", "Second") + .WithMany("CollectionLinks") + .HasForeignKey("SecondID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("First"); + + b.Navigation("Second"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.HasOne("Kyoo.Models.Library", "First") + .WithMany("CollectionLinks") + .HasForeignKey("FirstID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Collection", "Second") + .WithMany("LibraryLinks") + .HasForeignKey("SecondID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("First"); + + b.Navigation("Second"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.HasOne("Kyoo.Models.Library", "First") + .WithMany("ProviderLinks") + .HasForeignKey("FirstID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Provider", "Second") + .WithMany("LibraryLinks") + .HasForeignKey("SecondID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("First"); + + b.Navigation("Second"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.HasOne("Kyoo.Models.Library", "First") + .WithMany("ShowLinks") + .HasForeignKey("FirstID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Show", "Second") + .WithMany("LibraryLinks") + .HasForeignKey("SecondID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("First"); + + b.Navigation("Second"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.HasOne("Kyoo.Models.Show", "First") + .WithMany("GenreLinks") + .HasForeignKey("FirstID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Genre", "Second") + .WithMany("ShowLinks") + .HasForeignKey("SecondID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("First"); + + b.Navigation("Second"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.HasOne("Kyoo.Models.User", "First") + .WithMany("ShowLinks") + .HasForeignKey("FirstID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Show", "Second") + .WithMany() + .HasForeignKey("SecondID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("First"); + + b.Navigation("Second"); + }); + + modelBuilder.Entity("Kyoo.Models.MetadataID", b => + { + b.HasOne("Kyoo.Models.Episode", "Episode") + .WithMany("ExternalIDs") + .HasForeignKey("EpisodeID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Kyoo.Models.People", "People") + .WithMany("ExternalIDs") + .HasForeignKey("PeopleID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Kyoo.Models.Provider", "Provider") + .WithMany("MetadataLinks") + .HasForeignKey("ProviderID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Season", "Season") + .WithMany("ExternalIDs") + .HasForeignKey("SeasonID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Kyoo.Models.Show", "Show") + .WithMany("ExternalIDs") + .HasForeignKey("ShowID") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Episode"); + + b.Navigation("People"); + + b.Navigation("Provider"); + + b.Navigation("Season"); + + b.Navigation("Show"); + }); + + modelBuilder.Entity("Kyoo.Models.PeopleRole", b => + { + b.HasOne("Kyoo.Models.People", "People") + .WithMany("Roles") + .HasForeignKey("PeopleID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Show", "Show") + .WithMany("People") + .HasForeignKey("ShowID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("People"); + + b.Navigation("Show"); + }); + + modelBuilder.Entity("Kyoo.Models.Season", b => + { + b.HasOne("Kyoo.Models.Show", "Show") + .WithMany("Seasons") + .HasForeignKey("ShowID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Show"); + }); + + modelBuilder.Entity("Kyoo.Models.Show", b => + { + b.HasOne("Kyoo.Models.Studio", "Studio") + .WithMany("Shows") + .HasForeignKey("StudioID"); + + b.Navigation("Studio"); + }); + + modelBuilder.Entity("Kyoo.Models.Track", b => + { + b.HasOne("Kyoo.Models.Episode", "Episode") + .WithMany("Tracks") + .HasForeignKey("EpisodeID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Episode"); + }); + + modelBuilder.Entity("Kyoo.Models.WatchedEpisode", b => + { + b.HasOne("Kyoo.Models.User", "First") + .WithMany("CurrentlyWatching") + .HasForeignKey("FirstID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Episode", "Second") + .WithMany() + .HasForeignKey("SecondID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("First"); + + b.Navigation("Second"); + }); + + modelBuilder.Entity("Kyoo.Models.Collection", b => + { + b.Navigation("LibraryLinks"); + + b.Navigation("ShowLinks"); + }); + + modelBuilder.Entity("Kyoo.Models.Episode", b => + { + b.Navigation("ExternalIDs"); + + b.Navigation("Tracks"); + }); + + modelBuilder.Entity("Kyoo.Models.Genre", b => + { + b.Navigation("ShowLinks"); + }); + + modelBuilder.Entity("Kyoo.Models.Library", b => + { + b.Navigation("CollectionLinks"); + + b.Navigation("ProviderLinks"); + + b.Navigation("ShowLinks"); + }); + + modelBuilder.Entity("Kyoo.Models.People", b => + { + b.Navigation("ExternalIDs"); + + b.Navigation("Roles"); + }); + + modelBuilder.Entity("Kyoo.Models.Provider", b => + { + b.Navigation("LibraryLinks"); + + b.Navigation("MetadataLinks"); + }); + + modelBuilder.Entity("Kyoo.Models.Season", b => + { + b.Navigation("Episodes"); + + b.Navigation("ExternalIDs"); + }); + + modelBuilder.Entity("Kyoo.Models.Show", b => + { + b.Navigation("CollectionLinks"); + + b.Navigation("Episodes"); + + b.Navigation("ExternalIDs"); + + b.Navigation("GenreLinks"); + + b.Navigation("LibraryLinks"); + + b.Navigation("People"); + + b.Navigation("Seasons"); + }); + + modelBuilder.Entity("Kyoo.Models.Studio", b => + { + b.Navigation("Shows"); + }); + + modelBuilder.Entity("Kyoo.Models.User", b => + { + b.Navigation("CurrentlyWatching"); + + b.Navigation("ShowLinks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Kyoo.SqLite/Migrations/20210529124408_Initial.cs b/Kyoo.SqLite/Migrations/20210529124408_Initial.cs new file mode 100644 index 00000000..68a28ec5 --- /dev/null +++ b/Kyoo.SqLite/Migrations/20210529124408_Initial.cs @@ -0,0 +1,693 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Kyoo.SQLite.Migrations +{ + public partial class Initial : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Collections", + columns: table => new + { + ID = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Slug = table.Column(type: "TEXT", nullable: false), + Name = table.Column(type: "TEXT", nullable: true), + Poster = table.Column(type: "TEXT", nullable: true), + Overview = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Collections", x => x.ID); + }); + + migrationBuilder.CreateTable( + name: "Genres", + columns: table => new + { + ID = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Slug = table.Column(type: "TEXT", nullable: false), + Name = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Genres", x => x.ID); + }); + + migrationBuilder.CreateTable( + name: "Libraries", + columns: table => new + { + ID = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Slug = table.Column(type: "TEXT", nullable: false), + Name = table.Column(type: "TEXT", nullable: true), + Paths = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Libraries", x => x.ID); + }); + + migrationBuilder.CreateTable( + name: "People", + columns: table => new + { + ID = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Slug = table.Column(type: "TEXT", nullable: false), + Name = table.Column(type: "TEXT", nullable: true), + Poster = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_People", x => x.ID); + }); + + migrationBuilder.CreateTable( + name: "Providers", + columns: table => new + { + ID = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Slug = table.Column(type: "TEXT", nullable: false), + Name = table.Column(type: "TEXT", nullable: true), + Logo = table.Column(type: "TEXT", nullable: true), + LogoExtension = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Providers", x => x.ID); + }); + + migrationBuilder.CreateTable( + name: "Studios", + columns: table => new + { + ID = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Slug = table.Column(type: "TEXT", nullable: false), + Name = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Studios", x => x.ID); + }); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + ID = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Slug = table.Column(type: "TEXT", nullable: false), + Username = table.Column(type: "TEXT", nullable: true), + Email = table.Column(type: "TEXT", nullable: true), + Password = table.Column(type: "TEXT", nullable: true), + Permissions = table.Column(type: "TEXT", nullable: true), + ExtraData = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.ID); + }); + + migrationBuilder.CreateTable( + name: "Link", + columns: table => new + { + FirstID = table.Column(type: "INTEGER", nullable: false), + SecondID = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Link", x => new { x.FirstID, x.SecondID }); + table.ForeignKey( + name: "FK_Link_Collections_SecondID", + column: x => x.SecondID, + principalTable: "Collections", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Link_Libraries_FirstID", + column: x => x.FirstID, + principalTable: "Libraries", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Link", + columns: table => new + { + FirstID = table.Column(type: "INTEGER", nullable: false), + SecondID = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Link", x => new { x.FirstID, x.SecondID }); + table.ForeignKey( + name: "FK_Link_Libraries_FirstID", + column: x => x.FirstID, + principalTable: "Libraries", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Link_Providers_SecondID", + column: x => x.SecondID, + principalTable: "Providers", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Shows", + columns: table => new + { + ID = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Slug = table.Column(type: "TEXT", nullable: false), + Title = table.Column(type: "TEXT", nullable: true), + Aliases = table.Column(type: "TEXT", nullable: true), + Path = table.Column(type: "TEXT", nullable: true), + Overview = table.Column(type: "TEXT", nullable: true), + Status = table.Column(type: "INTEGER", nullable: true), + TrailerUrl = table.Column(type: "TEXT", nullable: true), + StartYear = table.Column(type: "INTEGER", nullable: true), + EndYear = table.Column(type: "INTEGER", nullable: true), + Poster = table.Column(type: "TEXT", nullable: true), + Logo = table.Column(type: "TEXT", nullable: true), + Backdrop = table.Column(type: "TEXT", nullable: true), + IsMovie = table.Column(type: "INTEGER", nullable: false), + StudioID = table.Column(type: "INTEGER", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Shows", x => x.ID); + table.ForeignKey( + name: "FK_Shows_Studios_StudioID", + column: x => x.StudioID, + principalTable: "Studios", + principalColumn: "ID", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "Link", + columns: table => new + { + FirstID = table.Column(type: "INTEGER", nullable: false), + SecondID = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Link", x => new { x.FirstID, x.SecondID }); + table.ForeignKey( + name: "FK_Link_Collections_FirstID", + column: x => x.FirstID, + principalTable: "Collections", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Link_Shows_SecondID", + column: x => x.SecondID, + principalTable: "Shows", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Link", + columns: table => new + { + FirstID = table.Column(type: "INTEGER", nullable: false), + SecondID = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Link", x => new { x.FirstID, x.SecondID }); + table.ForeignKey( + name: "FK_Link_Libraries_FirstID", + column: x => x.FirstID, + principalTable: "Libraries", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Link_Shows_SecondID", + column: x => x.SecondID, + principalTable: "Shows", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Link", + columns: table => new + { + FirstID = table.Column(type: "INTEGER", nullable: false), + SecondID = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Link", x => new { x.FirstID, x.SecondID }); + table.ForeignKey( + name: "FK_Link_Genres_SecondID", + column: x => x.SecondID, + principalTable: "Genres", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Link_Shows_FirstID", + column: x => x.FirstID, + principalTable: "Shows", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Link", + columns: table => new + { + FirstID = table.Column(type: "INTEGER", nullable: false), + SecondID = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Link", x => new { x.FirstID, x.SecondID }); + table.ForeignKey( + name: "FK_Link_Shows_SecondID", + column: x => x.SecondID, + principalTable: "Shows", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Link_Users_FirstID", + column: x => x.FirstID, + principalTable: "Users", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "PeopleRoles", + columns: table => new + { + ID = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + PeopleID = table.Column(type: "INTEGER", nullable: false), + ShowID = table.Column(type: "INTEGER", nullable: false), + Role = table.Column(type: "TEXT", nullable: true), + Type = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_PeopleRoles", x => x.ID); + table.ForeignKey( + name: "FK_PeopleRoles_People_PeopleID", + column: x => x.PeopleID, + principalTable: "People", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_PeopleRoles_Shows_ShowID", + column: x => x.ShowID, + principalTable: "Shows", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Seasons", + columns: table => new + { + ID = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + ShowID = table.Column(type: "INTEGER", nullable: false), + SeasonNumber = table.Column(type: "INTEGER", nullable: false), + Title = table.Column(type: "TEXT", nullable: true), + Overview = table.Column(type: "TEXT", nullable: true), + Year = table.Column(type: "INTEGER", nullable: true), + Poster = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Seasons", x => x.ID); + table.ForeignKey( + name: "FK_Seasons_Shows_ShowID", + column: x => x.ShowID, + principalTable: "Shows", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Episodes", + columns: table => new + { + ID = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + ShowID = table.Column(type: "INTEGER", nullable: false), + SeasonID = table.Column(type: "INTEGER", nullable: true), + SeasonNumber = table.Column(type: "INTEGER", nullable: false), + EpisodeNumber = table.Column(type: "INTEGER", nullable: false), + AbsoluteNumber = table.Column(type: "INTEGER", nullable: false), + Path = table.Column(type: "TEXT", nullable: true), + Thumb = table.Column(type: "TEXT", nullable: true), + Title = table.Column(type: "TEXT", nullable: true), + Overview = table.Column(type: "TEXT", nullable: true), + ReleaseDate = table.Column(type: "TEXT", nullable: true), + Runtime = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Episodes", x => x.ID); + table.ForeignKey( + name: "FK_Episodes_Seasons_SeasonID", + column: x => x.SeasonID, + principalTable: "Seasons", + principalColumn: "ID", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_Episodes_Shows_ShowID", + column: x => x.ShowID, + principalTable: "Shows", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "MetadataIds", + columns: table => new + { + ID = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + ProviderID = table.Column(type: "INTEGER", nullable: false), + ShowID = table.Column(type: "INTEGER", nullable: true), + EpisodeID = table.Column(type: "INTEGER", nullable: true), + SeasonID = table.Column(type: "INTEGER", nullable: true), + PeopleID = table.Column(type: "INTEGER", nullable: true), + DataID = table.Column(type: "TEXT", nullable: true), + Link = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_MetadataIds", x => x.ID); + table.ForeignKey( + name: "FK_MetadataIds_Episodes_EpisodeID", + column: x => x.EpisodeID, + principalTable: "Episodes", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_MetadataIds_People_PeopleID", + column: x => x.PeopleID, + principalTable: "People", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_MetadataIds_Providers_ProviderID", + column: x => x.ProviderID, + principalTable: "Providers", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_MetadataIds_Seasons_SeasonID", + column: x => x.SeasonID, + principalTable: "Seasons", + 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: "Tracks", + columns: table => new + { + ID = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + EpisodeID = table.Column(type: "INTEGER", nullable: false), + TrackIndex = table.Column(type: "INTEGER", nullable: false), + IsDefault = table.Column(type: "INTEGER", nullable: false), + IsForced = table.Column(type: "INTEGER", nullable: false), + IsExternal = table.Column(type: "INTEGER", nullable: false), + Title = table.Column(type: "TEXT", nullable: true), + Language = table.Column(type: "TEXT", nullable: true), + Codec = table.Column(type: "TEXT", nullable: true), + Path = table.Column(type: "TEXT", nullable: true), + Type = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Tracks", x => x.ID); + table.ForeignKey( + name: "FK_Tracks_Episodes_EpisodeID", + column: x => x.EpisodeID, + principalTable: "Episodes", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "WatchedEpisodes", + columns: table => new + { + FirstID = table.Column(type: "INTEGER", nullable: false), + SecondID = table.Column(type: "INTEGER", nullable: false), + WatchedPercentage = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_WatchedEpisodes", x => new { x.FirstID, x.SecondID }); + table.ForeignKey( + name: "FK_WatchedEpisodes_Episodes_SecondID", + column: x => x.SecondID, + principalTable: "Episodes", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_WatchedEpisodes_Users_FirstID", + column: x => x.FirstID, + principalTable: "Users", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Collections_Slug", + table: "Collections", + column: "Slug", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Episodes_SeasonID", + table: "Episodes", + column: "SeasonID"); + + migrationBuilder.CreateIndex( + name: "IX_Episodes_ShowID_SeasonNumber_EpisodeNumber_AbsoluteNumber", + table: "Episodes", + columns: new[] { "ShowID", "SeasonNumber", "EpisodeNumber", "AbsoluteNumber" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Genres_Slug", + table: "Genres", + column: "Slug", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Libraries_Slug", + table: "Libraries", + column: "Slug", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Link_SecondID", + table: "Link", + column: "SecondID"); + + migrationBuilder.CreateIndex( + name: "IX_Link_SecondID", + table: "Link", + column: "SecondID"); + + migrationBuilder.CreateIndex( + name: "IX_Link_SecondID", + table: "Link", + column: "SecondID"); + + migrationBuilder.CreateIndex( + name: "IX_Link_SecondID", + table: "Link", + column: "SecondID"); + + migrationBuilder.CreateIndex( + name: "IX_Link_SecondID", + table: "Link", + column: "SecondID"); + + migrationBuilder.CreateIndex( + name: "IX_Link_SecondID", + table: "Link", + column: "SecondID"); + + migrationBuilder.CreateIndex( + name: "IX_MetadataIds_EpisodeID", + table: "MetadataIds", + column: "EpisodeID"); + + migrationBuilder.CreateIndex( + name: "IX_MetadataIds_PeopleID", + table: "MetadataIds", + column: "PeopleID"); + + migrationBuilder.CreateIndex( + name: "IX_MetadataIds_ProviderID", + table: "MetadataIds", + column: "ProviderID"); + + migrationBuilder.CreateIndex( + name: "IX_MetadataIds_SeasonID", + table: "MetadataIds", + column: "SeasonID"); + + migrationBuilder.CreateIndex( + name: "IX_MetadataIds_ShowID", + table: "MetadataIds", + column: "ShowID"); + + migrationBuilder.CreateIndex( + name: "IX_People_Slug", + table: "People", + column: "Slug", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_PeopleRoles_PeopleID", + table: "PeopleRoles", + column: "PeopleID"); + + migrationBuilder.CreateIndex( + name: "IX_PeopleRoles_ShowID", + table: "PeopleRoles", + column: "ShowID"); + + migrationBuilder.CreateIndex( + name: "IX_Providers_Slug", + table: "Providers", + column: "Slug", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Seasons_ShowID_SeasonNumber", + table: "Seasons", + columns: new[] { "ShowID", "SeasonNumber" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Shows_Slug", + table: "Shows", + column: "Slug", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Shows_StudioID", + table: "Shows", + column: "StudioID"); + + migrationBuilder.CreateIndex( + name: "IX_Studios_Slug", + table: "Studios", + column: "Slug", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Tracks_EpisodeID_Type_Language_TrackIndex_IsForced", + table: "Tracks", + columns: new[] { "EpisodeID", "Type", "Language", "TrackIndex", "IsForced" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Users_Slug", + table: "Users", + column: "Slug", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_WatchedEpisodes_SecondID", + table: "WatchedEpisodes", + column: "SecondID"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Link"); + + migrationBuilder.DropTable( + name: "Link"); + + migrationBuilder.DropTable( + name: "Link"); + + migrationBuilder.DropTable( + name: "Link"); + + migrationBuilder.DropTable( + name: "Link"); + + migrationBuilder.DropTable( + name: "Link"); + + migrationBuilder.DropTable( + name: "MetadataIds"); + + migrationBuilder.DropTable( + name: "PeopleRoles"); + + migrationBuilder.DropTable( + name: "Tracks"); + + migrationBuilder.DropTable( + name: "WatchedEpisodes"); + + migrationBuilder.DropTable( + name: "Collections"); + + migrationBuilder.DropTable( + name: "Libraries"); + + migrationBuilder.DropTable( + name: "Genres"); + + migrationBuilder.DropTable( + name: "Providers"); + + migrationBuilder.DropTable( + name: "People"); + + migrationBuilder.DropTable( + name: "Episodes"); + + migrationBuilder.DropTable( + name: "Users"); + + migrationBuilder.DropTable( + name: "Seasons"); + + migrationBuilder.DropTable( + name: "Shows"); + + migrationBuilder.DropTable( + name: "Studios"); + } + } +} diff --git a/Kyoo.SqLite/Migrations/SqLiteContextModelSnapshot.cs b/Kyoo.SqLite/Migrations/SqLiteContextModelSnapshot.cs new file mode 100644 index 00000000..60379986 --- /dev/null +++ b/Kyoo.SqLite/Migrations/SqLiteContextModelSnapshot.cs @@ -0,0 +1,876 @@ +// +using System; +using Kyoo.SqLite; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Kyoo.SQLite.Migrations +{ + [DbContext(typeof(SqLiteContext))] + partial class SqLiteContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.6"); + + modelBuilder.Entity("Kyoo.Models.Collection", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("Poster") + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Collections"); + }); + + modelBuilder.Entity("Kyoo.Models.Episode", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AbsoluteNumber") + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("Runtime") + .HasColumnType("INTEGER"); + + b.Property("SeasonID") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("ShowID") + .HasColumnType("INTEGER"); + + b.Property("Thumb") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("SeasonID"); + + b.HasIndex("ShowID", "SeasonNumber", "EpisodeNumber", "AbsoluteNumber") + .IsUnique(); + + b.ToTable("Episodes"); + }); + + modelBuilder.Entity("Kyoo.Models.Genre", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Genres"); + }); + + modelBuilder.Entity("Kyoo.Models.Library", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Paths") + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Libraries"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.Property("FirstID") + .HasColumnType("INTEGER"); + + b.Property("SecondID") + .HasColumnType("INTEGER"); + + b.HasKey("FirstID", "SecondID"); + + b.HasIndex("SecondID"); + + b.ToTable("Link"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.Property("FirstID") + .HasColumnType("INTEGER"); + + b.Property("SecondID") + .HasColumnType("INTEGER"); + + b.HasKey("FirstID", "SecondID"); + + b.HasIndex("SecondID"); + + b.ToTable("Link"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.Property("FirstID") + .HasColumnType("INTEGER"); + + b.Property("SecondID") + .HasColumnType("INTEGER"); + + b.HasKey("FirstID", "SecondID"); + + b.HasIndex("SecondID"); + + b.ToTable("Link"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.Property("FirstID") + .HasColumnType("INTEGER"); + + b.Property("SecondID") + .HasColumnType("INTEGER"); + + b.HasKey("FirstID", "SecondID"); + + b.HasIndex("SecondID"); + + b.ToTable("Link"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.Property("FirstID") + .HasColumnType("INTEGER"); + + b.Property("SecondID") + .HasColumnType("INTEGER"); + + b.HasKey("FirstID", "SecondID"); + + b.HasIndex("SecondID"); + + b.ToTable("Link"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.Property("FirstID") + .HasColumnType("INTEGER"); + + b.Property("SecondID") + .HasColumnType("INTEGER"); + + b.HasKey("FirstID", "SecondID"); + + b.HasIndex("SecondID"); + + b.ToTable("Link"); + }); + + modelBuilder.Entity("Kyoo.Models.MetadataID", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DataID") + .HasColumnType("TEXT"); + + b.Property("EpisodeID") + .HasColumnType("INTEGER"); + + b.Property("Link") + .HasColumnType("TEXT"); + + b.Property("PeopleID") + .HasColumnType("INTEGER"); + + b.Property("ProviderID") + .HasColumnType("INTEGER"); + + b.Property("SeasonID") + .HasColumnType("INTEGER"); + + b.Property("ShowID") + .HasColumnType("INTEGER"); + + b.HasKey("ID"); + + b.HasIndex("EpisodeID"); + + b.HasIndex("PeopleID"); + + b.HasIndex("ProviderID"); + + b.HasIndex("SeasonID"); + + b.HasIndex("ShowID"); + + b.ToTable("MetadataIds"); + }); + + modelBuilder.Entity("Kyoo.Models.People", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Poster") + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("People"); + }); + + modelBuilder.Entity("Kyoo.Models.PeopleRole", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("PeopleID") + .HasColumnType("INTEGER"); + + b.Property("Role") + .HasColumnType("TEXT"); + + b.Property("ShowID") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("PeopleID"); + + b.HasIndex("ShowID"); + + b.ToTable("PeopleRoles"); + }); + + modelBuilder.Entity("Kyoo.Models.Provider", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Logo") + .HasColumnType("TEXT"); + + b.Property("LogoExtension") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Providers"); + }); + + modelBuilder.Entity("Kyoo.Models.Season", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("Poster") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("ShowID") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("ID"); + + b.HasIndex("ShowID", "SeasonNumber") + .IsUnique(); + + b.ToTable("Seasons"); + }); + + modelBuilder.Entity("Kyoo.Models.Show", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Aliases") + .HasColumnType("TEXT"); + + b.Property("Backdrop") + .HasColumnType("TEXT"); + + b.Property("EndYear") + .HasColumnType("INTEGER"); + + b.Property("IsMovie") + .HasColumnType("INTEGER"); + + b.Property("Logo") + .HasColumnType("TEXT"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.Property("Poster") + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StartYear") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("StudioID") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TrailerUrl") + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("Slug") + .IsUnique(); + + b.HasIndex("StudioID"); + + b.ToTable("Shows"); + }); + + modelBuilder.Entity("Kyoo.Models.Studio", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Studios"); + }); + + modelBuilder.Entity("Kyoo.Models.Track", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Codec") + .HasColumnType("TEXT"); + + b.Property("EpisodeID") + .HasColumnType("INTEGER"); + + b.Property("IsDefault") + .HasColumnType("INTEGER"); + + b.Property("IsExternal") + .HasColumnType("INTEGER"); + + b.Property("IsForced") + .HasColumnType("INTEGER"); + + b.Property("Language") + .HasColumnType("TEXT"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TrackIndex") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("ID"); + + b.HasIndex("EpisodeID", "Type", "Language", "TrackIndex", "IsForced") + .IsUnique(); + + b.ToTable("Tracks"); + }); + + modelBuilder.Entity("Kyoo.Models.User", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Email") + .HasColumnType("TEXT"); + + b.Property("ExtraData") + .HasColumnType("TEXT"); + + b.Property("Password") + .HasColumnType("TEXT"); + + b.Property("Permissions") + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Username") + .HasColumnType("TEXT"); + + b.HasKey("ID"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Kyoo.Models.WatchedEpisode", b => + { + b.Property("FirstID") + .HasColumnType("INTEGER"); + + b.Property("SecondID") + .HasColumnType("INTEGER"); + + b.Property("WatchedPercentage") + .HasColumnType("INTEGER"); + + b.HasKey("FirstID", "SecondID"); + + b.HasIndex("SecondID"); + + b.ToTable("WatchedEpisodes"); + }); + + modelBuilder.Entity("Kyoo.Models.Episode", b => + { + b.HasOne("Kyoo.Models.Season", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonID"); + + b.HasOne("Kyoo.Models.Show", "Show") + .WithMany("Episodes") + .HasForeignKey("ShowID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + + b.Navigation("Show"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.HasOne("Kyoo.Models.Collection", "First") + .WithMany("ShowLinks") + .HasForeignKey("FirstID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Show", "Second") + .WithMany("CollectionLinks") + .HasForeignKey("SecondID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("First"); + + b.Navigation("Second"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.HasOne("Kyoo.Models.Library", "First") + .WithMany("CollectionLinks") + .HasForeignKey("FirstID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Collection", "Second") + .WithMany("LibraryLinks") + .HasForeignKey("SecondID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("First"); + + b.Navigation("Second"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.HasOne("Kyoo.Models.Library", "First") + .WithMany("ProviderLinks") + .HasForeignKey("FirstID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Provider", "Second") + .WithMany("LibraryLinks") + .HasForeignKey("SecondID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("First"); + + b.Navigation("Second"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.HasOne("Kyoo.Models.Library", "First") + .WithMany("ShowLinks") + .HasForeignKey("FirstID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Show", "Second") + .WithMany("LibraryLinks") + .HasForeignKey("SecondID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("First"); + + b.Navigation("Second"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.HasOne("Kyoo.Models.Show", "First") + .WithMany("GenreLinks") + .HasForeignKey("FirstID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Genre", "Second") + .WithMany("ShowLinks") + .HasForeignKey("SecondID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("First"); + + b.Navigation("Second"); + }); + + modelBuilder.Entity("Kyoo.Models.Link", b => + { + b.HasOne("Kyoo.Models.User", "First") + .WithMany("ShowLinks") + .HasForeignKey("FirstID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Show", "Second") + .WithMany() + .HasForeignKey("SecondID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("First"); + + b.Navigation("Second"); + }); + + modelBuilder.Entity("Kyoo.Models.MetadataID", b => + { + b.HasOne("Kyoo.Models.Episode", "Episode") + .WithMany("ExternalIDs") + .HasForeignKey("EpisodeID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Kyoo.Models.People", "People") + .WithMany("ExternalIDs") + .HasForeignKey("PeopleID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Kyoo.Models.Provider", "Provider") + .WithMany("MetadataLinks") + .HasForeignKey("ProviderID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Season", "Season") + .WithMany("ExternalIDs") + .HasForeignKey("SeasonID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Kyoo.Models.Show", "Show") + .WithMany("ExternalIDs") + .HasForeignKey("ShowID") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Episode"); + + b.Navigation("People"); + + b.Navigation("Provider"); + + b.Navigation("Season"); + + b.Navigation("Show"); + }); + + modelBuilder.Entity("Kyoo.Models.PeopleRole", b => + { + b.HasOne("Kyoo.Models.People", "People") + .WithMany("Roles") + .HasForeignKey("PeopleID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Show", "Show") + .WithMany("People") + .HasForeignKey("ShowID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("People"); + + b.Navigation("Show"); + }); + + modelBuilder.Entity("Kyoo.Models.Season", b => + { + b.HasOne("Kyoo.Models.Show", "Show") + .WithMany("Seasons") + .HasForeignKey("ShowID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Show"); + }); + + modelBuilder.Entity("Kyoo.Models.Show", b => + { + b.HasOne("Kyoo.Models.Studio", "Studio") + .WithMany("Shows") + .HasForeignKey("StudioID"); + + b.Navigation("Studio"); + }); + + modelBuilder.Entity("Kyoo.Models.Track", b => + { + b.HasOne("Kyoo.Models.Episode", "Episode") + .WithMany("Tracks") + .HasForeignKey("EpisodeID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Episode"); + }); + + modelBuilder.Entity("Kyoo.Models.WatchedEpisode", b => + { + b.HasOne("Kyoo.Models.User", "First") + .WithMany("CurrentlyWatching") + .HasForeignKey("FirstID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Kyoo.Models.Episode", "Second") + .WithMany() + .HasForeignKey("SecondID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("First"); + + b.Navigation("Second"); + }); + + modelBuilder.Entity("Kyoo.Models.Collection", b => + { + b.Navigation("LibraryLinks"); + + b.Navigation("ShowLinks"); + }); + + modelBuilder.Entity("Kyoo.Models.Episode", b => + { + b.Navigation("ExternalIDs"); + + b.Navigation("Tracks"); + }); + + modelBuilder.Entity("Kyoo.Models.Genre", b => + { + b.Navigation("ShowLinks"); + }); + + modelBuilder.Entity("Kyoo.Models.Library", b => + { + b.Navigation("CollectionLinks"); + + b.Navigation("ProviderLinks"); + + b.Navigation("ShowLinks"); + }); + + modelBuilder.Entity("Kyoo.Models.People", b => + { + b.Navigation("ExternalIDs"); + + b.Navigation("Roles"); + }); + + modelBuilder.Entity("Kyoo.Models.Provider", b => + { + b.Navigation("LibraryLinks"); + + b.Navigation("MetadataLinks"); + }); + + modelBuilder.Entity("Kyoo.Models.Season", b => + { + b.Navigation("Episodes"); + + b.Navigation("ExternalIDs"); + }); + + modelBuilder.Entity("Kyoo.Models.Show", b => + { + b.Navigation("CollectionLinks"); + + b.Navigation("Episodes"); + + b.Navigation("ExternalIDs"); + + b.Navigation("GenreLinks"); + + b.Navigation("LibraryLinks"); + + b.Navigation("People"); + + b.Navigation("Seasons"); + }); + + modelBuilder.Entity("Kyoo.Models.Studio", b => + { + b.Navigation("Shows"); + }); + + modelBuilder.Entity("Kyoo.Models.User", b => + { + b.Navigation("CurrentlyWatching"); + + b.Navigation("ShowLinks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Kyoo.SqLite/SqLiteContext.cs b/Kyoo.SqLite/SqLiteContext.cs new file mode 100644 index 00000000..ca1a651e --- /dev/null +++ b/Kyoo.SqLite/SqLiteContext.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Reflection; +using Kyoo.Models; +using Microsoft.Data.Sqlite; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Newtonsoft.Json; + +namespace Kyoo.SqLite +{ + /// + /// A sqlite implementation of . + /// + public class SqLiteContext : DatabaseContext + { + /// + /// The connection string to use. + /// + private readonly string _connection; + + /// + /// Is this instance in debug mode? + /// + private readonly bool _debugMode; + + /// + /// Should the configure step be skipped? This is used when the database is created via DbContextOptions. + /// + private readonly bool _skipConfigure; + + /// + /// A basic constructor that set default values (query tracker behaviors, mapping enums...) + /// + public SqLiteContext() + { } + + /// + /// Create a new using specific options + /// + /// The options to use. + public SqLiteContext(DbContextOptions options) + : base(options) + { + _skipConfigure = true; + } + + /// + /// A basic constructor that set default values (query tracker behaviors, mapping enums...) + /// + /// The connection string to use + /// Is this instance in debug mode? + public SqLiteContext(string connection, bool debugMode) + { + _connection = connection; + _debugMode = debugMode; + } + + /// + /// Set connection information for this database context + /// + /// An option builder to fill. + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (!_skipConfigure) + { + if (_connection != null) + optionsBuilder.UseSqlite(_connection); + else + optionsBuilder.UseSqlite(); + if (_debugMode) + optionsBuilder.EnableDetailedErrors().EnableSensitiveDataLogging(); + } + + base.OnConfiguring(optionsBuilder); + } + + /// + /// Set database parameters to support every types of Kyoo. + /// + /// The database's model builder. + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + // modelBuilder.HasPostgresEnum(); + // modelBuilder.HasPostgresEnum(); + // modelBuilder.HasPostgresEnum(); + + ValueConverter arrayConvertor = new( + x => string.Join(";", x), + x => x.Split(';', StringSplitOptions.None)); + modelBuilder.Entity() + .Property(x => x.Paths) + .HasConversion(arrayConvertor); + modelBuilder.Entity() + .Property(x => x.Aliases) + .HasConversion(arrayConvertor); + modelBuilder.Entity() + .Property(x => x.Permissions) + .HasConversion(arrayConvertor); + + modelBuilder.Entity() + .Property(x => x.Status) + .HasConversion(); + modelBuilder.Entity() + .Property(x => x.Type) + .HasConversion(); + + ValueConverter, string> jsonConvertor = new( + x => JsonConvert.SerializeObject(x), + x => JsonConvert.DeserializeObject>(x)); + modelBuilder.Entity() + .Property(x => x.ExtraData) + .HasConversion(jsonConvertor); + + base.OnModelCreating(modelBuilder); + } + + /// + protected override bool IsDuplicateException(Exception ex) + { + return ex.InnerException is SqliteException { SqliteExtendedErrorCode: 2067 /*SQLITE_CONSTRAINT_UNIQUE*/}; + } + + /// + public override Expression> Like(Expression> query, string format) + { + MethodInfo iLike = MethodOfUtils.MethodOf(EF.Functions.Like); + MethodCallExpression call = Expression.Call(iLike, query.Body, Expression.Constant(format)); + + return Expression.Lambda>(call, query.Parameters); + } + } +} \ No newline at end of file diff --git a/Kyoo.SqLite/SqLiteModule.cs b/Kyoo.SqLite/SqLiteModule.cs new file mode 100644 index 00000000..d9815093 --- /dev/null +++ b/Kyoo.SqLite/SqLiteModule.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using Kyoo.Controllers; +using Microsoft.AspNetCore.Hosting; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace Kyoo.SqLite +{ + /// + /// A module to add sqlite capacity to the app. + /// + public class SqLiteModule : IPlugin + { + /// + public string Slug => "sqlite"; + + /// + public string Name => "SqLite"; + + /// + public string Description => "A database context for sqlite."; + + /// + public ICollection Provides => new[] + { + typeof(DatabaseContext) + }; + + /// + public ICollection ConditionalProvides => ArraySegment.Empty; + + /// + public ICollection Requires => ArraySegment.Empty; + + + /// + /// The configuration to use. The database connection string is pulled from it. + /// + private readonly IConfiguration _configuration; + + /// + /// The host environment to check if the app is in debug mode. + /// + private readonly IWebHostEnvironment _environment; + + /// + /// Create a new postgres module instance and use the given configuration and environment. + /// + /// The configuration to use + /// The environment that will be used (if the env is in development mode, more information will be displayed on errors. + public SqLiteModule(IConfiguration configuration, IWebHostEnvironment env) + { + _configuration = configuration; + _environment = env; + } + + + /// + public void Configure(IServiceCollection services, ICollection availableTypes) + { + services.AddDbContext(x => + { + x.UseSqlite(_configuration.GetDatabaseConnection("sqlite")); + if (_environment.IsDevelopment()) + x.EnableDetailedErrors().EnableSensitiveDataLogging(); + }); + } + } +} \ No newline at end of file diff --git a/Kyoo.sln b/Kyoo.sln index 3f814bd3..60998b55 100644 --- a/Kyoo.sln +++ b/Kyoo.sln @@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Postgresql", "Kyoo.Pos EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Authentication", "Kyoo.Authentication\Kyoo.Authentication.csproj", "{7A841335-6523-47DB-9717-80AA7BD943FD}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.SqLite", "Kyoo.SqLite\Kyoo.SqLite.csproj", "{6515380E-1E57-42DA-B6E3-E1C8A848818A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -41,5 +43,9 @@ Global {7A841335-6523-47DB-9717-80AA7BD943FD}.Debug|Any CPU.Build.0 = Debug|Any CPU {7A841335-6523-47DB-9717-80AA7BD943FD}.Release|Any CPU.ActiveCfg = Release|Any CPU {7A841335-6523-47DB-9717-80AA7BD943FD}.Release|Any CPU.Build.0 = Release|Any CPU + {6515380E-1E57-42DA-B6E3-E1C8A848818A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6515380E-1E57-42DA-B6E3-E1C8A848818A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6515380E-1E57-42DA-B6E3-E1C8A848818A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6515380E-1E57-42DA-B6E3-E1C8A848818A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal