aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Server.Implementations
diff options
context:
space:
mode:
authorPatrick Barron <barronpm@gmail.com>2020-05-02 18:32:22 -0400
committerPatrick Barron <barronpm@gmail.com>2020-05-02 18:32:22 -0400
commit032de931b14ded24bb1098a7eeec3d84561206e2 (patch)
tree9688d691481c63c6772dbc4b262cab61f7e3366d /Jellyfin.Server.Implementations
parent1927d0e23cfadf5ee203f4b4e9a3a306ad1b7c22 (diff)
Migrate activity db to EF Core
Diffstat (limited to 'Jellyfin.Server.Implementations')
-rw-r--r--Jellyfin.Server.Implementations/Activity/ActivityManager.cs103
-rw-r--r--Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj34
-rw-r--r--Jellyfin.Server.Implementations/JellyfinDb.cs119
-rw-r--r--Jellyfin.Server.Implementations/JellyfinDbProvider.cs33
-rw-r--r--Jellyfin.Server.Implementations/Migrations/20200430215054_InitialSchema.Designer.cs1513
-rw-r--r--Jellyfin.Server.Implementations/Migrations/20200430215054_InitialSchema.cs1294
-rw-r--r--Jellyfin.Server.Implementations/Migrations/DesignTimeJellyfinDbFactory.cs20
-rw-r--r--Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs1511
8 files changed, 4627 insertions, 0 deletions
diff --git a/Jellyfin.Server.Implementations/Activity/ActivityManager.cs b/Jellyfin.Server.Implementations/Activity/ActivityManager.cs
new file mode 100644
index 000000000..d7bbf793c
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Activity/ActivityManager.cs
@@ -0,0 +1,103 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Jellyfin.Data.Entities;
+using MediaBrowser.Model.Activity;
+using MediaBrowser.Model.Events;
+using MediaBrowser.Model.Querying;
+
+namespace Jellyfin.Server.Implementations.Activity
+{
+ /// <summary>
+ /// Manages the storage and retrieval of <see cref="ActivityLog"/> instances.
+ /// </summary>
+ public class ActivityManager : IActivityManager
+ {
+ private JellyfinDbProvider _provider;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ActivityManager"/> class.
+ /// </summary>
+ /// <param name="provider">The Jellyfin database provider.</param>
+ public ActivityManager(JellyfinDbProvider provider)
+ {
+ _provider = provider;
+ }
+
+ /// <inheritdoc/>
+ public event EventHandler<GenericEventArgs<ActivityLogEntry>> EntryCreated;
+
+ /// <inheritdoc/>
+ public void Create(ActivityLog entry)
+ {
+ using var dbContext = _provider.CreateContext();
+ dbContext.ActivityLogs.Add(entry);
+ dbContext.SaveChanges();
+
+ EntryCreated?.Invoke(this, new GenericEventArgs<ActivityLogEntry>(ConvertToOldModel(entry)));
+ }
+
+ /// <inheritdoc/>
+ public async Task CreateAsync(ActivityLog entry)
+ {
+ using var dbContext = _provider.CreateContext();
+ await dbContext.ActivityLogs.AddAsync(entry);
+ await dbContext.SaveChangesAsync().ConfigureAwait(false);
+
+ EntryCreated?.Invoke(this, new GenericEventArgs<ActivityLogEntry>(ConvertToOldModel(entry)));
+ }
+
+ /// <inheritdoc/>
+ public QueryResult<ActivityLogEntry> GetPagedResult(
+ Func<IQueryable<ActivityLog>, IEnumerable<ActivityLog>> func,
+ int? startIndex,
+ int? limit)
+ {
+ using var dbContext = _provider.CreateContext();
+
+ var result = func.Invoke(dbContext.ActivityLogs).AsQueryable();
+
+ if (startIndex.HasValue)
+ {
+ result = result.Where(entry => entry.Id >= startIndex.Value);
+ }
+
+ if (limit.HasValue)
+ {
+ result = result.OrderByDescending(entry => entry.DateCreated).Take(limit.Value);
+ }
+
+ // This converts the objects from the new database model to the old for compatibility with the existing API.
+ var list = result.Select(entry => ConvertToOldModel(entry)).ToList();
+
+ return new QueryResult<ActivityLogEntry>()
+ {
+ Items = list,
+ TotalRecordCount = list.Count
+ };
+ }
+
+ /// <inheritdoc/>
+ public QueryResult<ActivityLogEntry> GetPagedResult(int? startIndex, int? limit)
+ {
+ return GetPagedResult(logs => logs, startIndex, limit);
+ }
+
+ private static ActivityLogEntry ConvertToOldModel(ActivityLog entry)
+ {
+ return new ActivityLogEntry
+ {
+ Id = entry.Id,
+ Name = entry.Name,
+ Overview = entry.Overview,
+ ShortOverview = entry.ShortOverview,
+ Type = entry.Type,
+ ItemId = entry.ItemId,
+ UserId = entry.UserId,
+ Date = entry.DateCreated,
+ Severity = entry.LogSeverity
+ };
+ }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj b/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj
new file mode 100644
index 000000000..a31f28f64
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj
@@ -0,0 +1,34 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp3.1</TargetFramework>
+ <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+ <GenerateDocumentationFile>true</GenerateDocumentationFile>
+ <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+ </PropertyGroup>
+
+ <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+
+ <!-- Code analysers-->
+ <ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" />
+ <PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
+ <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
+ <PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="..\SharedVersion.cs" />
+ <Compile Remove="Migrations\20200430214405_InitialSchema.cs" />
+ <Compile Remove="Migrations\20200430214405_InitialSchema.Designer.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Jellyfin.Data\Jellyfin.Data.csproj" />
+ <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
+ <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/Jellyfin.Server.Implementations/JellyfinDb.cs b/Jellyfin.Server.Implementations/JellyfinDb.cs
new file mode 100644
index 000000000..9c1a23877
--- /dev/null
+++ b/Jellyfin.Server.Implementations/JellyfinDb.cs
@@ -0,0 +1,119 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1201 // Constuctors should not follow properties
+#pragma warning disable SA1516 // Elements should be followed by a blank line
+#pragma warning disable SA1623 // Property's documentation should begin with gets or sets
+#pragma warning disable SA1629 // Documentation should end with a period
+#pragma warning disable SA1648 // Inheritdoc should be used with inheriting class
+
+using System.Linq;
+using Jellyfin.Data;
+using Jellyfin.Data.Entities;
+using Microsoft.EntityFrameworkCore;
+
+namespace Jellyfin.Server.Implementations
+{
+ /// <inheritdoc/>
+ public partial class JellyfinDb : DbContext
+ {
+ public virtual DbSet<ActivityLog> ActivityLogs { get; set; }
+ public virtual DbSet<Artwork> Artwork { get; set; }
+ public virtual DbSet<Book> Books { get; set; }
+ public virtual DbSet<BookMetadata> BookMetadata { get; set; }
+ public virtual DbSet<Chapter> Chapters { get; set; }
+ public virtual DbSet<Collection> Collections { get; set; }
+ public virtual DbSet<CollectionItem> CollectionItems { get; set; }
+ public virtual DbSet<Company> Companies { get; set; }
+ public virtual DbSet<CompanyMetadata> CompanyMetadata { get; set; }
+ public virtual DbSet<CustomItem> CustomItems { get; set; }
+ public virtual DbSet<CustomItemMetadata> CustomItemMetadata { get; set; }
+ public virtual DbSet<Episode> Episodes { get; set; }
+ public virtual DbSet<EpisodeMetadata> EpisodeMetadata { get; set; }
+ public virtual DbSet<Genre> Genres { get; set; }
+ public virtual DbSet<Group> Groups { get; set; }
+ public virtual DbSet<Library> Libraries { get; set; }
+ public virtual DbSet<LibraryItem> LibraryItems { get; set; }
+ public virtual DbSet<LibraryRoot> LibraryRoot { get; set; }
+ public virtual DbSet<MediaFile> MediaFiles { get; set; }
+ public virtual DbSet<MediaFileStream> MediaFileStream { get; set; }
+ public virtual DbSet<Metadata> Metadata { get; set; }
+ public virtual DbSet<MetadataProvider> MetadataProviders { get; set; }
+ public virtual DbSet<MetadataProviderId> MetadataProviderIds { get; set; }
+ public virtual DbSet<Movie> Movies { get; set; }
+ public virtual DbSet<MovieMetadata> MovieMetadata { get; set; }
+ public virtual DbSet<MusicAlbum> MusicAlbums { get; set; }
+ public virtual DbSet<MusicAlbumMetadata> MusicAlbumMetadata { get; set; }
+ public virtual DbSet<Permission> Permissions { get; set; }
+ public virtual DbSet<Person> People { get; set; }
+ public virtual DbSet<PersonRole> PersonRoles { get; set; }
+ public virtual DbSet<Photo> Photo { get; set; }
+ public virtual DbSet<PhotoMetadata> PhotoMetadata { get; set; }
+ public virtual DbSet<Preference> Preferences { get; set; }
+ public virtual DbSet<ProviderMapping> ProviderMappings { get; set; }
+ public virtual DbSet<Rating> Ratings { get; set; }
+
+ /// <summary>
+ /// Repository for global::Jellyfin.Data.Entities.RatingSource - This is the entity to
+ /// store review ratings, not age ratings
+ /// </summary>
+ public virtual DbSet<RatingSource> RatingSources { get; set; }
+ public virtual DbSet<Release> Releases { get; set; }
+ public virtual DbSet<Season> Seasons { get; set; }
+ public virtual DbSet<SeasonMetadata> SeasonMetadata { get; set; }
+ public virtual DbSet<Series> Series { get; set; }
+ public virtual DbSet<SeriesMetadata> SeriesMetadata { get; set; }
+ public virtual DbSet<Track> Tracks { get; set; }
+ public virtual DbSet<TrackMetadata> TrackMetadata { get; set; }
+ public virtual DbSet<User> Users { get; set; }
+
+ /// <summary>
+ /// Gets or sets the default connection string.
+ /// </summary>
+ public static string ConnectionString { get; set; } = @"Data Source=jellyfin.db";
+
+ /// <inheritdoc />
+ public JellyfinDb(DbContextOptions<JellyfinDb> options) : base(options)
+ {
+ }
+
+ partial void CustomInit(DbContextOptionsBuilder optionsBuilder);
+
+ /// <inheritdoc />
+ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+ {
+ CustomInit(optionsBuilder);
+ }
+
+ partial void OnModelCreatingImpl(ModelBuilder modelBuilder);
+ partial void OnModelCreatedImpl(ModelBuilder modelBuilder);
+
+ /// <inheritdoc />
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ base.OnModelCreating(modelBuilder);
+ OnModelCreatingImpl(modelBuilder);
+
+ modelBuilder.HasDefaultSchema("jellyfin");
+
+ modelBuilder.Entity<Artwork>().HasIndex(t => t.Kind);
+
+ modelBuilder.Entity<Genre>().HasIndex(t => t.Name)
+ .IsUnique();
+
+ modelBuilder.Entity<LibraryItem>().HasIndex(t => t.UrlId)
+ .IsUnique();
+
+ OnModelCreatedImpl(modelBuilder);
+ }
+
+ public override int SaveChanges()
+ {
+ foreach (var entity in ChangeTracker.Entries().Where(e => e.State == EntityState.Modified))
+ {
+ var saveEntity = entity.Entity as ISavingChanges;
+ saveEntity.OnSavingChanges();
+ }
+
+ return base.SaveChanges();
+ }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/JellyfinDbProvider.cs b/Jellyfin.Server.Implementations/JellyfinDbProvider.cs
new file mode 100644
index 000000000..8fdeab088
--- /dev/null
+++ b/Jellyfin.Server.Implementations/JellyfinDbProvider.cs
@@ -0,0 +1,33 @@
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Jellyfin.Server.Implementations
+{
+ /// <summary>
+ /// Factory class for generating new <see cref="JellyfinDb"/> instances.
+ /// </summary>
+ public class JellyfinDbProvider
+ {
+ private readonly IServiceProvider _serviceProvider;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="JellyfinDbProvider"/> class.
+ /// </summary>
+ /// <param name="serviceProvider">The application's service provider.</param>
+ public JellyfinDbProvider(IServiceProvider serviceProvider)
+ {
+ _serviceProvider = serviceProvider;
+ serviceProvider.GetService<JellyfinDb>().Database.Migrate();
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="JellyfinDb"/> context.
+ /// </summary>
+ /// <returns>The newly created context.</returns>
+ public JellyfinDb CreateContext()
+ {
+ return _serviceProvider.GetService<JellyfinDb>();
+ }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/Migrations/20200430215054_InitialSchema.Designer.cs b/Jellyfin.Server.Implementations/Migrations/20200430215054_InitialSchema.Designer.cs
new file mode 100644
index 000000000..3fb0fd51e
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Migrations/20200430215054_InitialSchema.Designer.cs
@@ -0,0 +1,1513 @@
+#pragma warning disable CS1591
+
+// <auto-generated />
+using System;
+using Jellyfin.Server.Implementations;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+namespace Jellyfin.Server.Implementations.Migrations
+{
+ [DbContext(typeof(JellyfinDb))]
+ [Migration("20200430215054_InitialSchema")]
+ partial class InitialSchema
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasDefaultSchema("jellyfin")
+ .HasAnnotation("ProductVersion", "3.1.3");
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ActivityLog", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<DateTime>("DateCreated")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("ItemId")
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
+
+ b.Property<int>("LogSeverity")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(512);
+
+ b.Property<string>("Overview")
+ .HasColumnType("TEXT")
+ .HasMaxLength(512);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("ShortOverview")
+ .HasColumnType("TEXT")
+ .HasMaxLength(512);
+
+ b.Property<string>("Type")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("ActivityLog");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Artwork", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Kind")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Path")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<int?>("PersonRole_PersonRoles_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Kind");
+
+ b.HasIndex("PersonRole_PersonRoles_Id");
+
+ b.ToTable("Artwork");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Chapter", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Chapter_Chapters_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Language")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(3);
+
+ b.Property<string>("Name")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<long?>("TimeEnd")
+ .HasColumnType("INTEGER");
+
+ b.Property<long>("TimeStart")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Chapter_Chapters_Id");
+
+ b.ToTable("Chapter");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Collection", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Name")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.ToTable("Collection");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.CollectionItem", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("CollectionItem_CollectionItem_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("CollectionItem_Next_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("CollectionItem_Previous_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("LibraryItem_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CollectionItem_CollectionItem_Id");
+
+ b.HasIndex("CollectionItem_Next_Id");
+
+ b.HasIndex("CollectionItem_Previous_Id");
+
+ b.HasIndex("LibraryItem_Id");
+
+ b.ToTable("CollectionItem");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Company", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Company_Labels_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Company_Networks_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Company_Parent_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Company_Publishers_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Company_Studios_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Company_Labels_Id");
+
+ b.HasIndex("Company_Networks_Id");
+
+ b.HasIndex("Company_Parent_Id");
+
+ b.HasIndex("Company_Publishers_Id");
+
+ b.HasIndex("Company_Studios_Id");
+
+ b.ToTable("Company");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Genre", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<int?>("PersonRole_PersonRoles_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.HasIndex("PersonRole_PersonRoles_Id");
+
+ b.ToTable("Genre");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Group", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Group_Groups_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Group_Groups_Id");
+
+ b.ToTable("Group");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Library", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.ToTable("Library");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.LibraryItem", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<DateTime>("DateAdded")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("Discriminator")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property<int?>("LibraryRoot_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<Guid>("UrlId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("LibraryRoot_Id");
+
+ b.HasIndex("UrlId")
+ .IsUnique();
+
+ b.ToTable("LibraryItem");
+
+ b.HasDiscriminator<string>("Discriminator").HasValue("LibraryItem");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.LibraryRoot", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Library_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("NetworkPath")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<string>("Path")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Library_Id");
+
+ b.ToTable("LibraryRoot");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MediaFile", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Kind")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("MediaFile_MediaFiles_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Path")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MediaFile_MediaFiles_Id");
+
+ b.ToTable("MediaFile");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MediaFileStream", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("MediaFileStream_MediaFileStreams_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("StreamNumber")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MediaFileStream_MediaFileStreams_Id");
+
+ b.ToTable("MediaFileStream");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Metadata", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<DateTime>("DateAdded")
+ .HasColumnType("TEXT");
+
+ b.Property<DateTime>("DateModified")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("Discriminator")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property<string>("Language")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(3);
+
+ b.Property<string>("OriginalTitle")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<DateTimeOffset?>("ReleaseDate")
+ .HasColumnType("TEXT");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("SortTitle")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<string>("Title")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.HasKey("Id");
+
+ b.ToTable("Metadata");
+
+ b.HasDiscriminator<string>("Discriminator").HasValue("Metadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MetadataProvider", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.ToTable("MetadataProvider");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MetadataProviderId", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("MetadataProviderId_Sources_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("MetadataProvider_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("PersonRole_PersonRoles_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("ProviderId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MetadataProviderId_Sources_Id");
+
+ b.HasIndex("MetadataProvider_Id");
+
+ b.HasIndex("PersonRole_PersonRoles_Id");
+
+ b.ToTable("MetadataProviderId");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Permission", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Kind")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Permission_GroupPermissions_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Permission_Permissions_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("Value")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Permission_GroupPermissions_Id");
+
+ b.HasIndex("Permission_Permissions_Id");
+
+ b.ToTable("Permission");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Person", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<DateTime>("DateAdded")
+ .HasColumnType("TEXT");
+
+ b.Property<DateTime>("DateModified")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("SourceId")
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<Guid>("UrlId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("Person");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.PersonRole", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Artwork_Artwork_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("PersonRole_PersonRoles_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Person_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Role")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Type")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Artwork_Artwork_Id");
+
+ b.HasIndex("PersonRole_PersonRoles_Id");
+
+ b.HasIndex("Person_Id");
+
+ b.ToTable("PersonRole");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Preference", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Kind")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Preference_Preferences_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Value")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.HasKey("Id");
+
+ b.HasIndex("Preference_Preferences_Id");
+
+ b.ToTable("Preference");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ProviderMapping", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("ProviderData")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<int?>("ProviderMapping_ProviderMappings_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("ProviderName")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<string>("ProviderSecrets")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ProviderMapping_ProviderMappings_Id");
+
+ b.ToTable("ProviderMapping");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Rating", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("PersonRole_PersonRoles_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("RatingSource_RatingType_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<double>("Value")
+ .HasColumnType("REAL");
+
+ b.Property<int?>("Votes")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PersonRole_PersonRoles_Id");
+
+ b.HasIndex("RatingSource_RatingType_Id");
+
+ b.ToTable("Rating");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.RatingSource", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<double>("MaximumValue")
+ .HasColumnType("REAL");
+
+ b.Property<int?>("MetadataProviderId_Source_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<double>("MinimumValue")
+ .HasColumnType("REAL");
+
+ b.Property<string>("Name")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MetadataProviderId_Source_Id");
+
+ b.ToTable("RatingSource");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Release", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<int?>("Release_Releases_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Release_Releases_Id");
+
+ b.ToTable("Release");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.User", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("AudioLanguagePreference")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<string>("AuthenticationProviderId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<bool?>("DisplayCollectionsView")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool?>("DisplayMissingEpisodes")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool?>("EnableNextEpisodeAutoPlay")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool?>("EnableUserPreferenceAccess")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("GroupedFolders")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<bool?>("HidePlayedInLatest")
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("InvalidLoginAttemptCount")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("LatestItemExcludes")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<int?>("LoginAttemptsBeforeLockout")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("MustUpdatePassword")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("MyMediaExcludes")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<string>("OrderedViews")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<string>("Password")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<bool>("PlayDefaultAudioTrack")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool?>("RememberAudioSelections")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool?>("RememberSubtitleSelections")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("SubtitleLanguagePrefernce")
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<string>("SubtitleMode")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<string>("Username")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.HasKey("Id");
+
+ b.ToTable("User");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Book", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.LibraryItem");
+
+ b.ToTable("Book");
+
+ b.HasDiscriminator().HasValue("Book");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.CustomItem", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.LibraryItem");
+
+ b.ToTable("LibraryItem");
+
+ b.HasDiscriminator().HasValue("CustomItem");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Episode", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.LibraryItem");
+
+ b.Property<int?>("EpisodeNumber")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Episode_Episodes_Id")
+ .HasColumnType("INTEGER");
+
+ b.HasIndex("Episode_Episodes_Id");
+
+ b.ToTable("Episode");
+
+ b.HasDiscriminator().HasValue("Episode");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Movie", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.LibraryItem");
+
+ b.ToTable("Movie");
+
+ b.HasDiscriminator().HasValue("Movie");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MusicAlbum", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.LibraryItem");
+
+ b.ToTable("MusicAlbum");
+
+ b.HasDiscriminator().HasValue("MusicAlbum");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Photo", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.LibraryItem");
+
+ b.ToTable("Photo");
+
+ b.HasDiscriminator().HasValue("Photo");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Season", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.LibraryItem");
+
+ b.Property<int?>("SeasonNumber")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Season_Seasons_Id")
+ .HasColumnType("INTEGER");
+
+ b.HasIndex("Season_Seasons_Id");
+
+ b.ToTable("Season");
+
+ b.HasDiscriminator().HasValue("Season");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Series", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.LibraryItem");
+
+ b.Property<int?>("AirsDayOfWeek")
+ .HasColumnType("INTEGER");
+
+ b.Property<DateTimeOffset?>("AirsTime")
+ .HasColumnType("TEXT");
+
+ b.Property<DateTimeOffset?>("FirstAired")
+ .HasColumnType("TEXT");
+
+ b.ToTable("Series");
+
+ b.HasDiscriminator().HasValue("Series");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Track", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.LibraryItem");
+
+ b.Property<int?>("TrackNumber")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Track_Tracks_Id")
+ .HasColumnType("INTEGER");
+
+ b.HasIndex("Track_Tracks_Id");
+
+ b.ToTable("Track");
+
+ b.HasDiscriminator().HasValue("Track");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.BookMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<int?>("BookMetadata_BookMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<long?>("ISBN")
+ .HasColumnType("INTEGER");
+
+ b.HasIndex("BookMetadata_BookMetadata_Id");
+
+ b.ToTable("Metadata");
+
+ b.HasDiscriminator().HasValue("BookMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.CompanyMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<int?>("CompanyMetadata_CompanyMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Country")
+ .HasColumnType("TEXT")
+ .HasMaxLength(2);
+
+ b.Property<string>("Description")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<string>("Headquarters")
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<string>("Homepage")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.HasIndex("CompanyMetadata_CompanyMetadata_Id");
+
+ b.ToTable("CompanyMetadata");
+
+ b.HasDiscriminator().HasValue("CompanyMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.CustomItemMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<int?>("CustomItemMetadata_CustomItemMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.HasIndex("CustomItemMetadata_CustomItemMetadata_Id");
+
+ b.ToTable("CustomItemMetadata");
+
+ b.HasDiscriminator().HasValue("CustomItemMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.EpisodeMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<int?>("EpisodeMetadata_EpisodeMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Outline")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<string>("Plot")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<string>("Tagline")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.HasIndex("EpisodeMetadata_EpisodeMetadata_Id");
+
+ b.ToTable("EpisodeMetadata");
+
+ b.HasDiscriminator().HasValue("EpisodeMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MovieMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<string>("Country")
+ .HasColumnName("MovieMetadata_Country")
+ .HasColumnType("TEXT")
+ .HasMaxLength(2);
+
+ b.Property<int?>("MovieMetadata_MovieMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Outline")
+ .HasColumnName("MovieMetadata_Outline")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<string>("Plot")
+ .HasColumnName("MovieMetadata_Plot")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<string>("Tagline")
+ .HasColumnName("MovieMetadata_Tagline")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.HasIndex("MovieMetadata_MovieMetadata_Id");
+
+ b.ToTable("MovieMetadata");
+
+ b.HasDiscriminator().HasValue("MovieMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MusicAlbumMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<string>("Barcode")
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<string>("Country")
+ .HasColumnName("MusicAlbumMetadata_Country")
+ .HasColumnType("TEXT")
+ .HasMaxLength(2);
+
+ b.Property<string>("LabelNumber")
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<int?>("MusicAlbumMetadata_MusicAlbumMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.HasIndex("MusicAlbumMetadata_MusicAlbumMetadata_Id");
+
+ b.ToTable("MusicAlbumMetadata");
+
+ b.HasDiscriminator().HasValue("MusicAlbumMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.PhotoMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<int?>("PhotoMetadata_PhotoMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.HasIndex("PhotoMetadata_PhotoMetadata_Id");
+
+ b.ToTable("PhotoMetadata");
+
+ b.HasDiscriminator().HasValue("PhotoMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.SeasonMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<string>("Outline")
+ .HasColumnName("SeasonMetadata_Outline")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<int?>("SeasonMetadata_SeasonMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.HasIndex("SeasonMetadata_SeasonMetadata_Id");
+
+ b.ToTable("SeasonMetadata");
+
+ b.HasDiscriminator().HasValue("SeasonMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.SeriesMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<string>("Country")
+ .HasColumnName("SeriesMetadata_Country")
+ .HasColumnType("TEXT")
+ .HasMaxLength(2);
+
+ b.Property<string>("Outline")
+ .HasColumnName("SeriesMetadata_Outline")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<string>("Plot")
+ .HasColumnName("SeriesMetadata_Plot")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<int?>("SeriesMetadata_SeriesMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Tagline")
+ .HasColumnName("SeriesMetadata_Tagline")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.HasIndex("SeriesMetadata_SeriesMetadata_Id");
+
+ b.ToTable("SeriesMetadata");
+
+ b.HasDiscriminator().HasValue("SeriesMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.TrackMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<int?>("TrackMetadata_TrackMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.HasIndex("TrackMetadata_TrackMetadata_Id");
+
+ b.ToTable("TrackMetadata");
+
+ b.HasDiscriminator().HasValue("TrackMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Artwork", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Metadata", null)
+ .WithMany("Artwork")
+ .HasForeignKey("PersonRole_PersonRoles_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Chapter", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Release", null)
+ .WithMany("Chapters")
+ .HasForeignKey("Chapter_Chapters_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.CollectionItem", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Collection", null)
+ .WithMany("CollectionItem")
+ .HasForeignKey("CollectionItem_CollectionItem_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.CollectionItem", "Next")
+ .WithMany()
+ .HasForeignKey("CollectionItem_Next_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.CollectionItem", "Previous")
+ .WithMany()
+ .HasForeignKey("CollectionItem_Previous_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.LibraryItem", "LibraryItem")
+ .WithMany()
+ .HasForeignKey("LibraryItem_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Company", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.MusicAlbumMetadata", null)
+ .WithMany("Labels")
+ .HasForeignKey("Company_Labels_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.SeriesMetadata", null)
+ .WithMany("Networks")
+ .HasForeignKey("Company_Networks_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.Company", "Parent")
+ .WithMany()
+ .HasForeignKey("Company_Parent_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.BookMetadata", null)
+ .WithMany("Publishers")
+ .HasForeignKey("Company_Publishers_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.MovieMetadata", null)
+ .WithMany("Studios")
+ .HasForeignKey("Company_Studios_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Genre", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Metadata", null)
+ .WithMany("Genres")
+ .HasForeignKey("PersonRole_PersonRoles_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Group", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("Groups")
+ .HasForeignKey("Group_Groups_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.LibraryItem", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.LibraryRoot", "LibraryRoot")
+ .WithMany()
+ .HasForeignKey("LibraryRoot_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.LibraryRoot", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Library", "Library")
+ .WithMany()
+ .HasForeignKey("Library_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MediaFile", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Release", null)
+ .WithMany("MediaFiles")
+ .HasForeignKey("MediaFile_MediaFiles_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MediaFileStream", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.MediaFile", null)
+ .WithMany("MediaFileStreams")
+ .HasForeignKey("MediaFileStream_MediaFileStreams_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MetadataProviderId", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Person", null)
+ .WithMany("Sources")
+ .HasForeignKey("MetadataProviderId_Sources_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.PersonRole", null)
+ .WithMany("Sources")
+ .HasForeignKey("MetadataProviderId_Sources_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.MetadataProvider", "MetadataProvider")
+ .WithMany()
+ .HasForeignKey("MetadataProvider_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.Metadata", null)
+ .WithMany("Sources")
+ .HasForeignKey("PersonRole_PersonRoles_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Permission", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Group", null)
+ .WithMany("GroupPermissions")
+ .HasForeignKey("Permission_GroupPermissions_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("Permissions")
+ .HasForeignKey("Permission_Permissions_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.PersonRole", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Artwork", "Artwork")
+ .WithMany()
+ .HasForeignKey("Artwork_Artwork_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.Metadata", null)
+ .WithMany("PersonRoles")
+ .HasForeignKey("PersonRole_PersonRoles_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.Person", "Person")
+ .WithMany()
+ .HasForeignKey("Person_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Preference", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Group", null)
+ .WithMany("Preferences")
+ .HasForeignKey("Preference_Preferences_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("Preferences")
+ .HasForeignKey("Preference_Preferences_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ProviderMapping", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Group", null)
+ .WithMany("ProviderMappings")
+ .HasForeignKey("ProviderMapping_ProviderMappings_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("ProviderMappings")
+ .HasForeignKey("ProviderMapping_ProviderMappings_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Rating", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Metadata", null)
+ .WithMany("Ratings")
+ .HasForeignKey("PersonRole_PersonRoles_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.RatingSource", "RatingType")
+ .WithMany()
+ .HasForeignKey("RatingSource_RatingType_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.RatingSource", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.MetadataProviderId", "Source")
+ .WithMany()
+ .HasForeignKey("MetadataProviderId_Source_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Release", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Book", null)
+ .WithMany("Releases")
+ .HasForeignKey("Release_Releases_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.CustomItem", null)
+ .WithMany("Releases")
+ .HasForeignKey("Release_Releases_Id")
+ .HasConstraintName("FK_Release_LibraryItem_Release_Releases_Id1");
+
+ b.HasOne("Jellyfin.Data.Entities.Episode", null)
+ .WithMany("Releases")
+ .HasForeignKey("Release_Releases_Id")
+ .HasConstraintName("FK_Release_LibraryItem_Release_Releases_Id2");
+
+ b.HasOne("Jellyfin.Data.Entities.Movie", null)
+ .WithMany("Releases")
+ .HasForeignKey("Release_Releases_Id")
+ .HasConstraintName("FK_Release_LibraryItem_Release_Releases_Id3");
+
+ b.HasOne("Jellyfin.Data.Entities.Photo", null)
+ .WithMany("Releases")
+ .HasForeignKey("Release_Releases_Id")
+ .HasConstraintName("FK_Release_LibraryItem_Release_Releases_Id4");
+
+ b.HasOne("Jellyfin.Data.Entities.Track", null)
+ .WithMany("Releases")
+ .HasForeignKey("Release_Releases_Id")
+ .HasConstraintName("FK_Release_LibraryItem_Release_Releases_Id5");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Episode", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Season", null)
+ .WithMany("Episodes")
+ .HasForeignKey("Episode_Episodes_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Season", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Series", null)
+ .WithMany("Seasons")
+ .HasForeignKey("Season_Seasons_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Track", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.MusicAlbum", null)
+ .WithMany("Tracks")
+ .HasForeignKey("Track_Tracks_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.BookMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Book", null)
+ .WithMany("BookMetadata")
+ .HasForeignKey("BookMetadata_BookMetadata_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.CompanyMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Company", null)
+ .WithMany("CompanyMetadata")
+ .HasForeignKey("CompanyMetadata_CompanyMetadata_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.CustomItemMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.CustomItem", null)
+ .WithMany("CustomItemMetadata")
+ .HasForeignKey("CustomItemMetadata_CustomItemMetadata_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.EpisodeMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Episode", null)
+ .WithMany("EpisodeMetadata")
+ .HasForeignKey("EpisodeMetadata_EpisodeMetadata_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MovieMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Movie", null)
+ .WithMany("MovieMetadata")
+ .HasForeignKey("MovieMetadata_MovieMetadata_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MusicAlbumMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.MusicAlbum", null)
+ .WithMany("MusicAlbumMetadata")
+ .HasForeignKey("MusicAlbumMetadata_MusicAlbumMetadata_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.PhotoMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Photo", null)
+ .WithMany("PhotoMetadata")
+ .HasForeignKey("PhotoMetadata_PhotoMetadata_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.SeasonMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Season", null)
+ .WithMany("SeasonMetadata")
+ .HasForeignKey("SeasonMetadata_SeasonMetadata_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.SeriesMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Series", null)
+ .WithMany("SeriesMetadata")
+ .HasForeignKey("SeriesMetadata_SeriesMetadata_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.TrackMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Track", null)
+ .WithMany("TrackMetadata")
+ .HasForeignKey("TrackMetadata_TrackMetadata_Id");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/Migrations/20200430215054_InitialSchema.cs b/Jellyfin.Server.Implementations/Migrations/20200430215054_InitialSchema.cs
new file mode 100644
index 000000000..f6f2f1a81
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Migrations/20200430215054_InitialSchema.cs
@@ -0,0 +1,1294 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1601
+
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace Jellyfin.Server.Implementations.Migrations
+{
+ public partial class InitialSchema : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.EnsureSchema(
+ name: "jellyfin");
+
+ migrationBuilder.CreateTable(
+ name: "ActivityLog",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Name = table.Column<string>(maxLength: 512, nullable: false),
+ Overview = table.Column<string>(maxLength: 512, nullable: true),
+ ShortOverview = table.Column<string>(maxLength: 512, nullable: true),
+ Type = table.Column<string>(maxLength: 256, nullable: false),
+ UserId = table.Column<Guid>(nullable: false),
+ ItemId = table.Column<string>(maxLength: 256, nullable: true),
+ DateCreated = table.Column<DateTime>(nullable: false),
+ LogSeverity = table.Column<int>(nullable: false),
+ RowVersion = table.Column<uint>(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_ActivityLog", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Collection",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Name = table.Column<string>(maxLength: 1024, nullable: true),
+ RowVersion = table.Column<uint>(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Collection", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Library",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Name = table.Column<string>(maxLength: 1024, nullable: false),
+ RowVersion = table.Column<uint>(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Library", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "MetadataProvider",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Name = table.Column<string>(maxLength: 1024, nullable: false),
+ RowVersion = table.Column<uint>(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_MetadataProvider", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Person",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ UrlId = table.Column<Guid>(nullable: false),
+ Name = table.Column<string>(maxLength: 1024, nullable: false),
+ SourceId = table.Column<string>(maxLength: 255, nullable: true),
+ DateAdded = table.Column<DateTime>(nullable: false),
+ DateModified = table.Column<DateTime>(nullable: false),
+ RowVersion = table.Column<uint>(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Person", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "User",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Username = table.Column<string>(maxLength: 255, nullable: false),
+ Password = table.Column<string>(maxLength: 65535, nullable: true),
+ MustUpdatePassword = table.Column<bool>(nullable: false),
+ AudioLanguagePreference = table.Column<string>(maxLength: 255, nullable: false),
+ AuthenticationProviderId = table.Column<string>(maxLength: 255, nullable: false),
+ GroupedFolders = table.Column<string>(maxLength: 65535, nullable: true),
+ InvalidLoginAttemptCount = table.Column<int>(nullable: false),
+ LatestItemExcludes = table.Column<string>(maxLength: 65535, nullable: true),
+ LoginAttemptsBeforeLockout = table.Column<int>(nullable: true),
+ MyMediaExcludes = table.Column<string>(maxLength: 65535, nullable: true),
+ OrderedViews = table.Column<string>(maxLength: 65535, nullable: true),
+ SubtitleMode = table.Column<string>(maxLength: 255, nullable: false),
+ PlayDefaultAudioTrack = table.Column<bool>(nullable: false),
+ SubtitleLanguagePrefernce = table.Column<string>(maxLength: 255, nullable: true),
+ DisplayMissingEpisodes = table.Column<bool>(nullable: true),
+ DisplayCollectionsView = table.Column<bool>(nullable: true),
+ HidePlayedInLatest = table.Column<bool>(nullable: true),
+ RememberAudioSelections = table.Column<bool>(nullable: true),
+ RememberSubtitleSelections = table.Column<bool>(nullable: true),
+ EnableNextEpisodeAutoPlay = table.Column<bool>(nullable: true),
+ EnableUserPreferenceAccess = table.Column<bool>(nullable: true),
+ RowVersion = table.Column<uint>(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_User", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "LibraryRoot",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Path = table.Column<string>(maxLength: 65535, nullable: false),
+ NetworkPath = table.Column<string>(maxLength: 65535, nullable: true),
+ RowVersion = table.Column<uint>(nullable: false),
+ Library_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_LibraryRoot", x => x.Id);
+ table.ForeignKey(
+ name: "FK_LibraryRoot_Library_Library_Id",
+ column: x => x.Library_Id,
+ principalSchema: "jellyfin",
+ principalTable: "Library",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Group",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Name = table.Column<string>(maxLength: 255, nullable: false),
+ RowVersion = table.Column<uint>(nullable: false),
+ Group_Groups_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Group", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Group_User_Group_Groups_Id",
+ column: x => x.Group_Groups_Id,
+ principalSchema: "jellyfin",
+ principalTable: "User",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "LibraryItem",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ UrlId = table.Column<Guid>(nullable: false),
+ DateAdded = table.Column<DateTime>(nullable: false),
+ RowVersion = table.Column<uint>(nullable: false),
+ LibraryRoot_Id = table.Column<int>(nullable: true),
+ Discriminator = table.Column<string>(nullable: false),
+ EpisodeNumber = table.Column<int>(nullable: true),
+ Episode_Episodes_Id = table.Column<int>(nullable: true),
+ SeasonNumber = table.Column<int>(nullable: true),
+ Season_Seasons_Id = table.Column<int>(nullable: true),
+ AirsDayOfWeek = table.Column<int>(nullable: true),
+ AirsTime = table.Column<DateTimeOffset>(nullable: true),
+ FirstAired = table.Column<DateTimeOffset>(nullable: true),
+ TrackNumber = table.Column<int>(nullable: true),
+ Track_Tracks_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_LibraryItem", x => x.Id);
+ table.ForeignKey(
+ name: "FK_LibraryItem_LibraryItem_Episode_Episodes_Id",
+ column: x => x.Episode_Episodes_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_LibraryItem_LibraryRoot_LibraryRoot_Id",
+ column: x => x.LibraryRoot_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryRoot",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_LibraryItem_LibraryItem_Season_Seasons_Id",
+ column: x => x.Season_Seasons_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_LibraryItem_LibraryItem_Track_Tracks_Id",
+ column: x => x.Track_Tracks_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Permission",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Kind = table.Column<int>(nullable: false),
+ Value = table.Column<bool>(nullable: false),
+ RowVersion = table.Column<uint>(nullable: false),
+ Permission_GroupPermissions_Id = table.Column<int>(nullable: true),
+ Permission_Permissions_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Permission", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Permission_Group_Permission_GroupPermissions_Id",
+ column: x => x.Permission_GroupPermissions_Id,
+ principalSchema: "jellyfin",
+ principalTable: "Group",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Permission_User_Permission_Permissions_Id",
+ column: x => x.Permission_Permissions_Id,
+ principalSchema: "jellyfin",
+ principalTable: "User",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Preference",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Kind = table.Column<int>(nullable: false),
+ Value = table.Column<string>(maxLength: 65535, nullable: false),
+ RowVersion = table.Column<uint>(nullable: false),
+ Preference_Preferences_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Preference", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Preference_Group_Preference_Preferences_Id",
+ column: x => x.Preference_Preferences_Id,
+ principalSchema: "jellyfin",
+ principalTable: "Group",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Preference_User_Preference_Preferences_Id",
+ column: x => x.Preference_Preferences_Id,
+ principalSchema: "jellyfin",
+ principalTable: "User",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "ProviderMapping",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ ProviderName = table.Column<string>(maxLength: 255, nullable: false),
+ ProviderSecrets = table.Column<string>(maxLength: 65535, nullable: false),
+ ProviderData = table.Column<string>(maxLength: 65535, nullable: false),
+ RowVersion = table.Column<uint>(nullable: false),
+ ProviderMapping_ProviderMappings_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_ProviderMapping", x => x.Id);
+ table.ForeignKey(
+ name: "FK_ProviderMapping_Group_ProviderMapping_ProviderMappings_Id",
+ column: x => x.ProviderMapping_ProviderMappings_Id,
+ principalSchema: "jellyfin",
+ principalTable: "Group",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_ProviderMapping_User_ProviderMapping_ProviderMappings_Id",
+ column: x => x.ProviderMapping_ProviderMappings_Id,
+ principalSchema: "jellyfin",
+ principalTable: "User",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "CollectionItem",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ RowVersion = table.Column<uint>(nullable: false),
+ LibraryItem_Id = table.Column<int>(nullable: true),
+ CollectionItem_Next_Id = table.Column<int>(nullable: true),
+ CollectionItem_Previous_Id = table.Column<int>(nullable: true),
+ CollectionItem_CollectionItem_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_CollectionItem", x => x.Id);
+ table.ForeignKey(
+ name: "FK_CollectionItem_Collection_CollectionItem_CollectionItem_Id",
+ column: x => x.CollectionItem_CollectionItem_Id,
+ principalSchema: "jellyfin",
+ principalTable: "Collection",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_CollectionItem_CollectionItem_CollectionItem_Next_Id",
+ column: x => x.CollectionItem_Next_Id,
+ principalSchema: "jellyfin",
+ principalTable: "CollectionItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_CollectionItem_CollectionItem_CollectionItem_Previous_Id",
+ column: x => x.CollectionItem_Previous_Id,
+ principalSchema: "jellyfin",
+ principalTable: "CollectionItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_CollectionItem_LibraryItem_LibraryItem_Id",
+ column: x => x.LibraryItem_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Release",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Name = table.Column<string>(maxLength: 1024, nullable: false),
+ RowVersion = table.Column<uint>(nullable: false),
+ Release_Releases_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Release", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Release_LibraryItem_Release_Releases_Id",
+ column: x => x.Release_Releases_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Release_LibraryItem_Release_Releases_Id1",
+ column: x => x.Release_Releases_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Release_LibraryItem_Release_Releases_Id2",
+ column: x => x.Release_Releases_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Release_LibraryItem_Release_Releases_Id3",
+ column: x => x.Release_Releases_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Release_LibraryItem_Release_Releases_Id4",
+ column: x => x.Release_Releases_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Release_LibraryItem_Release_Releases_Id5",
+ column: x => x.Release_Releases_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Chapter",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Name = table.Column<string>(maxLength: 1024, nullable: true),
+ Language = table.Column<string>(maxLength: 3, nullable: false),
+ TimeStart = table.Column<long>(nullable: false),
+ TimeEnd = table.Column<long>(nullable: true),
+ RowVersion = table.Column<uint>(nullable: false),
+ Chapter_Chapters_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Chapter", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Chapter_Release_Chapter_Chapters_Id",
+ column: x => x.Chapter_Chapters_Id,
+ principalSchema: "jellyfin",
+ principalTable: "Release",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "MediaFile",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Path = table.Column<string>(maxLength: 65535, nullable: false),
+ Kind = table.Column<int>(nullable: false),
+ RowVersion = table.Column<uint>(nullable: false),
+ MediaFile_MediaFiles_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_MediaFile", x => x.Id);
+ table.ForeignKey(
+ name: "FK_MediaFile_Release_MediaFile_MediaFiles_Id",
+ column: x => x.MediaFile_MediaFiles_Id,
+ principalSchema: "jellyfin",
+ principalTable: "Release",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "MediaFileStream",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ StreamNumber = table.Column<int>(nullable: false),
+ RowVersion = table.Column<uint>(nullable: false),
+ MediaFileStream_MediaFileStreams_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_MediaFileStream", x => x.Id);
+ table.ForeignKey(
+ name: "FK_MediaFileStream_MediaFile_MediaFileStream_MediaFileStreams_Id",
+ column: x => x.MediaFileStream_MediaFileStreams_Id,
+ principalSchema: "jellyfin",
+ principalTable: "MediaFile",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "PersonRole",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Role = table.Column<string>(maxLength: 1024, nullable: true),
+ Type = table.Column<int>(nullable: false),
+ RowVersion = table.Column<uint>(nullable: false),
+ Person_Id = table.Column<int>(nullable: true),
+ Artwork_Artwork_Id = table.Column<int>(nullable: true),
+ PersonRole_PersonRoles_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_PersonRole", x => x.Id);
+ table.ForeignKey(
+ name: "FK_PersonRole_Person_Person_Id",
+ column: x => x.Person_Id,
+ principalSchema: "jellyfin",
+ principalTable: "Person",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Metadata",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Title = table.Column<string>(maxLength: 1024, nullable: false),
+ OriginalTitle = table.Column<string>(maxLength: 1024, nullable: true),
+ SortTitle = table.Column<string>(maxLength: 1024, nullable: true),
+ Language = table.Column<string>(maxLength: 3, nullable: false),
+ ReleaseDate = table.Column<DateTimeOffset>(nullable: true),
+ DateAdded = table.Column<DateTime>(nullable: false),
+ DateModified = table.Column<DateTime>(nullable: false),
+ RowVersion = table.Column<uint>(nullable: false),
+ Discriminator = table.Column<string>(nullable: false),
+ ISBN = table.Column<long>(nullable: true),
+ BookMetadata_BookMetadata_Id = table.Column<int>(nullable: true),
+ Description = table.Column<string>(maxLength: 65535, nullable: true),
+ Headquarters = table.Column<string>(maxLength: 255, nullable: true),
+ Country = table.Column<string>(maxLength: 2, nullable: true),
+ Homepage = table.Column<string>(maxLength: 1024, nullable: true),
+ CompanyMetadata_CompanyMetadata_Id = table.Column<int>(nullable: true),
+ CustomItemMetadata_CustomItemMetadata_Id = table.Column<int>(nullable: true),
+ Outline = table.Column<string>(maxLength: 1024, nullable: true),
+ Plot = table.Column<string>(maxLength: 65535, nullable: true),
+ Tagline = table.Column<string>(maxLength: 1024, nullable: true),
+ EpisodeMetadata_EpisodeMetadata_Id = table.Column<int>(nullable: true),
+ MovieMetadata_Outline = table.Column<string>(maxLength: 1024, nullable: true),
+ MovieMetadata_Plot = table.Column<string>(maxLength: 65535, nullable: true),
+ MovieMetadata_Tagline = table.Column<string>(maxLength: 1024, nullable: true),
+ MovieMetadata_Country = table.Column<string>(maxLength: 2, nullable: true),
+ MovieMetadata_MovieMetadata_Id = table.Column<int>(nullable: true),
+ Barcode = table.Column<string>(maxLength: 255, nullable: true),
+ LabelNumber = table.Column<string>(maxLength: 255, nullable: true),
+ MusicAlbumMetadata_Country = table.Column<string>(maxLength: 2, nullable: true),
+ MusicAlbumMetadata_MusicAlbumMetadata_Id = table.Column<int>(nullable: true),
+ PhotoMetadata_PhotoMetadata_Id = table.Column<int>(nullable: true),
+ SeasonMetadata_Outline = table.Column<string>(maxLength: 1024, nullable: true),
+ SeasonMetadata_SeasonMetadata_Id = table.Column<int>(nullable: true),
+ SeriesMetadata_Outline = table.Column<string>(maxLength: 1024, nullable: true),
+ SeriesMetadata_Plot = table.Column<string>(maxLength: 65535, nullable: true),
+ SeriesMetadata_Tagline = table.Column<string>(maxLength: 1024, nullable: true),
+ SeriesMetadata_Country = table.Column<string>(maxLength: 2, nullable: true),
+ SeriesMetadata_SeriesMetadata_Id = table.Column<int>(nullable: true),
+ TrackMetadata_TrackMetadata_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Metadata", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Metadata_LibraryItem_BookMetadata_BookMetadata_Id",
+ column: x => x.BookMetadata_BookMetadata_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Metadata_LibraryItem_CustomItemMetadata_CustomItemMetadata_Id",
+ column: x => x.CustomItemMetadata_CustomItemMetadata_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Metadata_LibraryItem_EpisodeMetadata_EpisodeMetadata_Id",
+ column: x => x.EpisodeMetadata_EpisodeMetadata_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Metadata_LibraryItem_MovieMetadata_MovieMetadata_Id",
+ column: x => x.MovieMetadata_MovieMetadata_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Metadata_LibraryItem_MusicAlbumMetadata_MusicAlbumMetadata_Id",
+ column: x => x.MusicAlbumMetadata_MusicAlbumMetadata_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Metadata_LibraryItem_PhotoMetadata_PhotoMetadata_Id",
+ column: x => x.PhotoMetadata_PhotoMetadata_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Metadata_LibraryItem_SeasonMetadata_SeasonMetadata_Id",
+ column: x => x.SeasonMetadata_SeasonMetadata_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Metadata_LibraryItem_SeriesMetadata_SeriesMetadata_Id",
+ column: x => x.SeriesMetadata_SeriesMetadata_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Metadata_LibraryItem_TrackMetadata_TrackMetadata_Id",
+ column: x => x.TrackMetadata_TrackMetadata_Id,
+ principalSchema: "jellyfin",
+ principalTable: "LibraryItem",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Artwork",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Path = table.Column<string>(maxLength: 65535, nullable: false),
+ Kind = table.Column<int>(nullable: false),
+ RowVersion = table.Column<uint>(nullable: false),
+ PersonRole_PersonRoles_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Artwork", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Artwork_Metadata_PersonRole_PersonRoles_Id",
+ column: x => x.PersonRole_PersonRoles_Id,
+ principalSchema: "jellyfin",
+ principalTable: "Metadata",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Company",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ RowVersion = table.Column<uint>(nullable: false),
+ Company_Parent_Id = table.Column<int>(nullable: true),
+ Company_Labels_Id = table.Column<int>(nullable: true),
+ Company_Networks_Id = table.Column<int>(nullable: true),
+ Company_Publishers_Id = table.Column<int>(nullable: true),
+ Company_Studios_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Company", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Company_Metadata_Company_Labels_Id",
+ column: x => x.Company_Labels_Id,
+ principalSchema: "jellyfin",
+ principalTable: "Metadata",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Company_Metadata_Company_Networks_Id",
+ column: x => x.Company_Networks_Id,
+ principalSchema: "jellyfin",
+ principalTable: "Metadata",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Company_Company_Company_Parent_Id",
+ column: x => x.Company_Parent_Id,
+ principalSchema: "jellyfin",
+ principalTable: "Company",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Company_Metadata_Company_Publishers_Id",
+ column: x => x.Company_Publishers_Id,
+ principalSchema: "jellyfin",
+ principalTable: "Metadata",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Company_Metadata_Company_Studios_Id",
+ column: x => x.Company_Studios_Id,
+ principalSchema: "jellyfin",
+ principalTable: "Metadata",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Genre",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Name = table.Column<string>(maxLength: 255, nullable: false),
+ RowVersion = table.Column<uint>(nullable: false),
+ PersonRole_PersonRoles_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Genre", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Genre_Metadata_PersonRole_PersonRoles_Id",
+ column: x => x.PersonRole_PersonRoles_Id,
+ principalSchema: "jellyfin",
+ principalTable: "Metadata",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "MetadataProviderId",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ ProviderId = table.Column<string>(maxLength: 255, nullable: false),
+ RowVersion = table.Column<uint>(nullable: false),
+ MetadataProvider_Id = table.Column<int>(nullable: true),
+ MetadataProviderId_Sources_Id = table.Column<int>(nullable: true),
+ PersonRole_PersonRoles_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_MetadataProviderId", x => x.Id);
+ table.ForeignKey(
+ name: "FK_MetadataProviderId_Person_MetadataProviderId_Sources_Id",
+ column: x => x.MetadataProviderId_Sources_Id,
+ principalSchema: "jellyfin",
+ principalTable: "Person",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_MetadataProviderId_PersonRole_MetadataProviderId_Sources_Id",
+ column: x => x.MetadataProviderId_Sources_Id,
+ principalSchema: "jellyfin",
+ principalTable: "PersonRole",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_MetadataProviderId_MetadataProvider_MetadataProvider_Id",
+ column: x => x.MetadataProvider_Id,
+ principalSchema: "jellyfin",
+ principalTable: "MetadataProvider",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_MetadataProviderId_Metadata_PersonRole_PersonRoles_Id",
+ column: x => x.PersonRole_PersonRoles_Id,
+ principalSchema: "jellyfin",
+ principalTable: "Metadata",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "RatingSource",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Name = table.Column<string>(maxLength: 1024, nullable: true),
+ MaximumValue = table.Column<double>(nullable: false),
+ MinimumValue = table.Column<double>(nullable: false),
+ RowVersion = table.Column<uint>(nullable: false),
+ MetadataProviderId_Source_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_RatingSource", x => x.Id);
+ table.ForeignKey(
+ name: "FK_RatingSource_MetadataProviderId_MetadataProviderId_Source_Id",
+ column: x => x.MetadataProviderId_Source_Id,
+ principalSchema: "jellyfin",
+ principalTable: "MetadataProviderId",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Rating",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Value = table.Column<double>(nullable: false),
+ Votes = table.Column<int>(nullable: true),
+ RowVersion = table.Column<uint>(nullable: false),
+ RatingSource_RatingType_Id = table.Column<int>(nullable: true),
+ PersonRole_PersonRoles_Id = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Rating", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Rating_Metadata_PersonRole_PersonRoles_Id",
+ column: x => x.PersonRole_PersonRoles_Id,
+ principalSchema: "jellyfin",
+ principalTable: "Metadata",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Rating_RatingSource_RatingSource_RatingType_Id",
+ column: x => x.RatingSource_RatingType_Id,
+ principalSchema: "jellyfin",
+ principalTable: "RatingSource",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Artwork_Kind",
+ schema: "jellyfin",
+ table: "Artwork",
+ column: "Kind");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Artwork_PersonRole_PersonRoles_Id",
+ schema: "jellyfin",
+ table: "Artwork",
+ column: "PersonRole_PersonRoles_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Chapter_Chapter_Chapters_Id",
+ schema: "jellyfin",
+ table: "Chapter",
+ column: "Chapter_Chapters_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_CollectionItem_CollectionItem_CollectionItem_Id",
+ schema: "jellyfin",
+ table: "CollectionItem",
+ column: "CollectionItem_CollectionItem_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_CollectionItem_CollectionItem_Next_Id",
+ schema: "jellyfin",
+ table: "CollectionItem",
+ column: "CollectionItem_Next_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_CollectionItem_CollectionItem_Previous_Id",
+ schema: "jellyfin",
+ table: "CollectionItem",
+ column: "CollectionItem_Previous_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_CollectionItem_LibraryItem_Id",
+ schema: "jellyfin",
+ table: "CollectionItem",
+ column: "LibraryItem_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Company_Company_Labels_Id",
+ schema: "jellyfin",
+ table: "Company",
+ column: "Company_Labels_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Company_Company_Networks_Id",
+ schema: "jellyfin",
+ table: "Company",
+ column: "Company_Networks_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Company_Company_Parent_Id",
+ schema: "jellyfin",
+ table: "Company",
+ column: "Company_Parent_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Company_Company_Publishers_Id",
+ schema: "jellyfin",
+ table: "Company",
+ column: "Company_Publishers_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Company_Company_Studios_Id",
+ schema: "jellyfin",
+ table: "Company",
+ column: "Company_Studios_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Genre_Name",
+ schema: "jellyfin",
+ table: "Genre",
+ column: "Name",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Genre_PersonRole_PersonRoles_Id",
+ schema: "jellyfin",
+ table: "Genre",
+ column: "PersonRole_PersonRoles_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Group_Group_Groups_Id",
+ schema: "jellyfin",
+ table: "Group",
+ column: "Group_Groups_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_LibraryItem_Episode_Episodes_Id",
+ schema: "jellyfin",
+ table: "LibraryItem",
+ column: "Episode_Episodes_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_LibraryItem_LibraryRoot_Id",
+ schema: "jellyfin",
+ table: "LibraryItem",
+ column: "LibraryRoot_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_LibraryItem_UrlId",
+ schema: "jellyfin",
+ table: "LibraryItem",
+ column: "UrlId",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_LibraryItem_Season_Seasons_Id",
+ schema: "jellyfin",
+ table: "LibraryItem",
+ column: "Season_Seasons_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_LibraryItem_Track_Tracks_Id",
+ schema: "jellyfin",
+ table: "LibraryItem",
+ column: "Track_Tracks_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_LibraryRoot_Library_Id",
+ schema: "jellyfin",
+ table: "LibraryRoot",
+ column: "Library_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_MediaFile_MediaFile_MediaFiles_Id",
+ schema: "jellyfin",
+ table: "MediaFile",
+ column: "MediaFile_MediaFiles_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_MediaFileStream_MediaFileStream_MediaFileStreams_Id",
+ schema: "jellyfin",
+ table: "MediaFileStream",
+ column: "MediaFileStream_MediaFileStreams_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Metadata_BookMetadata_BookMetadata_Id",
+ schema: "jellyfin",
+ table: "Metadata",
+ column: "BookMetadata_BookMetadata_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Metadata_CompanyMetadata_CompanyMetadata_Id",
+ schema: "jellyfin",
+ table: "Metadata",
+ column: "CompanyMetadata_CompanyMetadata_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Metadata_CustomItemMetadata_CustomItemMetadata_Id",
+ schema: "jellyfin",
+ table: "Metadata",
+ column: "CustomItemMetadata_CustomItemMetadata_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Metadata_EpisodeMetadata_EpisodeMetadata_Id",
+ schema: "jellyfin",
+ table: "Metadata",
+ column: "EpisodeMetadata_EpisodeMetadata_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Metadata_MovieMetadata_MovieMetadata_Id",
+ schema: "jellyfin",
+ table: "Metadata",
+ column: "MovieMetadata_MovieMetadata_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Metadata_MusicAlbumMetadata_MusicAlbumMetadata_Id",
+ schema: "jellyfin",
+ table: "Metadata",
+ column: "MusicAlbumMetadata_MusicAlbumMetadata_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Metadata_PhotoMetadata_PhotoMetadata_Id",
+ schema: "jellyfin",
+ table: "Metadata",
+ column: "PhotoMetadata_PhotoMetadata_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Metadata_SeasonMetadata_SeasonMetadata_Id",
+ schema: "jellyfin",
+ table: "Metadata",
+ column: "SeasonMetadata_SeasonMetadata_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Metadata_SeriesMetadata_SeriesMetadata_Id",
+ schema: "jellyfin",
+ table: "Metadata",
+ column: "SeriesMetadata_SeriesMetadata_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Metadata_TrackMetadata_TrackMetadata_Id",
+ schema: "jellyfin",
+ table: "Metadata",
+ column: "TrackMetadata_TrackMetadata_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_MetadataProviderId_MetadataProviderId_Sources_Id",
+ schema: "jellyfin",
+ table: "MetadataProviderId",
+ column: "MetadataProviderId_Sources_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_MetadataProviderId_MetadataProvider_Id",
+ schema: "jellyfin",
+ table: "MetadataProviderId",
+ column: "MetadataProvider_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_MetadataProviderId_PersonRole_PersonRoles_Id",
+ schema: "jellyfin",
+ table: "MetadataProviderId",
+ column: "PersonRole_PersonRoles_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Permission_Permission_GroupPermissions_Id",
+ schema: "jellyfin",
+ table: "Permission",
+ column: "Permission_GroupPermissions_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Permission_Permission_Permissions_Id",
+ schema: "jellyfin",
+ table: "Permission",
+ column: "Permission_Permissions_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_PersonRole_Artwork_Artwork_Id",
+ schema: "jellyfin",
+ table: "PersonRole",
+ column: "Artwork_Artwork_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_PersonRole_PersonRole_PersonRoles_Id",
+ schema: "jellyfin",
+ table: "PersonRole",
+ column: "PersonRole_PersonRoles_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_PersonRole_Person_Id",
+ schema: "jellyfin",
+ table: "PersonRole",
+ column: "Person_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Preference_Preference_Preferences_Id",
+ schema: "jellyfin",
+ table: "Preference",
+ column: "Preference_Preferences_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_ProviderMapping_ProviderMapping_ProviderMappings_Id",
+ schema: "jellyfin",
+ table: "ProviderMapping",
+ column: "ProviderMapping_ProviderMappings_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Rating_PersonRole_PersonRoles_Id",
+ schema: "jellyfin",
+ table: "Rating",
+ column: "PersonRole_PersonRoles_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Rating_RatingSource_RatingType_Id",
+ schema: "jellyfin",
+ table: "Rating",
+ column: "RatingSource_RatingType_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_RatingSource_MetadataProviderId_Source_Id",
+ schema: "jellyfin",
+ table: "RatingSource",
+ column: "MetadataProviderId_Source_Id");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Release_Release_Releases_Id",
+ schema: "jellyfin",
+ table: "Release",
+ column: "Release_Releases_Id");
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_PersonRole_Metadata_PersonRole_PersonRoles_Id",
+ schema: "jellyfin",
+ table: "PersonRole",
+ column: "PersonRole_PersonRoles_Id",
+ principalSchema: "jellyfin",
+ principalTable: "Metadata",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_PersonRole_Artwork_Artwork_Artwork_Id",
+ schema: "jellyfin",
+ table: "PersonRole",
+ column: "Artwork_Artwork_Id",
+ principalSchema: "jellyfin",
+ principalTable: "Artwork",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_Metadata_Company_CompanyMetadata_CompanyMetadata_Id",
+ schema: "jellyfin",
+ table: "Metadata",
+ column: "CompanyMetadata_CompanyMetadata_Id",
+ principalSchema: "jellyfin",
+ principalTable: "Company",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropForeignKey(
+ name: "FK_Company_Metadata_Company_Labels_Id",
+ schema: "jellyfin",
+ table: "Company");
+
+ migrationBuilder.DropForeignKey(
+ name: "FK_Company_Metadata_Company_Networks_Id",
+ schema: "jellyfin",
+ table: "Company");
+
+ migrationBuilder.DropForeignKey(
+ name: "FK_Company_Metadata_Company_Publishers_Id",
+ schema: "jellyfin",
+ table: "Company");
+
+ migrationBuilder.DropForeignKey(
+ name: "FK_Company_Metadata_Company_Studios_Id",
+ schema: "jellyfin",
+ table: "Company");
+
+ migrationBuilder.DropTable(
+ name: "ActivityLog",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "Chapter",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "CollectionItem",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "Genre",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "MediaFileStream",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "Permission",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "Preference",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "ProviderMapping",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "Rating",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "Collection",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "MediaFile",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "Group",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "RatingSource",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "Release",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "User",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "MetadataProviderId",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "PersonRole",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "MetadataProvider",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "Artwork",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "Person",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "Metadata",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "LibraryItem",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "Company",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "LibraryRoot",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "Library",
+ schema: "jellyfin");
+ }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/Migrations/DesignTimeJellyfinDbFactory.cs b/Jellyfin.Server.Implementations/Migrations/DesignTimeJellyfinDbFactory.cs
new file mode 100644
index 000000000..72a4a8c3b
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Migrations/DesignTimeJellyfinDbFactory.cs
@@ -0,0 +1,20 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Design;
+
+namespace Jellyfin.Server.Implementations.Migrations
+{
+ /// <summary>
+ /// The design time factory for <see cref="JellyfinDb"/>.
+ /// This is only used for the creation of migrations and not during runtime.
+ /// </summary>
+ internal class DesignTimeJellyfinDbFactory : IDesignTimeDbContextFactory<JellyfinDb>
+ {
+ public JellyfinDb CreateDbContext(string[] args)
+ {
+ var optionsBuilder = new DbContextOptionsBuilder<JellyfinDb>();
+ optionsBuilder.UseSqlite("Data Source=jellyfin.db");
+
+ return new JellyfinDb(optionsBuilder.Options);
+ }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs b/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs
new file mode 100644
index 000000000..8cdd101af
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs
@@ -0,0 +1,1511 @@
+#pragma warning disable CS1591
+
+// <auto-generated />
+using System;
+using Jellyfin.Server.Implementations;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+namespace Jellyfin.Server.Implementations.Migrations
+{
+ [DbContext(typeof(JellyfinDb))]
+ partial class JellyfinDbModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasDefaultSchema("jellyfin")
+ .HasAnnotation("ProductVersion", "3.1.3");
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ActivityLog", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<DateTime>("DateCreated")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("ItemId")
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
+
+ b.Property<int>("LogSeverity")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(512);
+
+ b.Property<string>("Overview")
+ .HasColumnType("TEXT")
+ .HasMaxLength(512);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("ShortOverview")
+ .HasColumnType("TEXT")
+ .HasMaxLength(512);
+
+ b.Property<string>("Type")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("ActivityLog");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Artwork", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Kind")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Path")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<int?>("PersonRole_PersonRoles_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Kind");
+
+ b.HasIndex("PersonRole_PersonRoles_Id");
+
+ b.ToTable("Artwork");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Chapter", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Chapter_Chapters_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Language")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(3);
+
+ b.Property<string>("Name")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<long?>("TimeEnd")
+ .HasColumnType("INTEGER");
+
+ b.Property<long>("TimeStart")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Chapter_Chapters_Id");
+
+ b.ToTable("Chapter");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Collection", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Name")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.ToTable("Collection");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.CollectionItem", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("CollectionItem_CollectionItem_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("CollectionItem_Next_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("CollectionItem_Previous_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("LibraryItem_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CollectionItem_CollectionItem_Id");
+
+ b.HasIndex("CollectionItem_Next_Id");
+
+ b.HasIndex("CollectionItem_Previous_Id");
+
+ b.HasIndex("LibraryItem_Id");
+
+ b.ToTable("CollectionItem");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Company", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Company_Labels_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Company_Networks_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Company_Parent_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Company_Publishers_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Company_Studios_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Company_Labels_Id");
+
+ b.HasIndex("Company_Networks_Id");
+
+ b.HasIndex("Company_Parent_Id");
+
+ b.HasIndex("Company_Publishers_Id");
+
+ b.HasIndex("Company_Studios_Id");
+
+ b.ToTable("Company");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Genre", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<int?>("PersonRole_PersonRoles_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.HasIndex("PersonRole_PersonRoles_Id");
+
+ b.ToTable("Genre");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Group", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Group_Groups_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Group_Groups_Id");
+
+ b.ToTable("Group");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Library", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.ToTable("Library");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.LibraryItem", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<DateTime>("DateAdded")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("Discriminator")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property<int?>("LibraryRoot_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<Guid>("UrlId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("LibraryRoot_Id");
+
+ b.HasIndex("UrlId")
+ .IsUnique();
+
+ b.ToTable("LibraryItem");
+
+ b.HasDiscriminator<string>("Discriminator").HasValue("LibraryItem");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.LibraryRoot", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Library_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("NetworkPath")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<string>("Path")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Library_Id");
+
+ b.ToTable("LibraryRoot");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MediaFile", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Kind")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("MediaFile_MediaFiles_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Path")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MediaFile_MediaFiles_Id");
+
+ b.ToTable("MediaFile");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MediaFileStream", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("MediaFileStream_MediaFileStreams_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("StreamNumber")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MediaFileStream_MediaFileStreams_Id");
+
+ b.ToTable("MediaFileStream");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Metadata", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<DateTime>("DateAdded")
+ .HasColumnType("TEXT");
+
+ b.Property<DateTime>("DateModified")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("Discriminator")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property<string>("Language")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(3);
+
+ b.Property<string>("OriginalTitle")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<DateTimeOffset?>("ReleaseDate")
+ .HasColumnType("TEXT");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("SortTitle")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<string>("Title")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.HasKey("Id");
+
+ b.ToTable("Metadata");
+
+ b.HasDiscriminator<string>("Discriminator").HasValue("Metadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MetadataProvider", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.ToTable("MetadataProvider");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MetadataProviderId", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("MetadataProviderId_Sources_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("MetadataProvider_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("PersonRole_PersonRoles_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("ProviderId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MetadataProviderId_Sources_Id");
+
+ b.HasIndex("MetadataProvider_Id");
+
+ b.HasIndex("PersonRole_PersonRoles_Id");
+
+ b.ToTable("MetadataProviderId");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Permission", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Kind")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Permission_GroupPermissions_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Permission_Permissions_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("Value")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Permission_GroupPermissions_Id");
+
+ b.HasIndex("Permission_Permissions_Id");
+
+ b.ToTable("Permission");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Person", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<DateTime>("DateAdded")
+ .HasColumnType("TEXT");
+
+ b.Property<DateTime>("DateModified")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("SourceId")
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<Guid>("UrlId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("Person");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.PersonRole", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Artwork_Artwork_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("PersonRole_PersonRoles_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Person_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Role")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Type")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Artwork_Artwork_Id");
+
+ b.HasIndex("PersonRole_PersonRoles_Id");
+
+ b.HasIndex("Person_Id");
+
+ b.ToTable("PersonRole");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Preference", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Kind")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Preference_Preferences_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Value")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.HasKey("Id");
+
+ b.HasIndex("Preference_Preferences_Id");
+
+ b.ToTable("Preference");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ProviderMapping", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("ProviderData")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<int?>("ProviderMapping_ProviderMappings_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("ProviderName")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<string>("ProviderSecrets")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ProviderMapping_ProviderMappings_Id");
+
+ b.ToTable("ProviderMapping");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Rating", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("PersonRole_PersonRoles_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("RatingSource_RatingType_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<double>("Value")
+ .HasColumnType("REAL");
+
+ b.Property<int?>("Votes")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PersonRole_PersonRoles_Id");
+
+ b.HasIndex("RatingSource_RatingType_Id");
+
+ b.ToTable("Rating");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.RatingSource", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<double>("MaximumValue")
+ .HasColumnType("REAL");
+
+ b.Property<int?>("MetadataProviderId_Source_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<double>("MinimumValue")
+ .HasColumnType("REAL");
+
+ b.Property<string>("Name")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MetadataProviderId_Source_Id");
+
+ b.ToTable("RatingSource");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Release", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<int?>("Release_Releases_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Release_Releases_Id");
+
+ b.ToTable("Release");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.User", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("AudioLanguagePreference")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<string>("AuthenticationProviderId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<bool?>("DisplayCollectionsView")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool?>("DisplayMissingEpisodes")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool?>("EnableNextEpisodeAutoPlay")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool?>("EnableUserPreferenceAccess")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("GroupedFolders")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<bool?>("HidePlayedInLatest")
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("InvalidLoginAttemptCount")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("LatestItemExcludes")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<int?>("LoginAttemptsBeforeLockout")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("MustUpdatePassword")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("MyMediaExcludes")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<string>("OrderedViews")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<string>("Password")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<bool>("PlayDefaultAudioTrack")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool?>("RememberAudioSelections")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool?>("RememberSubtitleSelections")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("SubtitleLanguagePrefernce")
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<string>("SubtitleMode")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<string>("Username")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.HasKey("Id");
+
+ b.ToTable("User");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Book", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.LibraryItem");
+
+ b.ToTable("Book");
+
+ b.HasDiscriminator().HasValue("Book");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.CustomItem", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.LibraryItem");
+
+ b.ToTable("LibraryItem");
+
+ b.HasDiscriminator().HasValue("CustomItem");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Episode", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.LibraryItem");
+
+ b.Property<int?>("EpisodeNumber")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Episode_Episodes_Id")
+ .HasColumnType("INTEGER");
+
+ b.HasIndex("Episode_Episodes_Id");
+
+ b.ToTable("Episode");
+
+ b.HasDiscriminator().HasValue("Episode");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Movie", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.LibraryItem");
+
+ b.ToTable("Movie");
+
+ b.HasDiscriminator().HasValue("Movie");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MusicAlbum", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.LibraryItem");
+
+ b.ToTable("MusicAlbum");
+
+ b.HasDiscriminator().HasValue("MusicAlbum");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Photo", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.LibraryItem");
+
+ b.ToTable("Photo");
+
+ b.HasDiscriminator().HasValue("Photo");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Season", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.LibraryItem");
+
+ b.Property<int?>("SeasonNumber")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Season_Seasons_Id")
+ .HasColumnType("INTEGER");
+
+ b.HasIndex("Season_Seasons_Id");
+
+ b.ToTable("Season");
+
+ b.HasDiscriminator().HasValue("Season");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Series", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.LibraryItem");
+
+ b.Property<int?>("AirsDayOfWeek")
+ .HasColumnType("INTEGER");
+
+ b.Property<DateTimeOffset?>("AirsTime")
+ .HasColumnType("TEXT");
+
+ b.Property<DateTimeOffset?>("FirstAired")
+ .HasColumnType("TEXT");
+
+ b.ToTable("Series");
+
+ b.HasDiscriminator().HasValue("Series");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Track", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.LibraryItem");
+
+ b.Property<int?>("TrackNumber")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("Track_Tracks_Id")
+ .HasColumnType("INTEGER");
+
+ b.HasIndex("Track_Tracks_Id");
+
+ b.ToTable("Track");
+
+ b.HasDiscriminator().HasValue("Track");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.BookMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<int?>("BookMetadata_BookMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<long?>("ISBN")
+ .HasColumnType("INTEGER");
+
+ b.HasIndex("BookMetadata_BookMetadata_Id");
+
+ b.ToTable("Metadata");
+
+ b.HasDiscriminator().HasValue("BookMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.CompanyMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<int?>("CompanyMetadata_CompanyMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Country")
+ .HasColumnType("TEXT")
+ .HasMaxLength(2);
+
+ b.Property<string>("Description")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<string>("Headquarters")
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<string>("Homepage")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.HasIndex("CompanyMetadata_CompanyMetadata_Id");
+
+ b.ToTable("CompanyMetadata");
+
+ b.HasDiscriminator().HasValue("CompanyMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.CustomItemMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<int?>("CustomItemMetadata_CustomItemMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.HasIndex("CustomItemMetadata_CustomItemMetadata_Id");
+
+ b.ToTable("CustomItemMetadata");
+
+ b.HasDiscriminator().HasValue("CustomItemMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.EpisodeMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<int?>("EpisodeMetadata_EpisodeMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Outline")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<string>("Plot")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<string>("Tagline")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.HasIndex("EpisodeMetadata_EpisodeMetadata_Id");
+
+ b.ToTable("EpisodeMetadata");
+
+ b.HasDiscriminator().HasValue("EpisodeMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MovieMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<string>("Country")
+ .HasColumnName("MovieMetadata_Country")
+ .HasColumnType("TEXT")
+ .HasMaxLength(2);
+
+ b.Property<int?>("MovieMetadata_MovieMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Outline")
+ .HasColumnName("MovieMetadata_Outline")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<string>("Plot")
+ .HasColumnName("MovieMetadata_Plot")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<string>("Tagline")
+ .HasColumnName("MovieMetadata_Tagline")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.HasIndex("MovieMetadata_MovieMetadata_Id");
+
+ b.ToTable("MovieMetadata");
+
+ b.HasDiscriminator().HasValue("MovieMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MusicAlbumMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<string>("Barcode")
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<string>("Country")
+ .HasColumnName("MusicAlbumMetadata_Country")
+ .HasColumnType("TEXT")
+ .HasMaxLength(2);
+
+ b.Property<string>("LabelNumber")
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<int?>("MusicAlbumMetadata_MusicAlbumMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.HasIndex("MusicAlbumMetadata_MusicAlbumMetadata_Id");
+
+ b.ToTable("MusicAlbumMetadata");
+
+ b.HasDiscriminator().HasValue("MusicAlbumMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.PhotoMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<int?>("PhotoMetadata_PhotoMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.HasIndex("PhotoMetadata_PhotoMetadata_Id");
+
+ b.ToTable("PhotoMetadata");
+
+ b.HasDiscriminator().HasValue("PhotoMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.SeasonMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<string>("Outline")
+ .HasColumnName("SeasonMetadata_Outline")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<int?>("SeasonMetadata_SeasonMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.HasIndex("SeasonMetadata_SeasonMetadata_Id");
+
+ b.ToTable("SeasonMetadata");
+
+ b.HasDiscriminator().HasValue("SeasonMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.SeriesMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<string>("Country")
+ .HasColumnName("SeriesMetadata_Country")
+ .HasColumnType("TEXT")
+ .HasMaxLength(2);
+
+ b.Property<string>("Outline")
+ .HasColumnName("SeriesMetadata_Outline")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.Property<string>("Plot")
+ .HasColumnName("SeriesMetadata_Plot")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<int?>("SeriesMetadata_SeriesMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Tagline")
+ .HasColumnName("SeriesMetadata_Tagline")
+ .HasColumnType("TEXT")
+ .HasMaxLength(1024);
+
+ b.HasIndex("SeriesMetadata_SeriesMetadata_Id");
+
+ b.ToTable("SeriesMetadata");
+
+ b.HasDiscriminator().HasValue("SeriesMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.TrackMetadata", b =>
+ {
+ b.HasBaseType("Jellyfin.Data.Entities.Metadata");
+
+ b.Property<int?>("TrackMetadata_TrackMetadata_Id")
+ .HasColumnType("INTEGER");
+
+ b.HasIndex("TrackMetadata_TrackMetadata_Id");
+
+ b.ToTable("TrackMetadata");
+
+ b.HasDiscriminator().HasValue("TrackMetadata");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Artwork", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Metadata", null)
+ .WithMany("Artwork")
+ .HasForeignKey("PersonRole_PersonRoles_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Chapter", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Release", null)
+ .WithMany("Chapters")
+ .HasForeignKey("Chapter_Chapters_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.CollectionItem", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Collection", null)
+ .WithMany("CollectionItem")
+ .HasForeignKey("CollectionItem_CollectionItem_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.CollectionItem", "Next")
+ .WithMany()
+ .HasForeignKey("CollectionItem_Next_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.CollectionItem", "Previous")
+ .WithMany()
+ .HasForeignKey("CollectionItem_Previous_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.LibraryItem", "LibraryItem")
+ .WithMany()
+ .HasForeignKey("LibraryItem_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Company", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.MusicAlbumMetadata", null)
+ .WithMany("Labels")
+ .HasForeignKey("Company_Labels_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.SeriesMetadata", null)
+ .WithMany("Networks")
+ .HasForeignKey("Company_Networks_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.Company", "Parent")
+ .WithMany()
+ .HasForeignKey("Company_Parent_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.BookMetadata", null)
+ .WithMany("Publishers")
+ .HasForeignKey("Company_Publishers_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.MovieMetadata", null)
+ .WithMany("Studios")
+ .HasForeignKey("Company_Studios_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Genre", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Metadata", null)
+ .WithMany("Genres")
+ .HasForeignKey("PersonRole_PersonRoles_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Group", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("Groups")
+ .HasForeignKey("Group_Groups_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.LibraryItem", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.LibraryRoot", "LibraryRoot")
+ .WithMany()
+ .HasForeignKey("LibraryRoot_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.LibraryRoot", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Library", "Library")
+ .WithMany()
+ .HasForeignKey("Library_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MediaFile", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Release", null)
+ .WithMany("MediaFiles")
+ .HasForeignKey("MediaFile_MediaFiles_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MediaFileStream", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.MediaFile", null)
+ .WithMany("MediaFileStreams")
+ .HasForeignKey("MediaFileStream_MediaFileStreams_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MetadataProviderId", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Person", null)
+ .WithMany("Sources")
+ .HasForeignKey("MetadataProviderId_Sources_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.PersonRole", null)
+ .WithMany("Sources")
+ .HasForeignKey("MetadataProviderId_Sources_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.MetadataProvider", "MetadataProvider")
+ .WithMany()
+ .HasForeignKey("MetadataProvider_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.Metadata", null)
+ .WithMany("Sources")
+ .HasForeignKey("PersonRole_PersonRoles_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Permission", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Group", null)
+ .WithMany("GroupPermissions")
+ .HasForeignKey("Permission_GroupPermissions_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("Permissions")
+ .HasForeignKey("Permission_Permissions_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.PersonRole", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Artwork", "Artwork")
+ .WithMany()
+ .HasForeignKey("Artwork_Artwork_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.Metadata", null)
+ .WithMany("PersonRoles")
+ .HasForeignKey("PersonRole_PersonRoles_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.Person", "Person")
+ .WithMany()
+ .HasForeignKey("Person_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Preference", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Group", null)
+ .WithMany("Preferences")
+ .HasForeignKey("Preference_Preferences_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("Preferences")
+ .HasForeignKey("Preference_Preferences_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ProviderMapping", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Group", null)
+ .WithMany("ProviderMappings")
+ .HasForeignKey("ProviderMapping_ProviderMappings_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("ProviderMappings")
+ .HasForeignKey("ProviderMapping_ProviderMappings_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Rating", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Metadata", null)
+ .WithMany("Ratings")
+ .HasForeignKey("PersonRole_PersonRoles_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.RatingSource", "RatingType")
+ .WithMany()
+ .HasForeignKey("RatingSource_RatingType_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.RatingSource", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.MetadataProviderId", "Source")
+ .WithMany()
+ .HasForeignKey("MetadataProviderId_Source_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Release", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Book", null)
+ .WithMany("Releases")
+ .HasForeignKey("Release_Releases_Id");
+
+ b.HasOne("Jellyfin.Data.Entities.CustomItem", null)
+ .WithMany("Releases")
+ .HasForeignKey("Release_Releases_Id")
+ .HasConstraintName("FK_Release_LibraryItem_Release_Releases_Id1");
+
+ b.HasOne("Jellyfin.Data.Entities.Episode", null)
+ .WithMany("Releases")
+ .HasForeignKey("Release_Releases_Id")
+ .HasConstraintName("FK_Release_LibraryItem_Release_Releases_Id2");
+
+ b.HasOne("Jellyfin.Data.Entities.Movie", null)
+ .WithMany("Releases")
+ .HasForeignKey("Release_Releases_Id")
+ .HasConstraintName("FK_Release_LibraryItem_Release_Releases_Id3");
+
+ b.HasOne("Jellyfin.Data.Entities.Photo", null)
+ .WithMany("Releases")
+ .HasForeignKey("Release_Releases_Id")
+ .HasConstraintName("FK_Release_LibraryItem_Release_Releases_Id4");
+
+ b.HasOne("Jellyfin.Data.Entities.Track", null)
+ .WithMany("Releases")
+ .HasForeignKey("Release_Releases_Id")
+ .HasConstraintName("FK_Release_LibraryItem_Release_Releases_Id5");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Episode", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Season", null)
+ .WithMany("Episodes")
+ .HasForeignKey("Episode_Episodes_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Season", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Series", null)
+ .WithMany("Seasons")
+ .HasForeignKey("Season_Seasons_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Track", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.MusicAlbum", null)
+ .WithMany("Tracks")
+ .HasForeignKey("Track_Tracks_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.BookMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Book", null)
+ .WithMany("BookMetadata")
+ .HasForeignKey("BookMetadata_BookMetadata_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.CompanyMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Company", null)
+ .WithMany("CompanyMetadata")
+ .HasForeignKey("CompanyMetadata_CompanyMetadata_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.CustomItemMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.CustomItem", null)
+ .WithMany("CustomItemMetadata")
+ .HasForeignKey("CustomItemMetadata_CustomItemMetadata_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.EpisodeMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Episode", null)
+ .WithMany("EpisodeMetadata")
+ .HasForeignKey("EpisodeMetadata_EpisodeMetadata_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MovieMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Movie", null)
+ .WithMany("MovieMetadata")
+ .HasForeignKey("MovieMetadata_MovieMetadata_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.MusicAlbumMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.MusicAlbum", null)
+ .WithMany("MusicAlbumMetadata")
+ .HasForeignKey("MusicAlbumMetadata_MusicAlbumMetadata_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.PhotoMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Photo", null)
+ .WithMany("PhotoMetadata")
+ .HasForeignKey("PhotoMetadata_PhotoMetadata_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.SeasonMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Season", null)
+ .WithMany("SeasonMetadata")
+ .HasForeignKey("SeasonMetadata_SeasonMetadata_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.SeriesMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Series", null)
+ .WithMany("SeriesMetadata")
+ .HasForeignKey("SeriesMetadata_SeriesMetadata_Id");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.TrackMetadata", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.Track", null)
+ .WithMany("TrackMetadata")
+ .HasForeignKey("TrackMetadata_TrackMetadata_Id");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}