diff --git a/back/.config/dotnet-tools.json b/back/.config/dotnet-tools.json
index b4a41b06..2be6730d 100644
--- a/back/.config/dotnet-tools.json
+++ b/back/.config/dotnet-tools.json
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"dotnet-ef": {
- "version": "7.0.7",
+ "version": "7.0.9",
"commands": [
"dotnet-ef"
]
diff --git a/back/Kyoo.ruleset b/back/Kyoo.ruleset
index 305979a1..13d29e23 100644
--- a/back/Kyoo.ruleset
+++ b/back/Kyoo.ruleset
@@ -37,5 +37,6 @@
+
diff --git a/back/src/Kyoo.Postgresql/DatabaseContext.cs b/back/src/Kyoo.Postgresql/DatabaseContext.cs
index ab50866b..5a49edc1 100644
--- a/back/src/Kyoo.Postgresql/DatabaseContext.cs
+++ b/back/src/Kyoo.Postgresql/DatabaseContext.cs
@@ -353,6 +353,9 @@ namespace Kyoo.Postgresql
modelBuilder.Entity()
.HasIndex(x => x.Slug)
.IsUnique();
+
+ modelBuilder.Entity()
+ .ToView("library_items");
}
///
diff --git a/back/src/Kyoo.Postgresql/MigrationHelper.cs b/back/src/Kyoo.Postgresql/MigrationHelper.cs
new file mode 100644
index 00000000..f52dd2bd
--- /dev/null
+++ b/back/src/Kyoo.Postgresql/MigrationHelper.cs
@@ -0,0 +1,52 @@
+// Kyoo - A portable and vast media library solution.
+// Copyright (c) Kyoo.
+//
+// See AUTHORS.md and LICENSE file in the project root for full license information.
+//
+// Kyoo is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// Kyoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Kyoo. If not, see .
+
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace Kyoo.Postgresql
+{
+ public static class MigrationHelper
+ {
+ public static void CreateLibraryItemsView(MigrationBuilder migrationBuilder)
+ {
+ // language=PostgreSQL
+ migrationBuilder.Sql(@"
+ CREATE VIEW library_items AS
+ SELECT s.id, s.slug, s.title, s.overview, s.status, s.start_air, s.end_air, s.images, CASE
+ WHEN s.is_movie THEN 'movie'::item_type
+ ELSE 'show'::item_type
+ END AS type
+ FROM shows AS s
+ WHERE NOT (EXISTS (
+ SELECT 1
+ FROM link_collection_show AS l
+ INNER JOIN collections AS c ON l.collection_id = c.id
+ WHERE s.id = l.show_id))
+ UNION ALL
+ SELECT -c0.id, c0.slug, c0.name AS title, c0.overview, 'unknown'::status AS status,
+ NULL AS start_air, NULL AS end_air, c0.images, 'collection'::item_type AS type
+ FROM collections AS c0");
+ }
+
+ public static void DropLibraryItemsView(MigrationBuilder migrationBuilder)
+ {
+ // language=PostgreSQL
+ migrationBuilder.Sql(@"DROP VIEW library_items");
+ }
+ }
+}
diff --git a/back/src/Kyoo.Postgresql/Migrations/20210801171641_Triggers.cs b/back/src/Kyoo.Postgresql/Migrations/20210801171641_Triggers.cs
index 19cf8ce5..94a2ad80 100644
--- a/back/src/Kyoo.Postgresql/Migrations/20210801171641_Triggers.cs
+++ b/back/src/Kyoo.Postgresql/Migrations/20210801171641_Triggers.cs
@@ -157,23 +157,7 @@ namespace Kyoo.Postgresql.Migrations
BEFORE INSERT OR UPDATE OF episode_id, is_forced, language, track_index, type ON tracks
FOR EACH ROW EXECUTE PROCEDURE track_slug_update();");
- // language=PostgreSQL
- migrationBuilder.Sql(@"
- CREATE VIEW library_items AS
- SELECT s.id, s.slug, s.title, s.overview, s.status, s.start_air, s.end_air, s.images, CASE
- WHEN s.is_movie THEN 'movie'::item_type
- ELSE 'show'::item_type
- END AS type
- FROM shows AS s
- WHERE NOT (EXISTS (
- SELECT 1
- FROM link_collection_show AS l
- INNER JOIN collections AS c ON l.collection_id = c.id
- WHERE s.id = l.show_id))
- UNION ALL
- SELECT -c0.id, c0.slug, c0.name AS title, c0.overview, 'unknown'::status AS status,
- NULL AS start_air, NULL AS end_air, c0.images, 'collection'::item_type AS type
- FROM collections AS c0");
+ MigrationHelper.CreateLibraryItemsView(migrationBuilder);
}
///
@@ -199,8 +183,7 @@ namespace Kyoo.Postgresql.Migrations
migrationBuilder.Sql("DROP TRIGGER episode_track_slug_trigger ON episodes;");
// language=PostgreSQL
migrationBuilder.Sql(@"DROP FUNCTION episode_update_tracks_slug;");
- // language=PostgreSQL
- migrationBuilder.Sql(@"DROP VIEW library_items;");
+ MigrationHelper.DropLibraryItemsView(migrationBuilder);
}
}
}
diff --git a/back/src/Kyoo.Postgresql/Migrations/20230726100747_Timestamp.Designer.cs b/back/src/Kyoo.Postgresql/Migrations/20230726100747_Timestamp.Designer.cs
new file mode 100644
index 00000000..a50fbd67
--- /dev/null
+++ b/back/src/Kyoo.Postgresql/Migrations/20230726100747_Timestamp.Designer.cs
@@ -0,0 +1,1275 @@
+//
+using System;
+using System.Collections.Generic;
+using Kyoo.Abstractions.Models;
+using Kyoo.Postgresql;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace Kyoo.Postgresql.Migrations
+{
+ [DbContext(typeof(PostgresContext))]
+ [Migration("20230726100747_Timestamp")]
+ partial class Timestamp
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.9")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "item_type", new[] { "show", "movie", "collection" });
+ NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "status", new[] { "unknown", "finished", "airing", "planned" });
+ NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "stream_type", new[] { "unknown", "video", "audio", "subtitle" });
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.Collection", b =>
+ {
+ b.Property("ID")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
+
+ b.Property>("Images")
+ .HasColumnType("jsonb")
+ .HasColumnName("images");
+
+ b.Property("Name")
+ .HasColumnType("text")
+ .HasColumnName("name");
+
+ b.Property("Overview")
+ .HasColumnType("text")
+ .HasColumnName("overview");
+
+ b.Property("Slug")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("slug");
+
+ b.HasKey("ID")
+ .HasName("pk_collections");
+
+ b.HasIndex("Slug")
+ .IsUnique()
+ .HasDatabaseName("ix_collections_slug");
+
+ b.ToTable("collections", (string)null);
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.Episode", b =>
+ {
+ b.Property("ID")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
+
+ b.Property("AbsoluteNumber")
+ .HasColumnType("integer")
+ .HasColumnName("absolute_number");
+
+ b.Property("EpisodeNumber")
+ .HasColumnType("integer")
+ .HasColumnName("episode_number");
+
+ b.Property>("Images")
+ .HasColumnType("jsonb")
+ .HasColumnName("images");
+
+ b.Property("Overview")
+ .HasColumnType("text")
+ .HasColumnName("overview");
+
+ b.Property("Path")
+ .HasColumnType("text")
+ .HasColumnName("path");
+
+ b.Property("ReleaseDate")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("release_date");
+
+ b.Property("SeasonID")
+ .HasColumnType("integer")
+ .HasColumnName("season_id");
+
+ b.Property("SeasonNumber")
+ .HasColumnType("integer")
+ .HasColumnName("season_number");
+
+ b.Property("ShowID")
+ .HasColumnType("integer")
+ .HasColumnName("show_id");
+
+ b.Property("Slug")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("slug");
+
+ b.Property("Title")
+ .HasColumnType("text")
+ .HasColumnName("title");
+
+ b.HasKey("ID")
+ .HasName("pk_episodes");
+
+ b.HasIndex("SeasonID")
+ .HasDatabaseName("ix_episodes_season_id");
+
+ b.HasIndex("Slug")
+ .IsUnique()
+ .HasDatabaseName("ix_episodes_slug");
+
+ b.HasIndex("ShowID", "SeasonNumber", "EpisodeNumber", "AbsoluteNumber")
+ .IsUnique()
+ .HasDatabaseName("ix_episodes_show_id_season_number_episode_number_absolute_numb");
+
+ b.ToTable("episodes", (string)null);
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.Genre", b =>
+ {
+ b.Property("ID")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
+
+ b.Property("Name")
+ .HasColumnType("text")
+ .HasColumnName("name");
+
+ b.Property("Slug")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("slug");
+
+ b.HasKey("ID")
+ .HasName("pk_genres");
+
+ b.HasIndex("Slug")
+ .IsUnique()
+ .HasDatabaseName("ix_genres_slug");
+
+ b.ToTable("genres", (string)null);
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.Library", b =>
+ {
+ b.Property("ID")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
+
+ b.Property("Name")
+ .HasColumnType("text")
+ .HasColumnName("name");
+
+ b.Property("Paths")
+ .HasColumnType("text[]")
+ .HasColumnName("paths");
+
+ b.Property("Slug")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("slug");
+
+ b.HasKey("ID")
+ .HasName("pk_libraries");
+
+ b.HasIndex("Slug")
+ .IsUnique()
+ .HasDatabaseName("ix_libraries_slug");
+
+ b.ToTable("libraries", (string)null);
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.LibraryItem", b =>
+ {
+ b.Property("ID")
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ b.Property("EndAir")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("end_air");
+
+ b.Property>("Images")
+ .HasColumnType("jsonb")
+ .HasColumnName("images");
+
+ b.Property("Overview")
+ .HasColumnType("text")
+ .HasColumnName("overview");
+
+ b.Property("Slug")
+ .HasColumnType("text")
+ .HasColumnName("slug");
+
+ b.Property("StartAir")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("start_air");
+
+ b.Property("Status")
+ .HasColumnType("status")
+ .HasColumnName("status");
+
+ b.Property("Title")
+ .HasColumnType("text")
+ .HasColumnName("title");
+
+ b.Property("Type")
+ .HasColumnType("item_type")
+ .HasColumnName("type");
+
+ b.HasKey("ID")
+ .HasName("pk_library_items");
+
+ b.ToTable((string)null);
+
+ b.ToView("library_items", (string)null);
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.People", b =>
+ {
+ b.Property("ID")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
+
+ b.Property>("Images")
+ .HasColumnType("jsonb")
+ .HasColumnName("images");
+
+ b.Property("Name")
+ .HasColumnType("text")
+ .HasColumnName("name");
+
+ b.Property("Slug")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("slug");
+
+ b.HasKey("ID")
+ .HasName("pk_people");
+
+ b.HasIndex("Slug")
+ .IsUnique()
+ .HasDatabaseName("ix_people_slug");
+
+ b.ToTable("people", (string)null);
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.PeopleRole", b =>
+ {
+ b.Property("ID")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
+
+ b.Property("PeopleID")
+ .HasColumnType("integer")
+ .HasColumnName("people_id");
+
+ b.Property("Role")
+ .HasColumnType("text")
+ .HasColumnName("role");
+
+ b.Property("ShowID")
+ .HasColumnType("integer")
+ .HasColumnName("show_id");
+
+ b.Property("Type")
+ .HasColumnType("text")
+ .HasColumnName("type");
+
+ b.HasKey("ID")
+ .HasName("pk_people_roles");
+
+ b.HasIndex("PeopleID")
+ .HasDatabaseName("ix_people_roles_people_id");
+
+ b.HasIndex("ShowID")
+ .HasDatabaseName("ix_people_roles_show_id");
+
+ b.ToTable("people_roles", (string)null);
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.Provider", b =>
+ {
+ b.Property("ID")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
+
+ b.Property>("Images")
+ .HasColumnType("jsonb")
+ .HasColumnName("images");
+
+ b.Property("Name")
+ .HasColumnType("text")
+ .HasColumnName("name");
+
+ b.Property("Slug")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("slug");
+
+ b.HasKey("ID")
+ .HasName("pk_providers");
+
+ b.HasIndex("Slug")
+ .IsUnique()
+ .HasDatabaseName("ix_providers_slug");
+
+ b.ToTable("providers", (string)null);
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.Season", b =>
+ {
+ b.Property("ID")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
+
+ b.Property("EndDate")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("end_date");
+
+ b.Property>("Images")
+ .HasColumnType("jsonb")
+ .HasColumnName("images");
+
+ b.Property("Overview")
+ .HasColumnType("text")
+ .HasColumnName("overview");
+
+ b.Property("SeasonNumber")
+ .HasColumnType("integer")
+ .HasColumnName("season_number");
+
+ b.Property("ShowID")
+ .HasColumnType("integer")
+ .HasColumnName("show_id");
+
+ b.Property("Slug")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("slug");
+
+ b.Property("StartDate")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("start_date");
+
+ b.Property("Title")
+ .HasColumnType("text")
+ .HasColumnName("title");
+
+ b.HasKey("ID")
+ .HasName("pk_seasons");
+
+ b.HasIndex("Slug")
+ .IsUnique()
+ .HasDatabaseName("ix_seasons_slug");
+
+ b.HasIndex("ShowID", "SeasonNumber")
+ .IsUnique()
+ .HasDatabaseName("ix_seasons_show_id_season_number");
+
+ b.ToTable("seasons", (string)null);
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.Show", b =>
+ {
+ b.Property("ID")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
+
+ b.Property("Aliases")
+ .HasColumnType("text[]")
+ .HasColumnName("aliases");
+
+ b.Property("EndAir")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("end_air");
+
+ b.Property>("Images")
+ .HasColumnType("jsonb")
+ .HasColumnName("images");
+
+ b.Property("IsMovie")
+ .HasColumnType("boolean")
+ .HasColumnName("is_movie");
+
+ b.Property("Overview")
+ .HasColumnType("text")
+ .HasColumnName("overview");
+
+ b.Property("Path")
+ .HasColumnType("text")
+ .HasColumnName("path");
+
+ b.Property("Slug")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("slug");
+
+ b.Property("StartAir")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("start_air");
+
+ b.Property("Status")
+ .HasColumnType("status")
+ .HasColumnName("status");
+
+ b.Property("StudioID")
+ .HasColumnType("integer")
+ .HasColumnName("studio_id");
+
+ b.Property("Title")
+ .HasColumnType("text")
+ .HasColumnName("title");
+
+ b.HasKey("ID")
+ .HasName("pk_shows");
+
+ b.HasIndex("Slug")
+ .IsUnique()
+ .HasDatabaseName("ix_shows_slug");
+
+ b.HasIndex("StudioID")
+ .HasDatabaseName("ix_shows_studio_id");
+
+ b.ToTable("shows", (string)null);
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.Studio", b =>
+ {
+ b.Property("ID")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
+
+ b.Property("Name")
+ .HasColumnType("text")
+ .HasColumnName("name");
+
+ b.Property("Slug")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("slug");
+
+ b.HasKey("ID")
+ .HasName("pk_studios");
+
+ b.HasIndex("Slug")
+ .IsUnique()
+ .HasDatabaseName("ix_studios_slug");
+
+ b.ToTable("studios", (string)null);
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.Track", b =>
+ {
+ b.Property("ID")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
+
+ b.Property("Codec")
+ .HasColumnType("text")
+ .HasColumnName("codec");
+
+ b.Property("EpisodeID")
+ .HasColumnType("integer")
+ .HasColumnName("episode_id");
+
+ b.Property("IsDefault")
+ .HasColumnType("boolean")
+ .HasColumnName("is_default");
+
+ b.Property("IsExternal")
+ .HasColumnType("boolean")
+ .HasColumnName("is_external");
+
+ b.Property("IsForced")
+ .HasColumnType("boolean")
+ .HasColumnName("is_forced");
+
+ b.Property("Language")
+ .HasColumnType("text")
+ .HasColumnName("language");
+
+ b.Property("Path")
+ .HasColumnType("text")
+ .HasColumnName("path");
+
+ b.Property("Slug")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("slug");
+
+ b.Property("Title")
+ .HasColumnType("text")
+ .HasColumnName("title");
+
+ b.Property("TrackIndex")
+ .HasColumnType("integer")
+ .HasColumnName("track_index");
+
+ b.Property("Type")
+ .HasColumnType("stream_type")
+ .HasColumnName("type");
+
+ b.HasKey("ID")
+ .HasName("pk_tracks");
+
+ b.HasIndex("Slug")
+ .IsUnique()
+ .HasDatabaseName("ix_tracks_slug");
+
+ b.HasIndex("EpisodeID", "Type", "Language", "TrackIndex", "IsForced")
+ .IsUnique()
+ .HasDatabaseName("ix_tracks_episode_id_type_language_track_index_is_forced");
+
+ b.ToTable("tracks", (string)null);
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.User", b =>
+ {
+ b.Property("ID")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
+
+ b.Property("Email")
+ .HasColumnType("text")
+ .HasColumnName("email");
+
+ b.Property>("ExtraData")
+ .HasColumnType("jsonb")
+ .HasColumnName("extra_data");
+
+ b.Property>("Images")
+ .HasColumnType("jsonb")
+ .HasColumnName("images");
+
+ b.Property("Password")
+ .HasColumnType("text")
+ .HasColumnName("password");
+
+ b.Property("Permissions")
+ .HasColumnType("text[]")
+ .HasColumnName("permissions");
+
+ b.Property("Slug")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("slug");
+
+ b.Property("Username")
+ .HasColumnType("text")
+ .HasColumnName("username");
+
+ b.HasKey("ID")
+ .HasName("pk_users");
+
+ b.HasIndex("Slug")
+ .IsUnique()
+ .HasDatabaseName("ix_users_slug");
+
+ b.ToTable("users", (string)null);
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.WatchedEpisode", b =>
+ {
+ b.Property("UserID")
+ .HasColumnType("integer")
+ .HasColumnName("user_id");
+
+ b.Property("EpisodeID")
+ .HasColumnType("integer")
+ .HasColumnName("episode_id");
+
+ b.Property("WatchedPercentage")
+ .HasColumnType("integer")
+ .HasColumnName("watched_percentage");
+
+ b.HasKey("UserID", "EpisodeID")
+ .HasName("pk_watched_episodes");
+
+ b.HasIndex("EpisodeID")
+ .HasDatabaseName("ix_watched_episodes_episode_id");
+
+ b.ToTable("watched_episodes", (string)null);
+ });
+
+ modelBuilder.Entity("ShowUser", b =>
+ {
+ b.Property("UsersID")
+ .HasColumnType("integer")
+ .HasColumnName("users_id");
+
+ b.Property("WatchedID")
+ .HasColumnType("integer")
+ .HasColumnName("watched_id");
+
+ b.HasKey("UsersID", "WatchedID")
+ .HasName("pk_link_user_show");
+
+ b.HasIndex("WatchedID")
+ .HasDatabaseName("ix_link_user_show_watched_id");
+
+ b.ToTable("link_user_show", (string)null);
+ });
+
+ modelBuilder.Entity("collection_metadata_id", b =>
+ {
+ b.Property("ResourceID")
+ .HasColumnType("integer")
+ .HasColumnName("resource_id");
+
+ b.Property("ProviderID")
+ .HasColumnType("integer")
+ .HasColumnName("provider_id");
+
+ b.Property("DataID")
+ .HasColumnType("text")
+ .HasColumnName("data_id");
+
+ b.Property("Link")
+ .HasColumnType("text")
+ .HasColumnName("link");
+
+ b.HasKey("ResourceID", "ProviderID")
+ .HasName("pk_collection_metadata_id");
+
+ b.HasIndex("ProviderID")
+ .HasDatabaseName("ix_collection_metadata_id_provider_id");
+
+ b.ToTable("collection_metadata_id", (string)null);
+ });
+
+ modelBuilder.Entity("episode_metadata_id", b =>
+ {
+ b.Property("ResourceID")
+ .HasColumnType("integer")
+ .HasColumnName("resource_id");
+
+ b.Property("ProviderID")
+ .HasColumnType("integer")
+ .HasColumnName("provider_id");
+
+ b.Property("DataID")
+ .HasColumnType("text")
+ .HasColumnName("data_id");
+
+ b.Property("Link")
+ .HasColumnType("text")
+ .HasColumnName("link");
+
+ b.HasKey("ResourceID", "ProviderID")
+ .HasName("pk_episode_metadata_id");
+
+ b.HasIndex("ProviderID")
+ .HasDatabaseName("ix_episode_metadata_id_provider_id");
+
+ b.ToTable("episode_metadata_id", (string)null);
+ });
+
+ modelBuilder.Entity("link_collection_show", b =>
+ {
+ b.Property("collection_id")
+ .HasColumnType("integer")
+ .HasColumnName("collection_id");
+
+ b.Property("show_id")
+ .HasColumnType("integer")
+ .HasColumnName("show_id");
+
+ b.HasKey("collection_id", "show_id")
+ .HasName("pk_link_collection_show");
+
+ b.HasIndex("show_id")
+ .HasDatabaseName("ix_link_collection_show_show_id");
+
+ b.ToTable("link_collection_show", (string)null);
+ });
+
+ modelBuilder.Entity("link_library_collection", b =>
+ {
+ b.Property("collection_id")
+ .HasColumnType("integer")
+ .HasColumnName("collection_id");
+
+ b.Property("library_id")
+ .HasColumnType("integer")
+ .HasColumnName("library_id");
+
+ b.HasKey("collection_id", "library_id")
+ .HasName("pk_link_library_collection");
+
+ b.HasIndex("library_id")
+ .HasDatabaseName("ix_link_library_collection_library_id");
+
+ b.ToTable("link_library_collection", (string)null);
+ });
+
+ modelBuilder.Entity("link_library_provider", b =>
+ {
+ b.Property("library_id")
+ .HasColumnType("integer")
+ .HasColumnName("library_id");
+
+ b.Property("provider_id")
+ .HasColumnType("integer")
+ .HasColumnName("provider_id");
+
+ b.HasKey("library_id", "provider_id")
+ .HasName("pk_link_library_provider");
+
+ b.HasIndex("provider_id")
+ .HasDatabaseName("ix_link_library_provider_provider_id");
+
+ b.ToTable("link_library_provider", (string)null);
+ });
+
+ modelBuilder.Entity("link_library_show", b =>
+ {
+ b.Property("library_id")
+ .HasColumnType("integer")
+ .HasColumnName("library_id");
+
+ b.Property("show_id")
+ .HasColumnType("integer")
+ .HasColumnName("show_id");
+
+ b.HasKey("library_id", "show_id")
+ .HasName("pk_link_library_show");
+
+ b.HasIndex("show_id")
+ .HasDatabaseName("ix_link_library_show_show_id");
+
+ b.ToTable("link_library_show", (string)null);
+ });
+
+ modelBuilder.Entity("link_show_genre", b =>
+ {
+ b.Property("genre_id")
+ .HasColumnType("integer")
+ .HasColumnName("genre_id");
+
+ b.Property("show_id")
+ .HasColumnType("integer")
+ .HasColumnName("show_id");
+
+ b.HasKey("genre_id", "show_id")
+ .HasName("pk_link_show_genre");
+
+ b.HasIndex("show_id")
+ .HasDatabaseName("ix_link_show_genre_show_id");
+
+ b.ToTable("link_show_genre", (string)null);
+ });
+
+ modelBuilder.Entity("people_metadata_id", b =>
+ {
+ b.Property("ResourceID")
+ .HasColumnType("integer")
+ .HasColumnName("resource_id");
+
+ b.Property("ProviderID")
+ .HasColumnType("integer")
+ .HasColumnName("provider_id");
+
+ b.Property("DataID")
+ .HasColumnType("text")
+ .HasColumnName("data_id");
+
+ b.Property("Link")
+ .HasColumnType("text")
+ .HasColumnName("link");
+
+ b.HasKey("ResourceID", "ProviderID")
+ .HasName("pk_people_metadata_id");
+
+ b.HasIndex("ProviderID")
+ .HasDatabaseName("ix_people_metadata_id_provider_id");
+
+ b.ToTable("people_metadata_id", (string)null);
+ });
+
+ modelBuilder.Entity("season_metadata_id", b =>
+ {
+ b.Property("ResourceID")
+ .HasColumnType("integer")
+ .HasColumnName("resource_id");
+
+ b.Property("ProviderID")
+ .HasColumnType("integer")
+ .HasColumnName("provider_id");
+
+ b.Property("DataID")
+ .HasColumnType("text")
+ .HasColumnName("data_id");
+
+ b.Property("Link")
+ .HasColumnType("text")
+ .HasColumnName("link");
+
+ b.HasKey("ResourceID", "ProviderID")
+ .HasName("pk_season_metadata_id");
+
+ b.HasIndex("ProviderID")
+ .HasDatabaseName("ix_season_metadata_id_provider_id");
+
+ b.ToTable("season_metadata_id", (string)null);
+ });
+
+ modelBuilder.Entity("show_metadata_id", b =>
+ {
+ b.Property("ResourceID")
+ .HasColumnType("integer")
+ .HasColumnName("resource_id");
+
+ b.Property("ProviderID")
+ .HasColumnType("integer")
+ .HasColumnName("provider_id");
+
+ b.Property("DataID")
+ .HasColumnType("text")
+ .HasColumnName("data_id");
+
+ b.Property("Link")
+ .HasColumnType("text")
+ .HasColumnName("link");
+
+ b.HasKey("ResourceID", "ProviderID")
+ .HasName("pk_show_metadata_id");
+
+ b.HasIndex("ProviderID")
+ .HasDatabaseName("ix_show_metadata_id_provider_id");
+
+ b.ToTable("show_metadata_id", (string)null);
+ });
+
+ modelBuilder.Entity("studio_metadata_id", b =>
+ {
+ b.Property("ResourceID")
+ .HasColumnType("integer")
+ .HasColumnName("resource_id");
+
+ b.Property("ProviderID")
+ .HasColumnType("integer")
+ .HasColumnName("provider_id");
+
+ b.Property("DataID")
+ .HasColumnType("text")
+ .HasColumnName("data_id");
+
+ b.Property("Link")
+ .HasColumnType("text")
+ .HasColumnName("link");
+
+ b.HasKey("ResourceID", "ProviderID")
+ .HasName("pk_studio_metadata_id");
+
+ b.HasIndex("ProviderID")
+ .HasDatabaseName("ix_studio_metadata_id_provider_id");
+
+ b.ToTable("studio_metadata_id", (string)null);
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.Episode", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.Season", "Season")
+ .WithMany("Episodes")
+ .HasForeignKey("SeasonID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .HasConstraintName("fk_episodes_seasons_season_id");
+
+ b.HasOne("Kyoo.Abstractions.Models.Show", "Show")
+ .WithMany("Episodes")
+ .HasForeignKey("ShowID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_episodes_shows_show_id");
+
+ b.Navigation("Season");
+
+ b.Navigation("Show");
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.PeopleRole", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.People", "People")
+ .WithMany("Roles")
+ .HasForeignKey("PeopleID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_people_roles_people_people_id");
+
+ b.HasOne("Kyoo.Abstractions.Models.Show", "Show")
+ .WithMany("People")
+ .HasForeignKey("ShowID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_people_roles_shows_show_id");
+
+ b.Navigation("People");
+
+ b.Navigation("Show");
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.Season", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.Show", "Show")
+ .WithMany("Seasons")
+ .HasForeignKey("ShowID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_seasons_shows_show_id");
+
+ b.Navigation("Show");
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.Show", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.Studio", "Studio")
+ .WithMany("Shows")
+ .HasForeignKey("StudioID")
+ .OnDelete(DeleteBehavior.SetNull)
+ .HasConstraintName("fk_shows_studios_studio_id");
+
+ b.Navigation("Studio");
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.Track", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.Episode", "Episode")
+ .WithMany("Tracks")
+ .HasForeignKey("EpisodeID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_tracks_episodes_episode_id");
+
+ b.Navigation("Episode");
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.WatchedEpisode", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.Episode", "Episode")
+ .WithMany()
+ .HasForeignKey("EpisodeID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_watched_episodes_episodes_episode_id");
+
+ b.HasOne("Kyoo.Abstractions.Models.User", null)
+ .WithMany("CurrentlyWatching")
+ .HasForeignKey("UserID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_watched_episodes_users_user_id");
+
+ b.Navigation("Episode");
+ });
+
+ modelBuilder.Entity("ShowUser", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_link_user_show_users_users_id");
+
+ b.HasOne("Kyoo.Abstractions.Models.Show", null)
+ .WithMany()
+ .HasForeignKey("WatchedID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_link_user_show_shows_watched_id");
+ });
+
+ modelBuilder.Entity("collection_metadata_id", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.Provider", "Provider")
+ .WithMany()
+ .HasForeignKey("ProviderID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_collection_metadata_id_providers_provider_id");
+
+ b.HasOne("Kyoo.Abstractions.Models.Collection", null)
+ .WithMany("ExternalIDs")
+ .HasForeignKey("ResourceID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_collection_metadata_id_collections_collection_id");
+
+ b.Navigation("Provider");
+ });
+
+ modelBuilder.Entity("episode_metadata_id", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.Provider", "Provider")
+ .WithMany()
+ .HasForeignKey("ProviderID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_episode_metadata_id_providers_provider_id");
+
+ b.HasOne("Kyoo.Abstractions.Models.Episode", null)
+ .WithMany("ExternalIDs")
+ .HasForeignKey("ResourceID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_episode_metadata_id_episodes_episode_id");
+
+ b.Navigation("Provider");
+ });
+
+ modelBuilder.Entity("link_collection_show", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.Collection", null)
+ .WithMany()
+ .HasForeignKey("collection_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_link_collection_show_collections_collection_id");
+
+ b.HasOne("Kyoo.Abstractions.Models.Show", null)
+ .WithMany()
+ .HasForeignKey("show_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_link_collection_show_shows_show_id");
+ });
+
+ modelBuilder.Entity("link_library_collection", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.Collection", null)
+ .WithMany()
+ .HasForeignKey("collection_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_link_library_collection_collections_collection_id");
+
+ b.HasOne("Kyoo.Abstractions.Models.Library", null)
+ .WithMany()
+ .HasForeignKey("library_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_link_library_collection_libraries_library_id");
+ });
+
+ modelBuilder.Entity("link_library_provider", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.Library", null)
+ .WithMany()
+ .HasForeignKey("library_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_link_library_provider_libraries_library_id");
+
+ b.HasOne("Kyoo.Abstractions.Models.Provider", null)
+ .WithMany()
+ .HasForeignKey("provider_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_link_library_provider_providers_provider_id");
+ });
+
+ modelBuilder.Entity("link_library_show", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.Library", null)
+ .WithMany()
+ .HasForeignKey("library_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_link_library_show_libraries_library_id");
+
+ b.HasOne("Kyoo.Abstractions.Models.Show", null)
+ .WithMany()
+ .HasForeignKey("show_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_link_library_show_shows_show_id");
+ });
+
+ modelBuilder.Entity("link_show_genre", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.Genre", null)
+ .WithMany()
+ .HasForeignKey("genre_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_link_show_genre_genres_genre_id");
+
+ b.HasOne("Kyoo.Abstractions.Models.Show", null)
+ .WithMany()
+ .HasForeignKey("show_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_link_show_genre_shows_show_id");
+ });
+
+ modelBuilder.Entity("people_metadata_id", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.Provider", "Provider")
+ .WithMany()
+ .HasForeignKey("ProviderID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_people_metadata_id_providers_provider_id");
+
+ b.HasOne("Kyoo.Abstractions.Models.People", null)
+ .WithMany("ExternalIDs")
+ .HasForeignKey("ResourceID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_people_metadata_id_people_people_id");
+
+ b.Navigation("Provider");
+ });
+
+ modelBuilder.Entity("season_metadata_id", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.Provider", "Provider")
+ .WithMany()
+ .HasForeignKey("ProviderID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_season_metadata_id_providers_provider_id");
+
+ b.HasOne("Kyoo.Abstractions.Models.Season", null)
+ .WithMany("ExternalIDs")
+ .HasForeignKey("ResourceID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_season_metadata_id_seasons_season_id");
+
+ b.Navigation("Provider");
+ });
+
+ modelBuilder.Entity("show_metadata_id", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.Provider", "Provider")
+ .WithMany()
+ .HasForeignKey("ProviderID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_show_metadata_id_providers_provider_id");
+
+ b.HasOne("Kyoo.Abstractions.Models.Show", null)
+ .WithMany("ExternalIDs")
+ .HasForeignKey("ResourceID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_show_metadata_id_shows_show_id");
+
+ b.Navigation("Provider");
+ });
+
+ modelBuilder.Entity("studio_metadata_id", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.Provider", "Provider")
+ .WithMany()
+ .HasForeignKey("ProviderID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_studio_metadata_id_providers_provider_id");
+
+ b.HasOne("Kyoo.Abstractions.Models.Studio", null)
+ .WithMany("ExternalIDs")
+ .HasForeignKey("ResourceID")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_studio_metadata_id_studios_studio_id");
+
+ b.Navigation("Provider");
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.Collection", b =>
+ {
+ b.Navigation("ExternalIDs");
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.Episode", b =>
+ {
+ b.Navigation("ExternalIDs");
+
+ b.Navigation("Tracks");
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.People", b =>
+ {
+ b.Navigation("ExternalIDs");
+
+ b.Navigation("Roles");
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.Season", b =>
+ {
+ b.Navigation("Episodes");
+
+ b.Navigation("ExternalIDs");
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.Show", b =>
+ {
+ b.Navigation("Episodes");
+
+ b.Navigation("ExternalIDs");
+
+ b.Navigation("People");
+
+ b.Navigation("Seasons");
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.Studio", b =>
+ {
+ b.Navigation("ExternalIDs");
+
+ b.Navigation("Shows");
+ });
+
+ modelBuilder.Entity("Kyoo.Abstractions.Models.User", b =>
+ {
+ b.Navigation("CurrentlyWatching");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/back/src/Kyoo.Postgresql/Migrations/20230726100747_Timestamp.cs b/back/src/Kyoo.Postgresql/Migrations/20230726100747_Timestamp.cs
new file mode 100644
index 00000000..804af4f2
--- /dev/null
+++ b/back/src/Kyoo.Postgresql/Migrations/20230726100747_Timestamp.cs
@@ -0,0 +1,135 @@
+// Kyoo - A portable and vast media library solution.
+// Copyright (c) Kyoo.
+//
+// See AUTHORS.md and LICENSE file in the project root for full license information.
+//
+// Kyoo is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// Kyoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Kyoo. If not, see .
+
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Kyoo.Postgresql.Migrations
+{
+ ///
+ public partial class Timestamp : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ MigrationHelper.DropLibraryItemsView(migrationBuilder);
+
+ migrationBuilder.AlterColumn(
+ name: "start_air",
+ table: "shows",
+ type: "timestamp with time zone",
+ nullable: true,
+ oldClrType: typeof(DateTime),
+ oldType: "timestamp without time zone",
+ oldNullable: true);
+
+ migrationBuilder.AlterColumn(
+ name: "end_air",
+ table: "shows",
+ type: "timestamp with time zone",
+ nullable: true,
+ oldClrType: typeof(DateTime),
+ oldType: "timestamp without time zone",
+ oldNullable: true);
+
+ migrationBuilder.AlterColumn(
+ name: "start_date",
+ table: "seasons",
+ type: "timestamp with time zone",
+ nullable: true,
+ oldClrType: typeof(DateTime),
+ oldType: "timestamp without time zone",
+ oldNullable: true);
+
+ migrationBuilder.AlterColumn(
+ name: "end_date",
+ table: "seasons",
+ type: "timestamp with time zone",
+ nullable: true,
+ oldClrType: typeof(DateTime),
+ oldType: "timestamp without time zone",
+ oldNullable: true);
+
+ migrationBuilder.AlterColumn(
+ name: "release_date",
+ table: "episodes",
+ type: "timestamp with time zone",
+ nullable: true,
+ oldClrType: typeof(DateTime),
+ oldType: "timestamp without time zone",
+ oldNullable: true);
+
+ MigrationHelper.CreateLibraryItemsView(migrationBuilder);
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ MigrationHelper.DropLibraryItemsView(migrationBuilder);
+
+ migrationBuilder.AlterColumn(
+ name: "start_air",
+ table: "shows",
+ type: "timestamp without time zone",
+ nullable: true,
+ oldClrType: typeof(DateTime),
+ oldType: "timestamp with time zone",
+ oldNullable: true);
+
+ migrationBuilder.AlterColumn(
+ name: "end_air",
+ table: "shows",
+ type: "timestamp without time zone",
+ nullable: true,
+ oldClrType: typeof(DateTime),
+ oldType: "timestamp with time zone",
+ oldNullable: true);
+
+ migrationBuilder.AlterColumn(
+ name: "start_date",
+ table: "seasons",
+ type: "timestamp without time zone",
+ nullable: true,
+ oldClrType: typeof(DateTime),
+ oldType: "timestamp with time zone",
+ oldNullable: true);
+
+ migrationBuilder.AlterColumn(
+ name: "end_date",
+ table: "seasons",
+ type: "timestamp without time zone",
+ nullable: true,
+ oldClrType: typeof(DateTime),
+ oldType: "timestamp with time zone",
+ oldNullable: true);
+
+ migrationBuilder.AlterColumn(
+ name: "release_date",
+ table: "episodes",
+ type: "timestamp without time zone",
+ nullable: true,
+ oldClrType: typeof(DateTime),
+ oldType: "timestamp with time zone",
+ oldNullable: true);
+
+ MigrationHelper.CreateLibraryItemsView(migrationBuilder);
+ }
+ }
+}
diff --git a/back/src/Kyoo.Postgresql/Migrations/PostgresContextModelSnapshot.cs b/back/src/Kyoo.Postgresql/Migrations/PostgresContextModelSnapshot.cs
index 92dfd929..4a5cca16 100644
--- a/back/src/Kyoo.Postgresql/Migrations/PostgresContextModelSnapshot.cs
+++ b/back/src/Kyoo.Postgresql/Migrations/PostgresContextModelSnapshot.cs
@@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+#nullable disable
+
namespace Kyoo.Postgresql.Migrations
{
[DbContext(typeof(PostgresContext))]
@@ -17,20 +19,22 @@ namespace Kyoo.Postgresql.Migrations
{
#pragma warning disable 612, 618
modelBuilder
- .HasPostgresEnum(null, "item_type", new[] { "show", "movie", "collection" })
- .HasPostgresEnum(null, "status", new[] { "unknown", "finished", "airing", "planned" })
- .HasPostgresEnum(null, "stream_type", new[] { "unknown", "video", "audio", "subtitle" })
- .HasAnnotation("Relational:MaxIdentifierLength", 63)
- .HasAnnotation("ProductVersion", "5.0.7")
- .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+ .HasAnnotation("ProductVersion", "7.0.9")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "item_type", new[] { "show", "movie", "collection" });
+ NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "status", new[] { "unknown", "finished", "airing", "planned" });
+ NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "stream_type", new[] { "unknown", "video", "audio", "subtitle" });
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Kyoo.Abstractions.Models.Collection", b =>
{
b.Property("ID")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
- .HasColumnName("id")
- .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
b.Property>("Images")
.HasColumnType("jsonb")
@@ -56,7 +60,7 @@ namespace Kyoo.Postgresql.Migrations
.IsUnique()
.HasDatabaseName("ix_collections_slug");
- b.ToTable("collections");
+ b.ToTable("collections", (string)null);
});
modelBuilder.Entity("Kyoo.Abstractions.Models.Episode", b =>
@@ -64,8 +68,9 @@ namespace Kyoo.Postgresql.Migrations
b.Property("ID")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
- .HasColumnName("id")
- .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
b.Property("AbsoluteNumber")
.HasColumnType("integer")
@@ -88,7 +93,7 @@ namespace Kyoo.Postgresql.Migrations
.HasColumnName("path");
b.Property("ReleaseDate")
- .HasColumnType("timestamp without time zone")
+ .HasColumnType("timestamp with time zone")
.HasColumnName("release_date");
b.Property("SeasonID")
@@ -126,7 +131,7 @@ namespace Kyoo.Postgresql.Migrations
.IsUnique()
.HasDatabaseName("ix_episodes_show_id_season_number_episode_number_absolute_numb");
- b.ToTable("episodes");
+ b.ToTable("episodes", (string)null);
});
modelBuilder.Entity("Kyoo.Abstractions.Models.Genre", b =>
@@ -134,8 +139,9 @@ namespace Kyoo.Postgresql.Migrations
b.Property("ID")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
- .HasColumnName("id")
- .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
b.Property("Name")
.HasColumnType("text")
@@ -153,7 +159,7 @@ namespace Kyoo.Postgresql.Migrations
.IsUnique()
.HasDatabaseName("ix_genres_slug");
- b.ToTable("genres");
+ b.ToTable("genres", (string)null);
});
modelBuilder.Entity("Kyoo.Abstractions.Models.Library", b =>
@@ -161,8 +167,9 @@ namespace Kyoo.Postgresql.Migrations
b.Property("ID")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
- .HasColumnName("id")
- .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
b.Property("Name")
.HasColumnType("text")
@@ -184,18 +191,17 @@ namespace Kyoo.Postgresql.Migrations
.IsUnique()
.HasDatabaseName("ix_libraries_slug");
- b.ToTable("libraries");
+ b.ToTable("libraries", (string)null);
});
modelBuilder.Entity("Kyoo.Abstractions.Models.LibraryItem", b =>
{
b.Property("ID")
.HasColumnType("integer")
- .HasColumnName("id")
- .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+ .HasColumnName("id");
b.Property("EndAir")
- .HasColumnType("timestamp without time zone")
+ .HasColumnType("timestamp with time zone")
.HasColumnName("end_air");
b.Property>("Images")
@@ -211,7 +217,7 @@ namespace Kyoo.Postgresql.Migrations
.HasColumnName("slug");
b.Property("StartAir")
- .HasColumnType("timestamp without time zone")
+ .HasColumnType("timestamp with time zone")
.HasColumnName("start_air");
b.Property("Status")
@@ -229,7 +235,9 @@ namespace Kyoo.Postgresql.Migrations
b.HasKey("ID")
.HasName("pk_library_items");
- b.ToView("library_items");
+ b.ToTable((string)null);
+
+ b.ToView("library_items", (string)null);
});
modelBuilder.Entity("Kyoo.Abstractions.Models.People", b =>
@@ -237,8 +245,9 @@ namespace Kyoo.Postgresql.Migrations
b.Property("ID")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
- .HasColumnName("id")
- .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
b.Property>("Images")
.HasColumnType("jsonb")
@@ -260,7 +269,7 @@ namespace Kyoo.Postgresql.Migrations
.IsUnique()
.HasDatabaseName("ix_people_slug");
- b.ToTable("people");
+ b.ToTable("people", (string)null);
});
modelBuilder.Entity("Kyoo.Abstractions.Models.PeopleRole", b =>
@@ -268,8 +277,9 @@ namespace Kyoo.Postgresql.Migrations
b.Property("ID")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
- .HasColumnName("id")
- .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
b.Property("PeopleID")
.HasColumnType("integer")
@@ -296,7 +306,7 @@ namespace Kyoo.Postgresql.Migrations
b.HasIndex("ShowID")
.HasDatabaseName("ix_people_roles_show_id");
- b.ToTable("people_roles");
+ b.ToTable("people_roles", (string)null);
});
modelBuilder.Entity("Kyoo.Abstractions.Models.Provider", b =>
@@ -304,8 +314,9 @@ namespace Kyoo.Postgresql.Migrations
b.Property("ID")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
- .HasColumnName("id")
- .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
b.Property>("Images")
.HasColumnType("jsonb")
@@ -327,7 +338,7 @@ namespace Kyoo.Postgresql.Migrations
.IsUnique()
.HasDatabaseName("ix_providers_slug");
- b.ToTable("providers");
+ b.ToTable("providers", (string)null);
});
modelBuilder.Entity("Kyoo.Abstractions.Models.Season", b =>
@@ -335,11 +346,12 @@ namespace Kyoo.Postgresql.Migrations
b.Property("ID")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
- .HasColumnName("id")
- .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
b.Property("EndDate")
- .HasColumnType("timestamp without time zone")
+ .HasColumnType("timestamp with time zone")
.HasColumnName("end_date");
b.Property>("Images")
@@ -364,7 +376,7 @@ namespace Kyoo.Postgresql.Migrations
.HasColumnName("slug");
b.Property("StartDate")
- .HasColumnType("timestamp without time zone")
+ .HasColumnType("timestamp with time zone")
.HasColumnName("start_date");
b.Property("Title")
@@ -382,7 +394,7 @@ namespace Kyoo.Postgresql.Migrations
.IsUnique()
.HasDatabaseName("ix_seasons_show_id_season_number");
- b.ToTable("seasons");
+ b.ToTable("seasons", (string)null);
});
modelBuilder.Entity("Kyoo.Abstractions.Models.Show", b =>
@@ -390,15 +402,16 @@ namespace Kyoo.Postgresql.Migrations
b.Property("ID")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
- .HasColumnName("id")
- .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
b.Property("Aliases")
.HasColumnType("text[]")
.HasColumnName("aliases");
b.Property("EndAir")
- .HasColumnType("timestamp without time zone")
+ .HasColumnType("timestamp with time zone")
.HasColumnName("end_air");
b.Property>("Images")
@@ -423,7 +436,7 @@ namespace Kyoo.Postgresql.Migrations
.HasColumnName("slug");
b.Property("StartAir")
- .HasColumnType("timestamp without time zone")
+ .HasColumnType("timestamp with time zone")
.HasColumnName("start_air");
b.Property("Status")
@@ -448,7 +461,7 @@ namespace Kyoo.Postgresql.Migrations
b.HasIndex("StudioID")
.HasDatabaseName("ix_shows_studio_id");
- b.ToTable("shows");
+ b.ToTable("shows", (string)null);
});
modelBuilder.Entity("Kyoo.Abstractions.Models.Studio", b =>
@@ -456,8 +469,9 @@ namespace Kyoo.Postgresql.Migrations
b.Property("ID")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
- .HasColumnName("id")
- .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
b.Property("Name")
.HasColumnType("text")
@@ -475,7 +489,7 @@ namespace Kyoo.Postgresql.Migrations
.IsUnique()
.HasDatabaseName("ix_studios_slug");
- b.ToTable("studios");
+ b.ToTable("studios", (string)null);
});
modelBuilder.Entity("Kyoo.Abstractions.Models.Track", b =>
@@ -483,8 +497,9 @@ namespace Kyoo.Postgresql.Migrations
b.Property("ID")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
- .HasColumnName("id")
- .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
b.Property("Codec")
.HasColumnType("text")
@@ -542,7 +557,7 @@ namespace Kyoo.Postgresql.Migrations
.IsUnique()
.HasDatabaseName("ix_tracks_episode_id_type_language_track_index_is_forced");
- b.ToTable("tracks");
+ b.ToTable("tracks", (string)null);
});
modelBuilder.Entity("Kyoo.Abstractions.Models.User", b =>
@@ -550,8 +565,9 @@ namespace Kyoo.Postgresql.Migrations
b.Property("ID")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
- .HasColumnName("id")
- .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ID"));
b.Property("Email")
.HasColumnType("text")
@@ -589,7 +605,7 @@ namespace Kyoo.Postgresql.Migrations
.IsUnique()
.HasDatabaseName("ix_users_slug");
- b.ToTable("users");
+ b.ToTable("users", (string)null);
});
modelBuilder.Entity("Kyoo.Abstractions.Models.WatchedEpisode", b =>
@@ -612,7 +628,7 @@ namespace Kyoo.Postgresql.Migrations
b.HasIndex("EpisodeID")
.HasDatabaseName("ix_watched_episodes_episode_id");
- b.ToTable("watched_episodes");
+ b.ToTable("watched_episodes", (string)null);
});
modelBuilder.Entity("ShowUser", b =>
@@ -631,7 +647,7 @@ namespace Kyoo.Postgresql.Migrations
b.HasIndex("WatchedID")
.HasDatabaseName("ix_link_user_show_watched_id");
- b.ToTable("link_user_show");
+ b.ToTable("link_user_show", (string)null);
});
modelBuilder.Entity("collection_metadata_id", b =>
@@ -658,7 +674,7 @@ namespace Kyoo.Postgresql.Migrations
b.HasIndex("ProviderID")
.HasDatabaseName("ix_collection_metadata_id_provider_id");
- b.ToTable("collection_metadata_id");
+ b.ToTable("collection_metadata_id", (string)null);
});
modelBuilder.Entity("episode_metadata_id", b =>
@@ -685,7 +701,7 @@ namespace Kyoo.Postgresql.Migrations
b.HasIndex("ProviderID")
.HasDatabaseName("ix_episode_metadata_id_provider_id");
- b.ToTable("episode_metadata_id");
+ b.ToTable("episode_metadata_id", (string)null);
});
modelBuilder.Entity("link_collection_show", b =>
@@ -704,7 +720,7 @@ namespace Kyoo.Postgresql.Migrations
b.HasIndex("show_id")
.HasDatabaseName("ix_link_collection_show_show_id");
- b.ToTable("link_collection_show");
+ b.ToTable("link_collection_show", (string)null);
});
modelBuilder.Entity("link_library_collection", b =>
@@ -723,7 +739,7 @@ namespace Kyoo.Postgresql.Migrations
b.HasIndex("library_id")
.HasDatabaseName("ix_link_library_collection_library_id");
- b.ToTable("link_library_collection");
+ b.ToTable("link_library_collection", (string)null);
});
modelBuilder.Entity("link_library_provider", b =>
@@ -742,7 +758,7 @@ namespace Kyoo.Postgresql.Migrations
b.HasIndex("provider_id")
.HasDatabaseName("ix_link_library_provider_provider_id");
- b.ToTable("link_library_provider");
+ b.ToTable("link_library_provider", (string)null);
});
modelBuilder.Entity("link_library_show", b =>
@@ -761,7 +777,7 @@ namespace Kyoo.Postgresql.Migrations
b.HasIndex("show_id")
.HasDatabaseName("ix_link_library_show_show_id");
- b.ToTable("link_library_show");
+ b.ToTable("link_library_show", (string)null);
});
modelBuilder.Entity("link_show_genre", b =>
@@ -780,7 +796,7 @@ namespace Kyoo.Postgresql.Migrations
b.HasIndex("show_id")
.HasDatabaseName("ix_link_show_genre_show_id");
- b.ToTable("link_show_genre");
+ b.ToTable("link_show_genre", (string)null);
});
modelBuilder.Entity("people_metadata_id", b =>
@@ -807,7 +823,7 @@ namespace Kyoo.Postgresql.Migrations
b.HasIndex("ProviderID")
.HasDatabaseName("ix_people_metadata_id_provider_id");
- b.ToTable("people_metadata_id");
+ b.ToTable("people_metadata_id", (string)null);
});
modelBuilder.Entity("season_metadata_id", b =>
@@ -834,7 +850,7 @@ namespace Kyoo.Postgresql.Migrations
b.HasIndex("ProviderID")
.HasDatabaseName("ix_season_metadata_id_provider_id");
- b.ToTable("season_metadata_id");
+ b.ToTable("season_metadata_id", (string)null);
});
modelBuilder.Entity("show_metadata_id", b =>
@@ -861,7 +877,7 @@ namespace Kyoo.Postgresql.Migrations
b.HasIndex("ProviderID")
.HasDatabaseName("ix_show_metadata_id_provider_id");
- b.ToTable("show_metadata_id");
+ b.ToTable("show_metadata_id", (string)null);
});
modelBuilder.Entity("studio_metadata_id", b =>
@@ -888,7 +904,7 @@ namespace Kyoo.Postgresql.Migrations
b.HasIndex("ProviderID")
.HasDatabaseName("ix_studio_metadata_id_provider_id");
- b.ToTable("studio_metadata_id");
+ b.ToTable("studio_metadata_id", (string)null);
});
modelBuilder.Entity("Kyoo.Abstractions.Models.Episode", b =>
@@ -896,15 +912,15 @@ namespace Kyoo.Postgresql.Migrations
b.HasOne("Kyoo.Abstractions.Models.Season", "Season")
.WithMany("Episodes")
.HasForeignKey("SeasonID")
- .HasConstraintName("fk_episodes_seasons_season_id")
- .OnDelete(DeleteBehavior.Cascade);
+ .OnDelete(DeleteBehavior.Cascade)
+ .HasConstraintName("fk_episodes_seasons_season_id");
b.HasOne("Kyoo.Abstractions.Models.Show", "Show")
.WithMany("Episodes")
.HasForeignKey("ShowID")
- .HasConstraintName("fk_episodes_shows_show_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_episodes_shows_show_id");
b.Navigation("Season");
@@ -916,16 +932,16 @@ namespace Kyoo.Postgresql.Migrations
b.HasOne("Kyoo.Abstractions.Models.People", "People")
.WithMany("Roles")
.HasForeignKey("PeopleID")
- .HasConstraintName("fk_people_roles_people_people_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_people_roles_people_people_id");
b.HasOne("Kyoo.Abstractions.Models.Show", "Show")
.WithMany("People")
.HasForeignKey("ShowID")
- .HasConstraintName("fk_people_roles_shows_show_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_people_roles_shows_show_id");
b.Navigation("People");
@@ -937,9 +953,9 @@ namespace Kyoo.Postgresql.Migrations
b.HasOne("Kyoo.Abstractions.Models.Show", "Show")
.WithMany("Seasons")
.HasForeignKey("ShowID")
- .HasConstraintName("fk_seasons_shows_show_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_seasons_shows_show_id");
b.Navigation("Show");
});
@@ -949,8 +965,8 @@ namespace Kyoo.Postgresql.Migrations
b.HasOne("Kyoo.Abstractions.Models.Studio", "Studio")
.WithMany("Shows")
.HasForeignKey("StudioID")
- .HasConstraintName("fk_shows_studios_studio_id")
- .OnDelete(DeleteBehavior.SetNull);
+ .OnDelete(DeleteBehavior.SetNull)
+ .HasConstraintName("fk_shows_studios_studio_id");
b.Navigation("Studio");
});
@@ -960,9 +976,9 @@ namespace Kyoo.Postgresql.Migrations
b.HasOne("Kyoo.Abstractions.Models.Episode", "Episode")
.WithMany("Tracks")
.HasForeignKey("EpisodeID")
- .HasConstraintName("fk_tracks_episodes_episode_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_tracks_episodes_episode_id");
b.Navigation("Episode");
});
@@ -972,16 +988,16 @@ namespace Kyoo.Postgresql.Migrations
b.HasOne("Kyoo.Abstractions.Models.Episode", "Episode")
.WithMany()
.HasForeignKey("EpisodeID")
- .HasConstraintName("fk_watched_episodes_episodes_episode_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_watched_episodes_episodes_episode_id");
b.HasOne("Kyoo.Abstractions.Models.User", null)
.WithMany("CurrentlyWatching")
.HasForeignKey("UserID")
- .HasConstraintName("fk_watched_episodes_users_user_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_watched_episodes_users_user_id");
b.Navigation("Episode");
});
@@ -991,16 +1007,16 @@ namespace Kyoo.Postgresql.Migrations
b.HasOne("Kyoo.Abstractions.Models.User", null)
.WithMany()
.HasForeignKey("UsersID")
- .HasConstraintName("fk_link_user_show_users_users_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_link_user_show_users_users_id");
b.HasOne("Kyoo.Abstractions.Models.Show", null)
.WithMany()
.HasForeignKey("WatchedID")
- .HasConstraintName("fk_link_user_show_shows_watched_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_link_user_show_shows_watched_id");
});
modelBuilder.Entity("collection_metadata_id", b =>
@@ -1008,16 +1024,16 @@ namespace Kyoo.Postgresql.Migrations
b.HasOne("Kyoo.Abstractions.Models.Provider", "Provider")
.WithMany()
.HasForeignKey("ProviderID")
- .HasConstraintName("fk_collection_metadata_id_providers_provider_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_collection_metadata_id_providers_provider_id");
b.HasOne("Kyoo.Abstractions.Models.Collection", null)
.WithMany("ExternalIDs")
.HasForeignKey("ResourceID")
- .HasConstraintName("fk_collection_metadata_id_collections_collection_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_collection_metadata_id_collections_collection_id");
b.Navigation("Provider");
});
@@ -1027,16 +1043,16 @@ namespace Kyoo.Postgresql.Migrations
b.HasOne("Kyoo.Abstractions.Models.Provider", "Provider")
.WithMany()
.HasForeignKey("ProviderID")
- .HasConstraintName("fk_episode_metadata_id_providers_provider_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_episode_metadata_id_providers_provider_id");
b.HasOne("Kyoo.Abstractions.Models.Episode", null)
.WithMany("ExternalIDs")
.HasForeignKey("ResourceID")
- .HasConstraintName("fk_episode_metadata_id_episodes_episode_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_episode_metadata_id_episodes_episode_id");
b.Navigation("Provider");
});
@@ -1046,16 +1062,16 @@ namespace Kyoo.Postgresql.Migrations
b.HasOne("Kyoo.Abstractions.Models.Collection", null)
.WithMany()
.HasForeignKey("collection_id")
- .HasConstraintName("fk_link_collection_show_collections_collection_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_link_collection_show_collections_collection_id");
b.HasOne("Kyoo.Abstractions.Models.Show", null)
.WithMany()
.HasForeignKey("show_id")
- .HasConstraintName("fk_link_collection_show_shows_show_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_link_collection_show_shows_show_id");
});
modelBuilder.Entity("link_library_collection", b =>
@@ -1063,16 +1079,16 @@ namespace Kyoo.Postgresql.Migrations
b.HasOne("Kyoo.Abstractions.Models.Collection", null)
.WithMany()
.HasForeignKey("collection_id")
- .HasConstraintName("fk_link_library_collection_collections_collection_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_link_library_collection_collections_collection_id");
b.HasOne("Kyoo.Abstractions.Models.Library", null)
.WithMany()
.HasForeignKey("library_id")
- .HasConstraintName("fk_link_library_collection_libraries_library_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_link_library_collection_libraries_library_id");
});
modelBuilder.Entity("link_library_provider", b =>
@@ -1080,16 +1096,16 @@ namespace Kyoo.Postgresql.Migrations
b.HasOne("Kyoo.Abstractions.Models.Library", null)
.WithMany()
.HasForeignKey("library_id")
- .HasConstraintName("fk_link_library_provider_libraries_library_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_link_library_provider_libraries_library_id");
b.HasOne("Kyoo.Abstractions.Models.Provider", null)
.WithMany()
.HasForeignKey("provider_id")
- .HasConstraintName("fk_link_library_provider_providers_provider_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_link_library_provider_providers_provider_id");
});
modelBuilder.Entity("link_library_show", b =>
@@ -1097,16 +1113,16 @@ namespace Kyoo.Postgresql.Migrations
b.HasOne("Kyoo.Abstractions.Models.Library", null)
.WithMany()
.HasForeignKey("library_id")
- .HasConstraintName("fk_link_library_show_libraries_library_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_link_library_show_libraries_library_id");
b.HasOne("Kyoo.Abstractions.Models.Show", null)
.WithMany()
.HasForeignKey("show_id")
- .HasConstraintName("fk_link_library_show_shows_show_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_link_library_show_shows_show_id");
});
modelBuilder.Entity("link_show_genre", b =>
@@ -1114,16 +1130,16 @@ namespace Kyoo.Postgresql.Migrations
b.HasOne("Kyoo.Abstractions.Models.Genre", null)
.WithMany()
.HasForeignKey("genre_id")
- .HasConstraintName("fk_link_show_genre_genres_genre_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_link_show_genre_genres_genre_id");
b.HasOne("Kyoo.Abstractions.Models.Show", null)
.WithMany()
.HasForeignKey("show_id")
- .HasConstraintName("fk_link_show_genre_shows_show_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_link_show_genre_shows_show_id");
});
modelBuilder.Entity("people_metadata_id", b =>
@@ -1131,16 +1147,16 @@ namespace Kyoo.Postgresql.Migrations
b.HasOne("Kyoo.Abstractions.Models.Provider", "Provider")
.WithMany()
.HasForeignKey("ProviderID")
- .HasConstraintName("fk_people_metadata_id_providers_provider_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_people_metadata_id_providers_provider_id");
b.HasOne("Kyoo.Abstractions.Models.People", null)
.WithMany("ExternalIDs")
.HasForeignKey("ResourceID")
- .HasConstraintName("fk_people_metadata_id_people_people_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_people_metadata_id_people_people_id");
b.Navigation("Provider");
});
@@ -1150,16 +1166,16 @@ namespace Kyoo.Postgresql.Migrations
b.HasOne("Kyoo.Abstractions.Models.Provider", "Provider")
.WithMany()
.HasForeignKey("ProviderID")
- .HasConstraintName("fk_season_metadata_id_providers_provider_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_season_metadata_id_providers_provider_id");
b.HasOne("Kyoo.Abstractions.Models.Season", null)
.WithMany("ExternalIDs")
.HasForeignKey("ResourceID")
- .HasConstraintName("fk_season_metadata_id_seasons_season_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_season_metadata_id_seasons_season_id");
b.Navigation("Provider");
});
@@ -1169,16 +1185,16 @@ namespace Kyoo.Postgresql.Migrations
b.HasOne("Kyoo.Abstractions.Models.Provider", "Provider")
.WithMany()
.HasForeignKey("ProviderID")
- .HasConstraintName("fk_show_metadata_id_providers_provider_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_show_metadata_id_providers_provider_id");
b.HasOne("Kyoo.Abstractions.Models.Show", null)
.WithMany("ExternalIDs")
.HasForeignKey("ResourceID")
- .HasConstraintName("fk_show_metadata_id_shows_show_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_show_metadata_id_shows_show_id");
b.Navigation("Provider");
});
@@ -1188,16 +1204,16 @@ namespace Kyoo.Postgresql.Migrations
b.HasOne("Kyoo.Abstractions.Models.Provider", "Provider")
.WithMany()
.HasForeignKey("ProviderID")
- .HasConstraintName("fk_studio_metadata_id_providers_provider_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_studio_metadata_id_providers_provider_id");
b.HasOne("Kyoo.Abstractions.Models.Studio", null)
.WithMany("ExternalIDs")
.HasForeignKey("ResourceID")
- .HasConstraintName("fk_studio_metadata_id_studios_studio_id")
.OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
+ .IsRequired()
+ .HasConstraintName("fk_studio_metadata_id_studios_studio_id");
b.Navigation("Provider");
});
diff --git a/back/tests/Kyoo.Tests/Database/TestSample.cs b/back/tests/Kyoo.Tests/Database/TestSample.cs
index 3be5396e..ba330165 100644
--- a/back/tests/Kyoo.Tests/Database/TestSample.cs
+++ b/back/tests/Kyoo.Tests/Database/TestSample.cs
@@ -60,8 +60,8 @@ namespace Kyoo.Tests
Title = "New Show",
Overview = "overview",
Status = Status.Planned,
- StartAir = new DateTime(2011, 1, 1),
- EndAir = new DateTime(2011, 1, 1),
+ StartAir = new DateTime(2011, 1, 1).ToUniversalTime(),
+ EndAir = new DateTime(2011, 1, 1).ToUniversalTime(),
Images = new Dictionary
{
[Images.Poster] = "Poster",
@@ -81,9 +81,9 @@ namespace Kyoo.Tests
ShowSlug = Get().Slug,
Title = "New season",
Overview = "New overview",
- EndDate = new DateTime(2000, 10, 10),
+ EndDate = new DateTime(2000, 10, 10).ToUniversalTime(),
SeasonNumber = 2,
- StartDate = new DateTime(2010, 10, 10),
+ StartDate = new DateTime(2010, 10, 10).ToUniversalTime(),
Images = new Dictionary
{
[Images.Logo] = "logo"
@@ -103,7 +103,7 @@ namespace Kyoo.Tests
AbsoluteNumber = 4,
Path = "/episode-path",
Title = "New Episode Title",
- ReleaseDate = new DateTime(2000, 10, 10),
+ ReleaseDate = new DateTime(2000, 10, 10).ToUniversalTime(),
Overview = "new episode overview",
Images = new Dictionary
{
@@ -184,8 +184,8 @@ namespace Kyoo.Tests
"school students, they had long ceased to think of each other as friends.",
Status = Status.Finished,
StudioID = 1,
- StartAir = new DateTime(2011, 1, 1),
- EndAir = new DateTime(2011, 1, 1),
+ StartAir = new DateTime(2011, 1, 1).ToUniversalTime(),
+ EndAir = new DateTime(2011, 1, 1).ToUniversalTime(),
Images = new Dictionary
{
[Images.Poster] = "Poster",
@@ -206,8 +206,8 @@ namespace Kyoo.Tests
SeasonNumber = 1,
Title = "Season 1",
Overview = "The first season",
- StartDate = new DateTime(2020, 06, 05),
- EndDate = new DateTime(2020, 07, 05),
+ StartDate = new DateTime(2020, 06, 05).ToUniversalTime(),
+ EndDate = new DateTime(2020, 07, 05).ToUniversalTime(),
Images = new Dictionary
{
[Images.Poster] = "Poster",
@@ -236,7 +236,7 @@ namespace Kyoo.Tests
},
Title = "Episode 1",
Overview = "Summary of the first episode",
- ReleaseDate = new DateTime(2020, 06, 05)
+ ReleaseDate = new DateTime(2020, 06, 05).ToUniversalTime()
}
},
{
@@ -415,7 +415,7 @@ namespace Kyoo.Tests
},
Title = "Episode 3",
Overview = "Summary of the third absolute episode",
- ReleaseDate = new DateTime(2020, 06, 05)
+ ReleaseDate = new DateTime(2020, 06, 05).ToUniversalTime()
};
}
@@ -435,7 +435,7 @@ namespace Kyoo.Tests
},
Title = "John wick",
Overview = "A movie episode test",
- ReleaseDate = new DateTime(1595, 05, 12)
+ ReleaseDate = new DateTime(1595, 05, 12).ToUniversalTime()
};
}
}
diff --git a/shell.nix b/shell.nix
index 9e60002d..a2f69d2f 100644
--- a/shell.nix
+++ b/shell.nix
@@ -1,6 +1,11 @@
{pkgs ? import {}}: let
venvDir = "./scanner/.venv";
pythonPkgs = ./scanner/requirements.txt;
+ dotnet = with pkgs.dotnetCorePackages;
+ combinePackages [
+ sdk_7_0
+ aspnetcore_7_0
+ ];
in
pkgs.mkShell {
packages = with pkgs; [
@@ -8,11 +13,7 @@ in
nodePackages.yarn
nodePackages.eas-cli
nodePackages.expo-cli
- (with dotnetCorePackages;
- combinePackages [
- sdk_7_0
- aspnetcore_7_0
- ])
+ dotnet
python3
python3Packages.pip
cargo
@@ -26,6 +27,7 @@ in
];
RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
+ DOTNET_ROOT = "${dotnet}";
shellHook = ''
# Install python modules