diff --git a/back/src/Kyoo.Abstractions/Models/LibraryItem.cs b/back/src/Kyoo.Abstractions/Models/LibraryItem.cs
index 677f27ca..5961adbc 100644
--- a/back/src/Kyoo.Abstractions/Models/LibraryItem.cs
+++ b/back/src/Kyoo.Abstractions/Models/LibraryItem.cs
@@ -17,6 +17,11 @@
// along with Kyoo. If not, see .
using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Text.Json.Serialization;
+using Kyoo.Abstractions.Models.Attributes;
+using Kyoo.Utils;
namespace Kyoo.Abstractions.Models
{
@@ -53,60 +58,114 @@ namespace Kyoo.Abstractions.Models
///
public ItemKind Kind { get; }
+ ///
+ /// The title of this show.
+ ///
public string Name { get; }
- public DateTime? AirDate { get; }
+ ///
+ /// The summary of this show.
+ ///
+ public string? Overview { get; }
- public Image Poster { get; }
+ ///
+ /// The date this movie aired.
+ ///
+ public DateTime? AirDate { get; }
}
- public class BagItem : ILibraryItem
+ public class LibraryItem : IResource, ILibraryItem, IThumbnails, IMetadata
{
- public ItemKind Kind { get; }
-
+ ///
public int Id { get; set; }
- public string Slug { get; set; }
+ ///
+ [MaxLength(256)]
+ public string Slug { get; set; }
+ ///
+ /// The title of this show.
+ ///
public string Name { get; set; }
+ ///
+ /// A catchphrase for this movie.
+ ///
+ public string? Tagline { get; set; }
+
+ ///
+ /// The list of alternative titles of this show.
+ ///
+ public string[] Aliases { get; set; } = Array.Empty();
+
+ ///
+ /// The path of the movie video file.
+ ///
+ public string? Path { get; set; }
+
+ ///
+ /// The summary of this show.
+ ///
+ public string? Overview { get; set; }
+
+ ///
+ /// A list of tags that match this movie.
+ ///
+ public string[] Tags { get; set; } = Array.Empty();
+
+ ///
+ /// The list of genres (themes) this show has.
+ ///
+ public Genre[] Genres { get; set; } = Array.Empty();
+
+ ///
+ /// Is this show airing, not aired yet or finished?
+ ///
+ public Status Status { get; set; }
+
+ ///
+ /// The date this show started airing. It can be null if this is unknown.
+ ///
+ public DateTime? StartAir { get; set; }
+
+ ///
+ /// The date this show finished airing.
+ /// It can also be null if this is unknown.
+ ///
+ public DateTime? EndAir { get; set; }
+
+ ///
+ /// The date this movie aired.
+ ///
public DateTime? AirDate { get; set; }
- public Image Poster { get; set; }
+ ///
+ public Image? Poster { get; set; }
- public object Rest { get; set; }
+ ///
+ public Image? Thumbnail { get; set; }
- public ILibraryItem ToItem()
+ ///
+ public Image? Logo { get; set; }
+
+ ///
+ /// A video of a few minutes that tease the content.
+ ///
+ public string? Trailer { get; set; }
+
+ ///
+ public ItemKind Kind => ItemKind.Movie;
+
+ ///
+ public Dictionary ExternalId { get; set; } = new();
+
+ public LibraryItem() { }
+
+ [JsonConstructor]
+ public LibraryItem(string name)
{
- return Kind switch
- {
- ItemKind.Movie => Rest as MovieItem,
- ItemKind.Show => Rest as ShowItem,
- ItemKind.Collection => Rest as CollectionItem,
- };
+ Slug = Utility.ToSlug(name);
+ Name = name;
}
}
-
- public sealed class ShowItem : Show, ILibraryItem
- {
- ///
- public ItemKind Kind => ItemKind.Show;
-
- public DateTime? AirDate => StartAir;
- }
-
- public sealed class MovieItem : Movie, ILibraryItem
- {
- ///
- public ItemKind Kind => ItemKind.Movie;
- }
-
- public sealed class CollectionItem : Collection, ILibraryItem
- {
- ///
- public ItemKind Kind => ItemKind.Collection;
-
- public DateTime? AirDate => null;
- }
-
}
diff --git a/back/src/Kyoo.Abstractions/Models/Resources/Collection.cs b/back/src/Kyoo.Abstractions/Models/Resources/Collection.cs
index 544e6a17..6cae5231 100644
--- a/back/src/Kyoo.Abstractions/Models/Resources/Collection.cs
+++ b/back/src/Kyoo.Abstractions/Models/Resources/Collection.cs
@@ -41,6 +41,11 @@ namespace Kyoo.Abstractions.Models
///
public string Name { get; set; }
+ ///
+ /// The description of this collection.
+ ///
+ public string? Overview { get; set; }
+
///
public Image? Poster { get; set; }
@@ -50,11 +55,6 @@ namespace Kyoo.Abstractions.Models
///
public Image? Logo { get; set; }
- ///
- /// The description of this collection.
- ///
- public string? Overview { get; set; }
-
///
/// The list of movies contained in this collection.
///
diff --git a/back/src/Kyoo.Abstractions/Models/Resources/Movie.cs b/back/src/Kyoo.Abstractions/Models/Resources/Movie.cs
index 13943ff2..99a9f854 100644
--- a/back/src/Kyoo.Abstractions/Models/Resources/Movie.cs
+++ b/back/src/Kyoo.Abstractions/Models/Resources/Movie.cs
@@ -124,8 +124,11 @@ namespace Kyoo.Abstractions.Models
///
public void OnMerge(object merged)
{
- foreach (PeopleRole link in People)
- link.Movie = this;
+ if (People != null)
+ {
+ foreach (PeopleRole link in People)
+ link.Movie = this;
+ }
}
public Movie() { }
diff --git a/back/src/Kyoo.Abstractions/Models/Resources/Show.cs b/back/src/Kyoo.Abstractions/Models/Resources/Show.cs
index a73b8b21..38a4a42e 100644
--- a/back/src/Kyoo.Abstractions/Models/Resources/Show.cs
+++ b/back/src/Kyoo.Abstractions/Models/Resources/Show.cs
@@ -80,7 +80,6 @@ namespace Kyoo.Abstractions.Models
///
/// The date this show finished airing.
- /// It must be after the but can be the same (example: for movies).
/// It can also be null if this is unknown.
///
public DateTime? EndAir { get; set; }
@@ -99,6 +98,8 @@ namespace Kyoo.Abstractions.Models
///
public string? Trailer { get; set; }
+ [SerializeIgnore] public DateTime? AirDate => StartAir;
+
///
public Dictionary ExternalId { get; set; } = new();
diff --git a/back/src/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs b/back/src/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs
index 593407aa..3414b63c 100644
--- a/back/src/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs
+++ b/back/src/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs
@@ -54,13 +54,13 @@ namespace Kyoo.Core.Controllers
///
public override async Task GetOrDefault(int id)
{
- return (await _database.LibraryItems.FirstOrDefaultAsync(x => x.Id == id)).ToItem();
+ return await _database.LibraryItems.FirstOrDefaultAsync(x => x.Id == id);
}
///
public override async Task GetOrDefault(string slug)
{
- return (await _database.LibraryItems.SingleOrDefaultAsync(x => x.Slug == slug)).ToItem();
+ return await _database.LibraryItems.SingleOrDefaultAsync(x => x.Slug == slug);
}
///
@@ -68,9 +68,9 @@ namespace Kyoo.Core.Controllers
Sort sort = default,
Pagination limit = default)
{
- return (await ApplyFilters(_database.LibraryItems, where, sort, limit))
- .Select(x => (x as BagItem)!.ToItem())
- .ToList();
+ return await ApplyFilters(_database.LibraryItems, where, sort, limit);
+ // .Select(x => x.ToItem())
+ // .ToList();
}
///
@@ -85,14 +85,12 @@ namespace Kyoo.Core.Controllers
///
public override async Task> Search(string query)
{
- return (await Sort(
+ return await Sort(
_database.LibraryItems
- .Where(_database.Like(x => x.Name, $"%{query}%"))
+ .Where(_database.Like(x => x.Name, $"%{query}%"))
)
.Take(20)
- .ToListAsync())
- .Select(x => (x as BagItem)!.ToItem())
- .ToList();
+ .ToListAsync();
}
///
diff --git a/back/src/Kyoo.Postgresql/DatabaseContext.cs b/back/src/Kyoo.Postgresql/DatabaseContext.cs
index a5d1828a..7982c6e6 100644
--- a/back/src/Kyoo.Postgresql/DatabaseContext.cs
+++ b/back/src/Kyoo.Postgresql/DatabaseContext.cs
@@ -92,32 +92,7 @@ namespace Kyoo.Postgresql
///
/// This set is ready only, on most database this will be a view.
///
- public IQueryable LibraryItems =>
- Shows.Select(x => new BagItem
- {
- Id = x.Id,
- Slug = x.Slug,
- Name = x.Name,
- AirDate = x.StartAir,
- Poster = x.Poster,
- Rest = x
- }).Union(Movies.Select(x => new BagItem
- {
- Id = x.Id,
- Slug = x.Slug,
- Name = x.Name,
- AirDate = x.AirDate,
- Poster = x.Poster,
- Rest = x
- })).Union(Collections.Select(x => new BagItem
- {
- Id = x.Id,
- Slug = x.Slug,
- Name = x.Name,
- AirDate = null,
- Poster = x.Poster,
- Rest = x
- }));
+ public DbSet LibraryItems { get; set; }
///
/// Add a many to many link between two resources.
@@ -281,6 +256,7 @@ namespace Kyoo.Postgresql
.WithMany(x => x.Shows)
.OnDelete(DeleteBehavior.SetNull);
+ _HasManyToMany(modelBuilder, x => x.Movies, x => x.Collections);
_HasManyToMany(modelBuilder, x => x.Shows, x => x.Collections);
modelBuilder.Entity()
@@ -288,6 +264,7 @@ namespace Kyoo.Postgresql
.WithMany("Users")
.UsingEntity(x => x.ToTable(LinkName()));
+ _HasMetadata(modelBuilder);
_HasMetadata(modelBuilder);
_HasMetadata(modelBuilder);
_HasMetadata(modelBuilder);
@@ -296,6 +273,7 @@ namespace Kyoo.Postgresql
_HasMetadata(modelBuilder);
_HasMetadata(modelBuilder);
+ _HasImages(modelBuilder);
_HasImages(modelBuilder);
_HasImages(modelBuilder);
_HasImages(modelBuilder);
diff --git a/back/src/Kyoo.Postgresql/Migrations/20230805052627_initial.cs b/back/src/Kyoo.Postgresql/Migrations/20230805052627_initial.cs
deleted file mode 100644
index 40e8dd3a..00000000
--- a/back/src/Kyoo.Postgresql/Migrations/20230805052627_initial.cs
+++ /dev/null
@@ -1,528 +0,0 @@
-using System;
-using Kyoo.Abstractions.Models;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
-
-#nullable disable
-
-namespace Kyoo.Postgresql.Migrations
-{
- ///
- public partial class initial : Migration
- {
- ///
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.AlterDatabase()
- .Annotation("Npgsql:Enum:genre", "action,adventure,animation,comedy,crime,documentary,drama,family,fantasy,history,horror,music,mystery,romance,science_fiction,thriller,war,western")
- .Annotation("Npgsql:Enum:status", "unknown,finished,airing,planned");
-
- migrationBuilder.CreateTable(
- name: "collections",
- columns: table => new
- {
- id = table.Column(type: "integer", nullable: false)
- .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
- slug = table.Column(type: "character varying(256)", maxLength: 256, nullable: false),
- name = table.Column(type: "text", nullable: false),
- poster_source = table.Column(type: "text", nullable: true),
- poster_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
- thumbnail_source = table.Column(type: "text", nullable: true),
- thumbnail_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
- logo_source = table.Column(type: "text", nullable: true),
- logo_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
- overview = table.Column(type: "text", nullable: true),
- external_id = table.Column(type: "json", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("pk_collections", x => x.id);
- });
-
- migrationBuilder.CreateTable(
- name: "people",
- columns: table => new
- {
- id = table.Column(type: "integer", nullable: false)
- .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
- slug = table.Column(type: "character varying(256)", maxLength: 256, nullable: false),
- name = table.Column(type: "text", nullable: false),
- poster_source = table.Column(type: "text", nullable: true),
- poster_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
- thumbnail_source = table.Column(type: "text", nullable: true),
- thumbnail_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
- logo_source = table.Column(type: "text", nullable: true),
- logo_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
- external_id = table.Column(type: "json", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("pk_people", x => x.id);
- });
-
- migrationBuilder.CreateTable(
- name: "studios",
- columns: table => new
- {
- id = table.Column(type: "integer", nullable: false)
- .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
- slug = table.Column(type: "character varying(256)", maxLength: 256, nullable: false),
- name = table.Column(type: "text", nullable: false),
- external_id = table.Column(type: "json", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("pk_studios", x => x.id);
- });
-
- migrationBuilder.CreateTable(
- name: "users",
- columns: table => new
- {
- id = table.Column(type: "integer", nullable: false)
- .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
- slug = table.Column(type: "character varying(256)", maxLength: 256, nullable: false),
- username = table.Column(type: "text", nullable: false),
- email = table.Column(type: "text", nullable: false),
- password = table.Column(type: "text", nullable: false),
- permissions = table.Column(type: "text[]", nullable: false),
- logo_source = table.Column(type: "text", nullable: true),
- logo_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true)
- },
- constraints: table =>
- {
- table.PrimaryKey("pk_users", x => x.id);
- });
-
- migrationBuilder.CreateTable(
- name: "movies",
- columns: table => new
- {
- id = table.Column(type: "integer", nullable: false)
- .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
- slug = table.Column(type: "character varying(256)", maxLength: 256, nullable: false),
- name = table.Column(type: "text", nullable: false),
- tagline = table.Column(type: "text", nullable: true),
- aliases = table.Column(type: "text[]", nullable: false),
- path = table.Column(type: "text", nullable: false),
- overview = table.Column(type: "text", nullable: true),
- tags = table.Column(type: "text[]", nullable: false),
- genres = table.Column(type: "genre[]", nullable: false),
- status = table.Column(type: "status", nullable: false),
- air_date = table.Column(type: "timestamp with time zone", nullable: true),
- poster_source = table.Column(type: "text", nullable: true),
- poster_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
- thumbnail_source = table.Column(type: "text", nullable: true),
- thumbnail_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
- logo_source = table.Column(type: "text", nullable: true),
- logo_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
- trailer = table.Column(type: "text", nullable: true),
- external_id = table.Column(type: "json", nullable: false),
- studio_id = table.Column(type: "integer", nullable: true)
- },
- constraints: table =>
- {
- table.PrimaryKey("pk_movies", x => x.id);
- table.ForeignKey(
- name: "fk_movies_studios_studio_id",
- column: x => x.studio_id,
- principalTable: "studios",
- principalColumn: "id",
- onDelete: ReferentialAction.SetNull);
- });
-
- migrationBuilder.CreateTable(
- name: "shows",
- columns: table => new
- {
- id = table.Column(type: "integer", nullable: false)
- .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
- slug = table.Column(type: "character varying(256)", maxLength: 256, nullable: false),
- name = table.Column(type: "text", nullable: false),
- tagline = table.Column(type: "text", nullable: true),
- aliases = table.Column(type: "text[]", nullable: false),
- overview = table.Column(type: "text", nullable: true),
- tags = table.Column(type: "text[]", nullable: false),
- genres = table.Column(type: "genre[]", nullable: false),
- status = table.Column(type: "status", nullable: false),
- start_air = table.Column(type: "timestamp with time zone", nullable: true),
- end_air = table.Column(type: "timestamp with time zone", nullable: true),
- poster_source = table.Column(type: "text", nullable: true),
- poster_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
- thumbnail_source = table.Column(type: "text", nullable: true),
- thumbnail_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
- logo_source = table.Column(type: "text", nullable: true),
- logo_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
- trailer = table.Column(type: "text", nullable: true),
- external_id = table.Column(type: "json", nullable: false),
- studio_id = table.Column(type: "integer", nullable: true)
- },
- constraints: table =>
- {
- table.PrimaryKey("pk_shows", x => x.id);
- table.ForeignKey(
- name: "fk_shows_studios_studio_id",
- column: x => x.studio_id,
- principalTable: "studios",
- principalColumn: "id",
- onDelete: ReferentialAction.SetNull);
- });
-
- migrationBuilder.CreateTable(
- name: "collection_movie",
- columns: table => new
- {
- collections_id = table.Column(type: "integer", nullable: false),
- movies_id = table.Column(type: "integer", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("pk_collection_movie", x => new { x.collections_id, x.movies_id });
- table.ForeignKey(
- name: "fk_collection_movie_collections_collections_id",
- column: x => x.collections_id,
- principalTable: "collections",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- table.ForeignKey(
- name: "fk_collection_movie_movies_movies_id",
- column: x => x.movies_id,
- principalTable: "movies",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.CreateTable(
- name: "link_collection_show",
- columns: table => new
- {
- collection_id = table.Column(type: "integer", nullable: false),
- show_id = table.Column(type: "integer", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("pk_link_collection_show", x => new { x.collection_id, x.show_id });
- table.ForeignKey(
- name: "fk_link_collection_show_collections_collection_id",
- column: x => x.collection_id,
- principalTable: "collections",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- table.ForeignKey(
- name: "fk_link_collection_show_shows_show_id",
- column: x => x.show_id,
- principalTable: "shows",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.CreateTable(
- name: "link_user_show",
- columns: table => new
- {
- users_id = table.Column(type: "integer", nullable: false),
- watched_id = table.Column(type: "integer", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("pk_link_user_show", x => new { x.users_id, x.watched_id });
- table.ForeignKey(
- name: "fk_link_user_show_shows_watched_id",
- column: x => x.watched_id,
- principalTable: "shows",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- table.ForeignKey(
- name: "fk_link_user_show_users_users_id",
- column: x => x.users_id,
- principalTable: "users",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.CreateTable(
- name: "people_roles",
- columns: table => new
- {
- id = table.Column(type: "integer", nullable: false)
- .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
- people_id = table.Column(type: "integer", nullable: false),
- show_id = table.Column(type: "integer", nullable: true),
- movie_id = table.Column(type: "integer", nullable: true),
- type = table.Column(type: "text", nullable: false),
- role = table.Column(type: "text", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("pk_people_roles", x => x.id);
- table.ForeignKey(
- name: "fk_people_roles_movies_movie_id",
- column: x => x.movie_id,
- principalTable: "movies",
- principalColumn: "id");
- table.ForeignKey(
- name: "fk_people_roles_people_people_id",
- column: x => x.people_id,
- principalTable: "people",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- table.ForeignKey(
- name: "fk_people_roles_shows_show_id",
- column: x => x.show_id,
- principalTable: "shows",
- principalColumn: "id");
- });
-
- migrationBuilder.CreateTable(
- name: "seasons",
- columns: table => new
- {
- id = table.Column(type: "integer", nullable: false)
- .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
- slug = table.Column(type: "character varying(256)", maxLength: 256, nullable: false),
- show_id = table.Column(type: "integer", nullable: false),
- season_number = table.Column(type: "integer", nullable: false),
- name = table.Column(type: "text", nullable: true),
- overview = table.Column(type: "text", nullable: true),
- start_date = table.Column(type: "timestamp with time zone", nullable: true),
- end_date = table.Column(type: "timestamp with time zone", nullable: true),
- poster_source = table.Column(type: "text", nullable: true),
- poster_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
- thumbnail_source = table.Column(type: "text", nullable: true),
- thumbnail_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
- logo_source = table.Column(type: "text", nullable: true),
- logo_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
- external_id = table.Column(type: "json", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("pk_seasons", x => x.id);
- table.ForeignKey(
- name: "fk_seasons_shows_show_id",
- column: x => x.show_id,
- principalTable: "shows",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.CreateTable(
- name: "episodes",
- columns: table => new
- {
- id = table.Column(type: "integer", nullable: false)
- .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
- slug = table.Column(type: "character varying(256)", maxLength: 256, nullable: false),
- show_id = table.Column(type: "integer", nullable: false),
- season_id = table.Column(type: "integer", nullable: true),
- season_number = table.Column(type: "integer", nullable: true),
- episode_number = table.Column(type: "integer", nullable: true),
- absolute_number = table.Column(type: "integer", nullable: true),
- path = table.Column(type: "text", nullable: false),
- name = table.Column(type: "text", nullable: true),
- overview = table.Column(type: "text", nullable: true),
- release_date = table.Column(type: "timestamp with time zone", nullable: true),
- poster_source = table.Column(type: "text", nullable: true),
- poster_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
- thumbnail_source = table.Column(type: "text", nullable: true),
- thumbnail_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
- logo_source = table.Column(type: "text", nullable: true),
- logo_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
- external_id = table.Column(type: "json", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("pk_episodes", x => x.id);
- table.ForeignKey(
- name: "fk_episodes_seasons_season_id",
- column: x => x.season_id,
- principalTable: "seasons",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- table.ForeignKey(
- name: "fk_episodes_shows_show_id",
- column: x => x.show_id,
- principalTable: "shows",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.CreateTable(
- name: "watched_episode",
- columns: table => new
- {
- user_id = table.Column(type: "integer", nullable: false),
- episode_id = table.Column(type: "integer", nullable: false),
- watched_percentage = table.Column(type: "integer", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("pk_watched_episode", x => new { x.user_id, x.episode_id });
- table.ForeignKey(
- name: "fk_watched_episode_episodes_episode_id",
- column: x => x.episode_id,
- principalTable: "episodes",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- table.ForeignKey(
- name: "fk_watched_episode_users_user_id",
- column: x => x.user_id,
- principalTable: "users",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.CreateIndex(
- name: "ix_collection_movie_movies_id",
- table: "collection_movie",
- column: "movies_id");
-
- migrationBuilder.CreateIndex(
- name: "ix_collections_slug",
- table: "collections",
- column: "slug",
- unique: true);
-
- migrationBuilder.CreateIndex(
- name: "ix_episodes_season_id",
- table: "episodes",
- column: "season_id");
-
- migrationBuilder.CreateIndex(
- name: "ix_episodes_show_id_season_number_episode_number_absolute_numb",
- table: "episodes",
- columns: new[] { "show_id", "season_number", "episode_number", "absolute_number" },
- unique: true);
-
- migrationBuilder.CreateIndex(
- name: "ix_episodes_slug",
- table: "episodes",
- column: "slug",
- unique: true);
-
- migrationBuilder.CreateIndex(
- name: "ix_link_collection_show_show_id",
- table: "link_collection_show",
- column: "show_id");
-
- migrationBuilder.CreateIndex(
- name: "ix_link_user_show_watched_id",
- table: "link_user_show",
- column: "watched_id");
-
- migrationBuilder.CreateIndex(
- name: "ix_movies_slug",
- table: "movies",
- column: "slug",
- unique: true);
-
- migrationBuilder.CreateIndex(
- name: "ix_movies_studio_id",
- table: "movies",
- column: "studio_id");
-
- migrationBuilder.CreateIndex(
- name: "ix_people_slug",
- table: "people",
- column: "slug",
- unique: true);
-
- migrationBuilder.CreateIndex(
- name: "ix_people_roles_movie_id",
- table: "people_roles",
- column: "movie_id");
-
- migrationBuilder.CreateIndex(
- name: "ix_people_roles_people_id",
- table: "people_roles",
- column: "people_id");
-
- migrationBuilder.CreateIndex(
- name: "ix_people_roles_show_id",
- table: "people_roles",
- column: "show_id");
-
- migrationBuilder.CreateIndex(
- name: "ix_seasons_show_id_season_number",
- table: "seasons",
- columns: new[] { "show_id", "season_number" },
- unique: true);
-
- migrationBuilder.CreateIndex(
- name: "ix_seasons_slug",
- table: "seasons",
- column: "slug",
- unique: true);
-
- migrationBuilder.CreateIndex(
- name: "ix_shows_slug",
- table: "shows",
- column: "slug",
- unique: true);
-
- migrationBuilder.CreateIndex(
- name: "ix_shows_studio_id",
- table: "shows",
- column: "studio_id");
-
- migrationBuilder.CreateIndex(
- name: "ix_studios_slug",
- table: "studios",
- column: "slug",
- unique: true);
-
- migrationBuilder.CreateIndex(
- name: "ix_users_slug",
- table: "users",
- column: "slug",
- unique: true);
-
- migrationBuilder.CreateIndex(
- name: "ix_watched_episode_episode_id",
- table: "watched_episode",
- column: "episode_id");
- }
-
- ///
- protected override void Down(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.DropTable(
- name: "collection_movie");
-
- migrationBuilder.DropTable(
- name: "link_collection_show");
-
- migrationBuilder.DropTable(
- name: "link_user_show");
-
- migrationBuilder.DropTable(
- name: "people_roles");
-
- migrationBuilder.DropTable(
- name: "watched_episode");
-
- migrationBuilder.DropTable(
- name: "collections");
-
- migrationBuilder.DropTable(
- name: "movies");
-
- 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/back/src/Kyoo.Postgresql/Migrations/20230805052627_initial.Designer.cs b/back/src/Kyoo.Postgresql/Migrations/20230806025737_initial.Designer.cs
similarity index 86%
rename from back/src/Kyoo.Postgresql/Migrations/20230805052627_initial.Designer.cs
rename to back/src/Kyoo.Postgresql/Migrations/20230806025737_initial.Designer.cs
index 8fa8ae08..b0ecb787 100644
--- a/back/src/Kyoo.Postgresql/Migrations/20230805052627_initial.Designer.cs
+++ b/back/src/Kyoo.Postgresql/Migrations/20230806025737_initial.Designer.cs
@@ -13,7 +13,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace Kyoo.Postgresql.Migrations
{
[DbContext(typeof(PostgresContext))]
- [Migration("20230805052627_initial")]
+ [Migration("20230806025737_initial")]
partial class initial
{
///
@@ -25,28 +25,10 @@ namespace Kyoo.Postgresql.Migrations
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "genre", new[] { "action", "adventure", "animation", "comedy", "crime", "documentary", "drama", "family", "fantasy", "history", "horror", "music", "mystery", "romance", "science_fiction", "thriller", "war", "western" });
+ NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "item_kind", new[] { "show", "movie", "collection" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "status", new[] { "unknown", "finished", "airing", "planned" });
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
- modelBuilder.Entity("CollectionMovie", b =>
- {
- b.Property("CollectionsId")
- .HasColumnType("integer")
- .HasColumnName("collections_id");
-
- b.Property("MoviesId")
- .HasColumnType("integer")
- .HasColumnName("movies_id");
-
- b.HasKey("CollectionsId", "MoviesId")
- .HasName("pk_collection_movie");
-
- b.HasIndex("MoviesId")
- .HasDatabaseName("ix_collection_movie_movies_id");
-
- b.ToTable("collection_movie", (string)null);
- });
-
modelBuilder.Entity("Kyoo.Abstractions.Models.Collection", b =>
{
b.Property("Id")
@@ -160,6 +142,85 @@ namespace Kyoo.Postgresql.Migrations
b.ToTable("episodes", (string)null);
});
+ modelBuilder.Entity("Kyoo.Abstractions.Models.LibraryItem", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("AirDate")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("air_date");
+
+ b.Property("Aliases")
+ .IsRequired()
+ .HasColumnType("text[]")
+ .HasColumnName("aliases");
+
+ b.Property("EndAir")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("end_air");
+
+ b.Property("ExternalId")
+ .IsRequired()
+ .HasColumnType("json")
+ .HasColumnName("external_id");
+
+ b.Property("Genres")
+ .IsRequired()
+ .HasColumnType("genre[]")
+ .HasColumnName("genres");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("name");
+
+ b.Property("Overview")
+ .HasColumnType("text")
+ .HasColumnName("overview");
+
+ b.Property("Path")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("path");
+
+ b.Property("Slug")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("slug");
+
+ b.Property("StartAir")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("start_air");
+
+ b.Property("Status")
+ .HasColumnType("status")
+ .HasColumnName("status");
+
+ b.Property("Tagline")
+ .HasColumnType("text")
+ .HasColumnName("tagline");
+
+ b.Property("Tags")
+ .IsRequired()
+ .HasColumnType("text[]")
+ .HasColumnName("tags");
+
+ b.Property("Trailer")
+ .HasColumnType("text")
+ .HasColumnName("trailer");
+
+ b.HasKey("Id")
+ .HasName("pk_library_items");
+
+ b.ToTable("library_items", (string)null);
+ });
+
modelBuilder.Entity("Kyoo.Abstractions.Models.Movie", b =>
{
b.Property("Id")
@@ -584,6 +645,25 @@ namespace Kyoo.Postgresql.Migrations
b.ToTable("link_user_show", (string)null);
});
+ modelBuilder.Entity("link_collection_movie", b =>
+ {
+ b.Property("collection_id")
+ .HasColumnType("integer")
+ .HasColumnName("collection_id");
+
+ b.Property("movie_id")
+ .HasColumnType("integer")
+ .HasColumnName("movie_id");
+
+ b.HasKey("collection_id", "movie_id")
+ .HasName("pk_link_collection_movie");
+
+ b.HasIndex("movie_id")
+ .HasDatabaseName("ix_link_collection_movie_movie_id");
+
+ b.ToTable("link_collection_movie", (string)null);
+ });
+
modelBuilder.Entity("link_collection_show", b =>
{
b.Property("collection_id")
@@ -603,23 +683,6 @@ namespace Kyoo.Postgresql.Migrations
b.ToTable("link_collection_show", (string)null);
});
- modelBuilder.Entity("CollectionMovie", b =>
- {
- b.HasOne("Kyoo.Abstractions.Models.Collection", null)
- .WithMany()
- .HasForeignKey("CollectionsId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired()
- .HasConstraintName("fk_collection_movie_collections_collections_id");
-
- b.HasOne("Kyoo.Abstractions.Models.Movie", null)
- .WithMany()
- .HasForeignKey("MoviesId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired()
- .HasConstraintName("fk_collection_movie_movies_movies_id");
- });
-
modelBuilder.Entity("Kyoo.Abstractions.Models.Collection", b =>
{
b.OwnsOne("Kyoo.Abstractions.Models.Image", "Logo", b1 =>
@@ -811,6 +874,93 @@ namespace Kyoo.Postgresql.Migrations
b.Navigation("Thumbnail");
});
+ modelBuilder.Entity("Kyoo.Abstractions.Models.LibraryItem", b =>
+ {
+ b.OwnsOne("Kyoo.Abstractions.Models.Image", "Logo", b1 =>
+ {
+ b1.Property("LibraryItemId")
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ b1.Property("Blurhash")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("character varying(32)")
+ .HasColumnName("logo_blurhash");
+
+ b1.Property("Source")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("logo_source");
+
+ b1.HasKey("LibraryItemId");
+
+ b1.ToTable("library_items");
+
+ b1.WithOwner()
+ .HasForeignKey("LibraryItemId")
+ .HasConstraintName("fk_library_items_library_items_id");
+ });
+
+ b.OwnsOne("Kyoo.Abstractions.Models.Image", "Poster", b1 =>
+ {
+ b1.Property("LibraryItemId")
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ b1.Property("Blurhash")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("character varying(32)")
+ .HasColumnName("poster_blurhash");
+
+ b1.Property("Source")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("poster_source");
+
+ b1.HasKey("LibraryItemId");
+
+ b1.ToTable("library_items");
+
+ b1.WithOwner()
+ .HasForeignKey("LibraryItemId")
+ .HasConstraintName("fk_library_items_library_items_id");
+ });
+
+ b.OwnsOne("Kyoo.Abstractions.Models.Image", "Thumbnail", b1 =>
+ {
+ b1.Property("LibraryItemId")
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ b1.Property("Blurhash")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("character varying(32)")
+ .HasColumnName("thumbnail_blurhash");
+
+ b1.Property("Source")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("thumbnail_source");
+
+ b1.HasKey("LibraryItemId");
+
+ b1.ToTable("library_items");
+
+ b1.WithOwner()
+ .HasForeignKey("LibraryItemId")
+ .HasConstraintName("fk_library_items_library_items_id");
+ });
+
+ b.Navigation("Logo");
+
+ b.Navigation("Poster");
+
+ b.Navigation("Thumbnail");
+ });
+
modelBuilder.Entity("Kyoo.Abstractions.Models.Movie", b =>
{
b.HasOne("Kyoo.Abstractions.Models.Studio", "Studio")
@@ -1277,6 +1427,23 @@ namespace Kyoo.Postgresql.Migrations
.HasConstraintName("fk_link_user_show_shows_watched_id");
});
+ modelBuilder.Entity("link_collection_movie", b =>
+ {
+ b.HasOne("Kyoo.Abstractions.Models.Collection", null)
+ .WithMany()
+ .HasForeignKey("collection_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_link_collection_movie_collections_collection_id");
+
+ b.HasOne("Kyoo.Abstractions.Models.Movie", null)
+ .WithMany()
+ .HasForeignKey("movie_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_link_collection_movie_movies_movie_id");
+ });
+
modelBuilder.Entity("link_collection_show", b =>
{
b.HasOne("Kyoo.Abstractions.Models.Collection", null)
diff --git a/back/src/Kyoo.Postgresql/Migrations/20230806025737_initial.cs b/back/src/Kyoo.Postgresql/Migrations/20230806025737_initial.cs
new file mode 100644
index 00000000..ea2fd7d8
--- /dev/null
+++ b/back/src/Kyoo.Postgresql/Migrations/20230806025737_initial.cs
@@ -0,0 +1,547 @@
+// 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 Kyoo.Abstractions.Models;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace Kyoo.Postgresql.Migrations
+{
+ ///
+ public partial class initial : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AlterDatabase()
+ .Annotation("Npgsql:Enum:genre", "action,adventure,animation,comedy,crime,documentary,drama,family,fantasy,history,horror,music,mystery,romance,science_fiction,thriller,war,western")
+ .Annotation("Npgsql:Enum:item_kind", "show,movie,collection")
+ .Annotation("Npgsql:Enum:status", "unknown,finished,airing,planned");
+
+ migrationBuilder.CreateTable(
+ name: "collections",
+ columns: table => new
+ {
+ id = table.Column(type: "integer", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ slug = table.Column(type: "character varying(256)", maxLength: 256, nullable: false),
+ name = table.Column(type: "text", nullable: false),
+ overview = table.Column(type: "text", nullable: true),
+ poster_source = table.Column(type: "text", nullable: true),
+ poster_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
+ thumbnail_source = table.Column(type: "text", nullable: true),
+ thumbnail_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
+ logo_source = table.Column(type: "text", nullable: true),
+ logo_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
+ external_id = table.Column(type: "json", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("pk_collections", x => x.id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "people",
+ columns: table => new
+ {
+ id = table.Column(type: "integer", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ slug = table.Column(type: "character varying(256)", maxLength: 256, nullable: false),
+ name = table.Column(type: "text", nullable: false),
+ poster_source = table.Column(type: "text", nullable: true),
+ poster_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
+ thumbnail_source = table.Column(type: "text", nullable: true),
+ thumbnail_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
+ logo_source = table.Column(type: "text", nullable: true),
+ logo_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
+ external_id = table.Column(type: "json", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("pk_people", x => x.id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "studios",
+ columns: table => new
+ {
+ id = table.Column(type: "integer", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ slug = table.Column(type: "character varying(256)", maxLength: 256, nullable: false),
+ name = table.Column(type: "text", nullable: false),
+ external_id = table.Column(type: "json", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("pk_studios", x => x.id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "users",
+ columns: table => new
+ {
+ id = table.Column(type: "integer", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ slug = table.Column(type: "character varying(256)", maxLength: 256, nullable: false),
+ username = table.Column(type: "text", nullable: false),
+ email = table.Column(type: "text", nullable: false),
+ password = table.Column(type: "text", nullable: false),
+ permissions = table.Column(type: "text[]", nullable: false),
+ logo_source = table.Column(type: "text", nullable: true),
+ logo_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("pk_users", x => x.id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "movies",
+ columns: table => new
+ {
+ id = table.Column(type: "integer", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ slug = table.Column(type: "character varying(256)", maxLength: 256, nullable: false),
+ name = table.Column(type: "text", nullable: false),
+ tagline = table.Column(type: "text", nullable: true),
+ aliases = table.Column(type: "text[]", nullable: false),
+ path = table.Column(type: "text", nullable: false),
+ overview = table.Column(type: "text", nullable: true),
+ tags = table.Column(type: "text[]", nullable: false),
+ genres = table.Column(type: "genre[]", nullable: false),
+ status = table.Column(type: "status", nullable: false),
+ air_date = table.Column(type: "timestamp with time zone", nullable: true),
+ poster_source = table.Column(type: "text", nullable: true),
+ poster_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
+ thumbnail_source = table.Column(type: "text", nullable: true),
+ thumbnail_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
+ logo_source = table.Column(type: "text", nullable: true),
+ logo_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
+ trailer = table.Column(type: "text", nullable: true),
+ external_id = table.Column(type: "json", nullable: false),
+ studio_id = table.Column(type: "integer", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("pk_movies", x => x.id);
+ table.ForeignKey(
+ name: "fk_movies_studios_studio_id",
+ column: x => x.studio_id,
+ principalTable: "studios",
+ principalColumn: "id",
+ onDelete: ReferentialAction.SetNull);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "shows",
+ columns: table => new
+ {
+ id = table.Column(type: "integer", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ slug = table.Column(type: "character varying(256)", maxLength: 256, nullable: false),
+ name = table.Column(type: "text", nullable: false),
+ tagline = table.Column(type: "text", nullable: true),
+ aliases = table.Column(type: "text[]", nullable: false),
+ overview = table.Column(type: "text", nullable: true),
+ tags = table.Column(type: "text[]", nullable: false),
+ genres = table.Column(type: "genre[]", nullable: false),
+ status = table.Column(type: "status", nullable: false),
+ start_air = table.Column(type: "timestamp with time zone", nullable: true),
+ end_air = table.Column(type: "timestamp with time zone", nullable: true),
+ poster_source = table.Column(type: "text", nullable: true),
+ poster_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
+ thumbnail_source = table.Column(type: "text", nullable: true),
+ thumbnail_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
+ logo_source = table.Column(type: "text", nullable: true),
+ logo_blurhash = table.Column(type: "character varying(32)", maxLength: 32, nullable: true),
+ trailer = table.Column(type: "text", nullable: true),
+ external_id = table.Column(type: "json", nullable: false),
+ studio_id = table.Column(type: "integer", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("pk_shows", x => x.id);
+ table.ForeignKey(
+ name: "fk_shows_studios_studio_id",
+ column: x => x.studio_id,
+ principalTable: "studios",
+ principalColumn: "id",
+ onDelete: ReferentialAction.SetNull);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "link_collection_movie",
+ columns: table => new
+ {
+ collection_id = table.Column