diff --git a/Jellyfin.Server.Implementations/Item/BaseItemMapper.cs b/Jellyfin.Server.Implementations/Item/BaseItemMapper.cs
index 736388e9eb..c64e6ac068 100644
--- a/Jellyfin.Server.Implementations/Item/BaseItemMapper.cs
+++ b/Jellyfin.Server.Implementations/Item/BaseItemMapper.cs
@@ -26,7 +26,7 @@ namespace Jellyfin.Server.Implementations.Item;
///
/// Handles mapping between BaseItemEntity (database) and BaseItemDto (domain) objects.
///
-internal static class BaseItemMapper
+public static class BaseItemMapper
{
///
/// This holds all the types in the running assemblies
diff --git a/Jellyfin.Server/GlobalSuppressions.cs b/Jellyfin.Server/GlobalSuppressions.cs
new file mode 100644
index 0000000000..676747e29f
--- /dev/null
+++ b/Jellyfin.Server/GlobalSuppressions.cs
@@ -0,0 +1,8 @@
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+
+using System.Diagnostics.CodeAnalysis;
+
+[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Migration files should follow the EFCore standard in regards to naming.", Scope = "namespaceanddescendants", Target = "~N:Jellyfin.Server.Migrations.Routines")]
diff --git a/Jellyfin.Server/Migrations/Routines/20260113230000_CleanupOrphanedExtras.cs b/Jellyfin.Server/Migrations/Routines/20260113230000_CleanupOrphanedExtras.cs
index 14abaa7317..f4dfa49068 100644
--- a/Jellyfin.Server/Migrations/Routines/20260113230000_CleanupOrphanedExtras.cs
+++ b/Jellyfin.Server/Migrations/Routines/20260113230000_CleanupOrphanedExtras.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Database.Implementations;
+using Jellyfin.Server.Implementations.Item;
using Jellyfin.Server.Migrations.Stages;
using Jellyfin.Server.ServerSetupApp;
using MediaBrowser.Controller.Channels;
@@ -23,7 +24,7 @@ namespace Jellyfin.Server.Migrations.Routines;
/// Removes orphaned extras (items with OwnerId pointing to non-existent items).
/// Must run before EF migrations that add FK constraints on OwnerId.
///
-[JellyfinMigration("2026-01-13T23:00:00", nameof(CleanupOrphanedExtras), Stage = JellyfinMigrationStageTypes.CoreInitialisation)]
+[JellyfinMigration("2026-01-13T23:00:00", nameof(CleanupOrphanedExtras), Stage = JellyfinMigrationStageTypes.AppInitialisation)]
[JellyfinMigrationBackup(JellyfinDb = true)]
public class CleanupOrphanedExtras : IAsyncMigrationRoutine
{
@@ -37,39 +38,14 @@ public class CleanupOrphanedExtras : IAsyncMigrationRoutine
/// The startup logger.
/// The database context factory.
/// The library manager.
- /// The item repository.
- /// The item count service.
- /// The channel manager.
- /// The recordings manager.
- /// The media source manager.
- /// The media segments manager.
- /// The configuration manager.
- /// The file system.
public CleanupOrphanedExtras(
IStartupLogger logger,
IDbContextFactory dbContextFactory,
- ILibraryManager libraryManager,
- IItemRepository itemRepository,
- IItemCountService itemCountService,
- IChannelManager channelManager,
- IRecordingsManager recordingsManager,
- IMediaSourceManager mediaSourceManager,
- IMediaSegmentManager mediaSegmentManager,
- IServerConfigurationManager configurationManager,
- IFileSystem fileSystem)
+ ILibraryManager libraryManager)
{
_logger = logger;
_dbContextFactory = dbContextFactory;
_libraryManager = libraryManager;
- BaseItem.LibraryManager ??= libraryManager;
- BaseItem.ItemRepository ??= itemRepository;
- BaseItem.ItemCountService ??= itemCountService;
- BaseItem.ChannelManager ??= channelManager;
- BaseItem.MediaSourceManager ??= mediaSourceManager;
- BaseItem.MediaSegmentManager ??= mediaSegmentManager;
- BaseItem.ConfigurationManager ??= configurationManager;
- BaseItem.FileSystem ??= fileSystem;
- Video.RecordingsManager ??= recordingsManager;
}
///
@@ -78,12 +54,19 @@ public class CleanupOrphanedExtras : IAsyncMigrationRoutine
var context = await _dbContextFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
await using (context.ConfigureAwait(false))
{
+ var placeholderOwner = Guid.Parse("00000000-0000-0000-0000-000000000001");
+#pragma warning disable RS0030 // Do not use banned APIs
var orphanedItemIds = await context.BaseItems
- .Where(b => b.OwnerId.HasValue && !b.OwnerId.Value.Equals(Guid.Empty))
- .Where(b => !context.BaseItems.Any(parent => parent.Id.Equals(b.OwnerId!.Value)))
- .Select(b => b.Id)
+ .Where(b => b.OwnerId.HasValue && b.OwnerId == placeholderOwner)
+ .Select(b => new
+ {
+ b.Id,
+ b.Path,
+ b.Type
+ })
.ToListAsync(cancellationToken)
.ConfigureAwait(false);
+#pragma warning restore RS0030 // Do not use banned APIs
if (orphanedItemIds.Count == 0)
{
@@ -97,11 +80,16 @@ public class CleanupOrphanedExtras : IAsyncMigrationRoutine
var itemsToDelete = new List();
foreach (var itemId in orphanedItemIds)
{
- var item = _libraryManager.GetItemById(itemId);
- if (item is not null)
- {
- itemsToDelete.Add(item);
- }
+ itemsToDelete.Add(BaseItemMapper.DeserializeBaseItem(
+ new Database.Implementations.Entities.BaseItemEntity()
+ {
+ Id = itemId.Id,
+ Path = itemId.Path,
+ Type = itemId.Type
+ },
+ _logger,
+ null,
+ true)!);
}
_libraryManager.DeleteItemsUnsafeFast(itemsToDelete);
diff --git a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260113233000_AddForeignKeyToOwnerId.Designer.cs b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260113233000_AddForeignKeyToOwnerId.Designer.cs
index 0e28abc862..f9cb9aa736 100644
--- a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260113233000_AddForeignKeyToOwnerId.Designer.cs
+++ b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260113233000_AddForeignKeyToOwnerId.Designer.cs
@@ -270,6 +270,9 @@ namespace Jellyfin.Database.Providers.Sqlite.Migrations
b.Property("OfficialRating")
.HasColumnType("TEXT");
+ b.Property("OriginalLanguage")
+ .HasColumnType("TEXT");
+
b.Property("OriginalTitle")
.HasColumnType("TEXT");
diff --git a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260113233000_AddForeignKeyToOwnerId.cs b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260113233000_AddForeignKeyToOwnerId.cs
index c84086d992..388906c064 100644
--- a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260113233000_AddForeignKeyToOwnerId.cs
+++ b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260113233000_AddForeignKeyToOwnerId.cs
@@ -23,12 +23,40 @@ namespace Jellyfin.Database.Providers.Sqlite.Migrations
name: "BaseItemEntityId",
table: "BaseItems");
+ migrationBuilder.Sql(
+ """
+ UPDATE BaseItems
+ SET OwnerId = '00000000-0000-0000-0000-000000000001'
+ WHERE OwnerId IS NOT NULL
+ AND OwnerId NOT IN (SELECT Id FROM BaseItems);
+ """);
+
migrationBuilder.AddForeignKey(
name: "FK_BaseItems_BaseItems_OwnerId",
table: "BaseItems",
column: "OwnerId",
principalTable: "BaseItems",
principalColumn: "Id");
+
+ migrationBuilder.AddColumn(
+ name: "IsOriginal",
+ table: "MediaStreamInfos",
+ type: "INTEGER",
+ nullable: false,
+ defaultValue: false);
+
+ migrationBuilder.AddColumn(
+ name: "OriginalLanguage",
+ table: "BaseItems",
+ type: "TEXT",
+ nullable: true);
+
+ migrationBuilder.UpdateData(
+ table: "BaseItems",
+ keyColumn: "Id",
+ keyValue: new Guid("00000000-0000-0000-0000-000000000001"),
+ column: "OriginalLanguage",
+ value: null);
}
///
@@ -62,6 +90,14 @@ namespace Jellyfin.Database.Providers.Sqlite.Migrations
column: "BaseItemEntityId",
principalTable: "BaseItems",
principalColumn: "Id");
+
+ migrationBuilder.DropColumn(
+ name: "IsOriginal",
+ table: "MediaStreamInfos");
+
+ migrationBuilder.DropColumn(
+ name: "OriginalLanguage",
+ table: "BaseItems");
}
}
}
diff --git a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260113233500_DropExtraIdsColumn.Designer.cs b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260113233500_DropExtraIdsColumn.Designer.cs
index 92ed0cf6bf..29874264af 100644
--- a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260113233500_DropExtraIdsColumn.Designer.cs
+++ b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260113233500_DropExtraIdsColumn.Designer.cs
@@ -267,6 +267,9 @@ namespace Jellyfin.Database.Providers.Sqlite.Migrations
b.Property("OfficialRating")
.HasColumnType("TEXT");
+ b.Property("OriginalLanguage")
+ .HasColumnType("TEXT");
+
b.Property("OriginalTitle")
.HasColumnType("TEXT");
diff --git a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260116114245_AddLatestItemsDateCreatedIndexes.Designer.cs b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260116114245_AddLatestItemsDateCreatedIndexes.Designer.cs
index 89fb3ee815..8282a8a582 100644
--- a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260116114245_AddLatestItemsDateCreatedIndexes.Designer.cs
+++ b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260116114245_AddLatestItemsDateCreatedIndexes.Designer.cs
@@ -267,6 +267,9 @@ namespace Jellyfin.Database.Providers.Sqlite.Migrations
b.Property("OfficialRating")
.HasColumnType("TEXT");
+ b.Property("OriginalLanguage")
+ .HasColumnType("TEXT");
+
b.Property("OriginalTitle")
.HasColumnType("TEXT");
diff --git a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260118182305_AddIndicesToImageInfo.Designer.cs b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260118182305_AddIndicesToImageInfo.Designer.cs
index 83a6a7baf3..5541a0191b 100644
--- a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260118182305_AddIndicesToImageInfo.Designer.cs
+++ b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260118182305_AddIndicesToImageInfo.Designer.cs
@@ -267,6 +267,9 @@ namespace Jellyfin.Database.Providers.Sqlite.Migrations
b.Property("OfficialRating")
.HasColumnType("TEXT");
+ b.Property("OriginalLanguage")
+ .HasColumnType("TEXT");
+
b.Property("OriginalTitle")
.HasColumnType("TEXT");
diff --git a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260130232147_AddBaseItemNameIndex.Designer.cs b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260130232147_AddBaseItemNameIndex.Designer.cs
index 1b396a707c..f6fd1db21e 100644
--- a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260130232147_AddBaseItemNameIndex.Designer.cs
+++ b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260130232147_AddBaseItemNameIndex.Designer.cs
@@ -267,6 +267,9 @@ namespace Jellyfin.Database.Providers.Sqlite.Migrations
b.Property("OfficialRating")
.HasColumnType("TEXT");
+ b.Property("OriginalLanguage")
+ .HasColumnType("TEXT");
+
b.Property("OriginalTitle")
.HasColumnType("TEXT");
diff --git a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260206224832_IndexOptimizations.Designer.cs b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260206224832_IndexOptimizations.Designer.cs
index ca995decde..5f7131ff65 100644
--- a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260206224832_IndexOptimizations.Designer.cs
+++ b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260206224832_IndexOptimizations.Designer.cs
@@ -267,6 +267,9 @@ namespace Jellyfin.Database.Providers.Sqlite.Migrations
b.Property("OfficialRating")
.HasColumnType("TEXT");
+ b.Property("OriginalLanguage")
+ .HasColumnType("TEXT");
+
b.Property("OriginalTitle")
.HasColumnType("TEXT");
diff --git a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260215201634_ChangePrimaryVersionIdToGuid.Designer.cs b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260215201634_ChangePrimaryVersionIdToGuid.Designer.cs
index 0184154566..0499921fec 100644
--- a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260215201634_ChangePrimaryVersionIdToGuid.Designer.cs
+++ b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260215201634_ChangePrimaryVersionIdToGuid.Designer.cs
@@ -267,6 +267,9 @@ namespace Jellyfin.Database.Providers.Sqlite.Migrations
b.Property("OfficialRating")
.HasColumnType("TEXT");
+ b.Property("OriginalLanguage")
+ .HasColumnType("TEXT");
+
b.Property("OriginalTitle")
.HasColumnType("TEXT");
diff --git a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260308123920_AddTypeCleanNameIndex.Designer.cs b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260308123920_AddTypeCleanNameIndex.Designer.cs
index 4c9ccc13bf..bf46ad9b39 100644
--- a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260308123920_AddTypeCleanNameIndex.Designer.cs
+++ b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260308123920_AddTypeCleanNameIndex.Designer.cs
@@ -267,6 +267,9 @@ namespace Jellyfin.Database.Providers.Sqlite.Migrations
b.Property("OfficialRating")
.HasColumnType("TEXT");
+ b.Property("OriginalLanguage")
+ .HasColumnType("TEXT");
+
b.Property("OriginalTitle")
.HasColumnType("TEXT");
diff --git a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260504075755_AddPartialIndexForItemCounts.Designer.cs b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260504075755_AddPartialIndexForItemCounts.Designer.cs
index 23ab2a4674..fc5c7afa0e 100644
--- a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260504075755_AddPartialIndexForItemCounts.Designer.cs
+++ b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260504075755_AddPartialIndexForItemCounts.Designer.cs
@@ -267,6 +267,9 @@ namespace Jellyfin.Database.Providers.Sqlite.Migrations
b.Property("OfficialRating")
.HasColumnType("TEXT");
+ b.Property("OriginalLanguage")
+ .HasColumnType("TEXT");
+
b.Property("OriginalTitle")
.HasColumnType("TEXT");
diff --git a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260504180809_AddOriginalLanguage.Designer.cs b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260504180809_AddOriginalLanguage.Designer.cs
deleted file mode 100644
index e0f5125da1..0000000000
--- a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260504180809_AddOriginalLanguage.Designer.cs
+++ /dev/null
@@ -1,1802 +0,0 @@
-//
-using System;
-using Jellyfin.Database.Implementations;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-
-#nullable disable
-
-namespace Jellyfin.Database.Providers.Sqlite.Migrations
-{
- [DbContext(typeof(JellyfinDbContext))]
- [Migration("20260504180809_AddOriginalLanguage")]
- partial class AddOriginalLanguage
- {
- ///
- protected override void BuildTargetModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder.HasAnnotation("ProductVersion", "10.0.7");
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.AccessSchedule", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER");
-
- b.Property("DayOfWeek")
- .HasColumnType("INTEGER");
-
- b.Property("EndHour")
- .HasColumnType("REAL");
-
- b.Property("StartHour")
- .HasColumnType("REAL");
-
- b.Property("UserId")
- .HasColumnType("TEXT");
-
- b.HasKey("Id");
-
- b.HasIndex("UserId");
-
- b.ToTable("AccessSchedules");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.ActivityLog", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER");
-
- b.Property("DateCreated")
- .HasColumnType("TEXT");
-
- b.Property("ItemId")
- .HasMaxLength(256)
- .HasColumnType("TEXT");
-
- b.Property("LogSeverity")
- .HasColumnType("INTEGER");
-
- b.Property("Name")
- .IsRequired()
- .HasMaxLength(512)
- .HasColumnType("TEXT");
-
- b.Property("Overview")
- .HasMaxLength(512)
- .HasColumnType("TEXT");
-
- b.Property("RowVersion")
- .IsConcurrencyToken()
- .HasColumnType("INTEGER");
-
- b.Property("ShortOverview")
- .HasMaxLength(512)
- .HasColumnType("TEXT");
-
- b.Property("Type")
- .IsRequired()
- .HasMaxLength(256)
- .HasColumnType("TEXT");
-
- b.Property("UserId")
- .HasColumnType("TEXT");
-
- b.HasKey("Id");
-
- b.HasIndex("DateCreated");
-
- b.ToTable("ActivityLogs");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.AncestorId", b =>
- {
- b.Property("ItemId")
- .HasColumnType("TEXT");
-
- b.Property("ParentItemId")
- .HasColumnType("TEXT");
-
- b.HasKey("ItemId", "ParentItemId");
-
- b.HasIndex("ParentItemId");
-
- b.ToTable("AncestorIds");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.AttachmentStreamInfo", b =>
- {
- b.Property("ItemId")
- .HasColumnType("TEXT");
-
- b.Property("Index")
- .HasColumnType("INTEGER");
-
- b.Property("Codec")
- .HasColumnType("TEXT");
-
- b.Property("CodecTag")
- .HasColumnType("TEXT");
-
- b.Property("Comment")
- .HasColumnType("TEXT");
-
- b.Property("Filename")
- .HasColumnType("TEXT");
-
- b.Property("MimeType")
- .HasColumnType("TEXT");
-
- b.HasKey("ItemId", "Index");
-
- b.ToTable("AttachmentStreamInfos");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.BaseItemEntity", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT");
-
- b.Property("Album")
- .HasColumnType("TEXT");
-
- b.Property("AlbumArtists")
- .HasColumnType("TEXT");
-
- b.Property("Artists")
- .HasColumnType("TEXT");
-
- b.Property("Audio")
- .HasColumnType("INTEGER");
-
- b.Property("ChannelId")
- .HasColumnType("TEXT");
-
- b.Property("CleanName")
- .HasColumnType("TEXT");
-
- b.Property("CommunityRating")
- .HasColumnType("REAL");
-
- b.Property("CriticRating")
- .HasColumnType("REAL");
-
- b.Property("CustomRating")
- .HasColumnType("TEXT");
-
- b.Property("Data")
- .HasColumnType("TEXT");
-
- b.Property("DateCreated")
- .HasColumnType("TEXT");
-
- b.Property("DateLastMediaAdded")
- .HasColumnType("TEXT");
-
- b.Property("DateLastRefreshed")
- .HasColumnType("TEXT");
-
- b.Property("DateLastSaved")
- .HasColumnType("TEXT");
-
- b.Property("DateModified")
- .HasColumnType("TEXT");
-
- b.Property("EndDate")
- .HasColumnType("TEXT");
-
- b.Property("EpisodeTitle")
- .HasColumnType("TEXT");
-
- b.Property("ExternalId")
- .HasColumnType("TEXT");
-
- b.Property("ExternalSeriesId")
- .HasColumnType("TEXT");
-
- b.Property("ExternalServiceId")
- .HasColumnType("TEXT");
-
- b.Property("ExtraType")
- .HasColumnType("INTEGER");
-
- b.Property("ForcedSortName")
- .HasColumnType("TEXT");
-
- b.Property("Genres")
- .HasColumnType("TEXT");
-
- b.Property("Height")
- .HasColumnType("INTEGER");
-
- b.Property("IndexNumber")
- .HasColumnType("INTEGER");
-
- b.Property("InheritedParentalRatingSubValue")
- .HasColumnType("INTEGER");
-
- b.Property("InheritedParentalRatingValue")
- .HasColumnType("INTEGER");
-
- b.Property("IsFolder")
- .HasColumnType("INTEGER");
-
- b.Property("IsInMixedFolder")
- .HasColumnType("INTEGER");
-
- b.Property("IsLocked")
- .HasColumnType("INTEGER");
-
- b.Property("IsMovie")
- .HasColumnType("INTEGER");
-
- b.Property("IsRepeat")
- .HasColumnType("INTEGER");
-
- b.Property("IsSeries")
- .HasColumnType("INTEGER");
-
- b.Property("IsVirtualItem")
- .HasColumnType("INTEGER");
-
- b.Property("LUFS")
- .HasColumnType("REAL");
-
- b.Property("MediaType")
- .HasColumnType("TEXT");
-
- b.Property("Name")
- .HasColumnType("TEXT");
-
- b.Property("NormalizationGain")
- .HasColumnType("REAL");
-
- b.Property("OfficialRating")
- .HasColumnType("TEXT");
-
- b.Property("OriginalLanguage")
- .HasColumnType("TEXT");
-
- b.Property("OriginalTitle")
- .HasColumnType("TEXT");
-
- b.Property("Overview")
- .HasColumnType("TEXT");
-
- b.Property("OwnerId")
- .HasColumnType("TEXT");
-
- b.Property("ParentId")
- .HasColumnType("TEXT");
-
- b.Property("ParentIndexNumber")
- .HasColumnType("INTEGER");
-
- b.Property("Path")
- .HasColumnType("TEXT");
-
- b.Property("PreferredMetadataCountryCode")
- .HasColumnType("TEXT");
-
- b.Property("PreferredMetadataLanguage")
- .HasColumnType("TEXT");
-
- b.Property("PremiereDate")
- .HasColumnType("TEXT");
-
- b.Property("PresentationUniqueKey")
- .HasColumnType("TEXT");
-
- b.Property("PrimaryVersionId")
- .HasColumnType("TEXT");
-
- b.Property("ProductionLocations")
- .HasColumnType("TEXT");
-
- b.Property("ProductionYear")
- .HasColumnType("INTEGER");
-
- b.Property("RunTimeTicks")
- .HasColumnType("INTEGER");
-
- b.Property("SeasonId")
- .HasColumnType("TEXT");
-
- b.Property("SeasonName")
- .HasColumnType("TEXT");
-
- b.Property("SeriesId")
- .HasColumnType("TEXT");
-
- b.Property("SeriesName")
- .HasColumnType("TEXT");
-
- b.Property("SeriesPresentationUniqueKey")
- .HasColumnType("TEXT");
-
- b.Property("ShowId")
- .HasColumnType("TEXT");
-
- b.Property("Size")
- .HasColumnType("INTEGER");
-
- b.Property("SortName")
- .HasColumnType("TEXT");
-
- b.Property("StartDate")
- .HasColumnType("TEXT");
-
- b.Property("Studios")
- .HasColumnType("TEXT");
-
- b.Property("Tagline")
- .HasColumnType("TEXT");
-
- b.Property("Tags")
- .HasColumnType("TEXT");
-
- b.Property("TopParentId")
- .HasColumnType("TEXT");
-
- b.Property("TotalBitrate")
- .HasColumnType("INTEGER");
-
- b.Property("Type")
- .IsRequired()
- .HasColumnType("TEXT");
-
- b.Property("UnratedType")
- .HasColumnType("TEXT");
-
- b.Property("Width")
- .HasColumnType("INTEGER");
-
- b.HasKey("Id");
-
- b.HasIndex("Name");
-
- b.HasIndex("OwnerId");
-
- b.HasIndex("ParentId");
-
- b.HasIndex("Path");
-
- b.HasIndex("PresentationUniqueKey");
-
- b.HasIndex("SeasonId");
-
- b.HasIndex("SeriesId");
-
- b.HasIndex("SeriesName");
-
- b.HasIndex("ExtraType", "OwnerId");
-
- b.HasIndex("TopParentId", "Id");
-
- b.HasIndex("Type", "CleanName");
-
- b.HasIndex("TopParentId", "Type", "IsVirtualItem")
- .HasFilter("\"PrimaryVersionId\" IS NULL AND (\"OwnerId\" IS NULL OR \"ExtraType\" IS NOT NULL)");
-
- b.HasIndex("Type", "TopParentId", "Id");
-
- b.HasIndex("Type", "TopParentId", "PresentationUniqueKey");
-
- b.HasIndex("Type", "TopParentId", "SortName");
-
- b.HasIndex("Type", "TopParentId", "StartDate");
-
- b.HasIndex("MediaType", "TopParentId", "IsVirtualItem", "PresentationUniqueKey");
-
- b.HasIndex("TopParentId", "IsFolder", "IsVirtualItem", "DateCreated");
-
- b.HasIndex("TopParentId", "MediaType", "IsVirtualItem", "DateCreated");
-
- b.HasIndex("TopParentId", "Type", "IsVirtualItem", "DateCreated");
-
- b.HasIndex("Type", "SeriesPresentationUniqueKey", "IsFolder", "IsVirtualItem");
-
- b.HasIndex("Type", "SeriesPresentationUniqueKey", "ParentIndexNumber", "IndexNumber");
-
- b.HasIndex("Type", "SeriesPresentationUniqueKey", "PresentationUniqueKey", "SortName");
-
- b.HasIndex("IsFolder", "TopParentId", "IsVirtualItem", "PresentationUniqueKey", "DateCreated");
-
- b.HasIndex("Type", "TopParentId", "IsVirtualItem", "PresentationUniqueKey", "DateCreated");
-
- b.ToTable("BaseItems");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
-
- b.HasData(
- new
- {
- Id = new Guid("00000000-0000-0000-0000-000000000001"),
- IsFolder = false,
- IsInMixedFolder = false,
- IsLocked = false,
- IsMovie = false,
- IsRepeat = false,
- IsSeries = false,
- IsVirtualItem = false,
- Name = "This is a placeholder item for UserData that has been detached from its original item",
- Type = "PLACEHOLDER"
- });
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.BaseItemImageInfo", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT");
-
- b.Property("Blurhash")
- .HasColumnType("BLOB");
-
- b.Property("DateModified")
- .HasColumnType("TEXT");
-
- b.Property("Height")
- .HasColumnType("INTEGER");
-
- b.Property("ImageType")
- .HasColumnType("INTEGER");
-
- b.Property("ItemId")
- .HasColumnType("TEXT");
-
- b.Property("Path")
- .IsRequired()
- .HasColumnType("TEXT");
-
- b.Property("Width")
- .HasColumnType("INTEGER");
-
- b.HasKey("Id");
-
- b.HasIndex("ItemId", "ImageType");
-
- b.ToTable("BaseItemImageInfos");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.BaseItemMetadataField", b =>
- {
- b.Property("Id")
- .HasColumnType("INTEGER");
-
- b.Property("ItemId")
- .HasColumnType("TEXT");
-
- b.HasKey("Id", "ItemId");
-
- b.HasIndex("ItemId");
-
- b.ToTable("BaseItemMetadataFields");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.BaseItemProvider", b =>
- {
- b.Property("ItemId")
- .HasColumnType("TEXT");
-
- b.Property("ProviderId")
- .HasColumnType("TEXT");
-
- b.Property("ProviderValue")
- .IsRequired()
- .HasColumnType("TEXT");
-
- b.HasKey("ItemId", "ProviderId");
-
- b.HasIndex("ProviderId", "ItemId", "ProviderValue");
-
- b.ToTable("BaseItemProviders");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.BaseItemTrailerType", b =>
- {
- b.Property("Id")
- .HasColumnType("INTEGER");
-
- b.Property("ItemId")
- .HasColumnType("TEXT");
-
- b.HasKey("Id", "ItemId");
-
- b.HasIndex("ItemId");
-
- b.ToTable("BaseItemTrailerTypes");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.Chapter", b =>
- {
- b.Property("ItemId")
- .HasColumnType("TEXT");
-
- b.Property("ChapterIndex")
- .HasColumnType("INTEGER");
-
- b.Property("ImageDateModified")
- .HasColumnType("TEXT");
-
- b.Property("ImagePath")
- .HasColumnType("TEXT");
-
- b.Property("Name")
- .HasColumnType("TEXT");
-
- b.Property("StartPositionTicks")
- .HasColumnType("INTEGER");
-
- b.HasKey("ItemId", "ChapterIndex");
-
- b.ToTable("Chapters");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.CustomItemDisplayPreferences", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER");
-
- b.Property("Client")
- .IsRequired()
- .HasMaxLength(32)
- .HasColumnType("TEXT");
-
- b.Property("ItemId")
- .HasColumnType("TEXT");
-
- b.Property("Key")
- .IsRequired()
- .HasColumnType("TEXT");
-
- b.Property("UserId")
- .HasColumnType("TEXT");
-
- b.Property("Value")
- .HasColumnType("TEXT");
-
- b.HasKey("Id");
-
- b.HasIndex("UserId", "ItemId", "Client", "Key")
- .IsUnique();
-
- b.ToTable("CustomItemDisplayPreferences");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.DisplayPreferences", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER");
-
- b.Property("ChromecastVersion")
- .HasColumnType("INTEGER");
-
- b.Property("Client")
- .IsRequired()
- .HasMaxLength(32)
- .HasColumnType("TEXT");
-
- b.Property("DashboardTheme")
- .HasMaxLength(32)
- .HasColumnType("TEXT");
-
- b.Property("EnableNextVideoInfoOverlay")
- .HasColumnType("INTEGER");
-
- b.Property("IndexBy")
- .HasColumnType("INTEGER");
-
- b.Property("ItemId")
- .HasColumnType("TEXT");
-
- b.Property("ScrollDirection")
- .HasColumnType("INTEGER");
-
- b.Property("ShowBackdrop")
- .HasColumnType("INTEGER");
-
- b.Property("ShowSidebar")
- .HasColumnType("INTEGER");
-
- b.Property("SkipBackwardLength")
- .HasColumnType("INTEGER");
-
- b.Property("SkipForwardLength")
- .HasColumnType("INTEGER");
-
- b.Property("TvHome")
- .HasMaxLength(32)
- .HasColumnType("TEXT");
-
- b.Property("UserId")
- .HasColumnType("TEXT");
-
- b.HasKey("Id");
-
- b.HasIndex("UserId", "ItemId", "Client")
- .IsUnique();
-
- b.ToTable("DisplayPreferences");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.HomeSection", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER");
-
- b.Property("DisplayPreferencesId")
- .HasColumnType("INTEGER");
-
- b.Property("Order")
- .HasColumnType("INTEGER");
-
- b.Property("Type")
- .HasColumnType("INTEGER");
-
- b.HasKey("Id");
-
- b.HasIndex("DisplayPreferencesId");
-
- b.ToTable("HomeSection");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.ImageInfo", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER");
-
- b.Property("LastModified")
- .HasColumnType("TEXT");
-
- b.Property("Path")
- .IsRequired()
- .HasMaxLength(512)
- .HasColumnType("TEXT");
-
- b.Property("UserId")
- .HasColumnType("TEXT");
-
- b.HasKey("Id");
-
- b.HasIndex("UserId")
- .IsUnique();
-
- b.ToTable("ImageInfos");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.ItemDisplayPreferences", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER");
-
- b.Property("Client")
- .IsRequired()
- .HasMaxLength(32)
- .HasColumnType("TEXT");
-
- b.Property("IndexBy")
- .HasColumnType("INTEGER");
-
- b.Property("ItemId")
- .HasColumnType("TEXT");
-
- b.Property("RememberIndexing")
- .HasColumnType("INTEGER");
-
- b.Property("RememberSorting")
- .HasColumnType("INTEGER");
-
- b.Property("SortBy")
- .IsRequired()
- .HasMaxLength(64)
- .HasColumnType("TEXT");
-
- b.Property("SortOrder")
- .HasColumnType("INTEGER");
-
- b.Property("UserId")
- .HasColumnType("TEXT");
-
- b.Property("ViewType")
- .HasColumnType("INTEGER");
-
- b.HasKey("Id");
-
- b.HasIndex("UserId");
-
- b.ToTable("ItemDisplayPreferences");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.ItemValue", b =>
- {
- b.Property("ItemValueId")
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT");
-
- b.Property("CleanValue")
- .IsRequired()
- .HasColumnType("TEXT");
-
- b.Property("Type")
- .HasColumnType("INTEGER");
-
- b.Property("Value")
- .IsRequired()
- .HasColumnType("TEXT");
-
- b.HasKey("ItemValueId");
-
- b.HasIndex("Type", "CleanValue");
-
- b.HasIndex("Type", "Value")
- .IsUnique();
-
- b.ToTable("ItemValues");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.ItemValueMap", b =>
- {
- b.Property("ItemValueId")
- .HasColumnType("TEXT");
-
- b.Property("ItemId")
- .HasColumnType("TEXT");
-
- b.HasKey("ItemValueId", "ItemId");
-
- b.HasIndex("ItemId");
-
- b.ToTable("ItemValuesMap");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.KeyframeData", b =>
- {
- b.Property("ItemId")
- .HasColumnType("TEXT");
-
- b.PrimitiveCollection("KeyframeTicks")
- .HasColumnType("TEXT");
-
- b.Property("TotalDuration")
- .HasColumnType("INTEGER");
-
- b.HasKey("ItemId");
-
- b.ToTable("KeyframeData");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.LinkedChildEntity", b =>
- {
- b.Property("ParentId")
- .HasColumnType("TEXT");
-
- b.Property("ChildId")
- .HasColumnType("TEXT");
-
- b.Property("ChildType")
- .HasColumnType("INTEGER");
-
- b.Property("SortOrder")
- .HasColumnType("INTEGER");
-
- b.HasKey("ParentId", "ChildId");
-
- b.HasIndex("ChildId", "ChildType");
-
- b.HasIndex("ParentId", "ChildType");
-
- b.HasIndex("ParentId", "SortOrder");
-
- b.ToTable("LinkedChildren", (string)null);
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.MediaSegment", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT");
-
- b.Property("EndTicks")
- .HasColumnType("INTEGER");
-
- b.Property("ItemId")
- .HasColumnType("TEXT");
-
- b.Property("SegmentProviderId")
- .IsRequired()
- .HasColumnType("TEXT");
-
- b.Property("StartTicks")
- .HasColumnType("INTEGER");
-
- b.Property("Type")
- .HasColumnType("INTEGER");
-
- b.HasKey("Id");
-
- b.ToTable("MediaSegments");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.MediaStreamInfo", b =>
- {
- b.Property("ItemId")
- .HasColumnType("TEXT");
-
- b.Property("StreamIndex")
- .HasColumnType("INTEGER");
-
- b.Property("AspectRatio")
- .HasColumnType("TEXT");
-
- b.Property("AverageFrameRate")
- .HasColumnType("REAL");
-
- b.Property("BitDepth")
- .HasColumnType("INTEGER");
-
- b.Property("BitRate")
- .HasColumnType("INTEGER");
-
- b.Property("BlPresentFlag")
- .HasColumnType("INTEGER");
-
- b.Property("ChannelLayout")
- .HasColumnType("TEXT");
-
- b.Property("Channels")
- .HasColumnType("INTEGER");
-
- b.Property("Codec")
- .HasColumnType("TEXT");
-
- b.Property("CodecTag")
- .HasColumnType("TEXT");
-
- b.Property("CodecTimeBase")
- .HasColumnType("TEXT");
-
- b.Property("ColorPrimaries")
- .HasColumnType("TEXT");
-
- b.Property("ColorSpace")
- .HasColumnType("TEXT");
-
- b.Property("ColorTransfer")
- .HasColumnType("TEXT");
-
- b.Property("Comment")
- .HasColumnType("TEXT");
-
- b.Property("DvBlSignalCompatibilityId")
- .HasColumnType("INTEGER");
-
- b.Property("DvLevel")
- .HasColumnType("INTEGER");
-
- b.Property("DvProfile")
- .HasColumnType("INTEGER");
-
- b.Property("DvVersionMajor")
- .HasColumnType("INTEGER");
-
- b.Property("DvVersionMinor")
- .HasColumnType("INTEGER");
-
- b.Property("ElPresentFlag")
- .HasColumnType("INTEGER");
-
- b.Property("Hdr10PlusPresentFlag")
- .HasColumnType("INTEGER");
-
- b.Property("Height")
- .HasColumnType("INTEGER");
-
- b.Property("IsAnamorphic")
- .HasColumnType("INTEGER");
-
- b.Property("IsAvc")
- .HasColumnType("INTEGER");
-
- b.Property("IsDefault")
- .HasColumnType("INTEGER");
-
- b.Property("IsExternal")
- .HasColumnType("INTEGER");
-
- b.Property("IsForced")
- .HasColumnType("INTEGER");
-
- b.Property("IsHearingImpaired")
- .HasColumnType("INTEGER");
-
- b.Property("IsInterlaced")
- .HasColumnType("INTEGER");
-
- b.Property("IsOriginal")
- .HasColumnType("INTEGER");
-
- b.Property("KeyFrames")
- .HasColumnType("TEXT");
-
- b.Property("Language")
- .HasColumnType("TEXT");
-
- b.Property("Level")
- .HasColumnType("REAL");
-
- b.Property("NalLengthSize")
- .HasColumnType("TEXT");
-
- b.Property("Path")
- .HasColumnType("TEXT");
-
- b.Property("PixelFormat")
- .HasColumnType("TEXT");
-
- b.Property("Profile")
- .HasColumnType("TEXT");
-
- b.Property("RealFrameRate")
- .HasColumnType("REAL");
-
- b.Property("RefFrames")
- .HasColumnType("INTEGER");
-
- b.Property("Rotation")
- .HasColumnType("INTEGER");
-
- b.Property("RpuPresentFlag")
- .HasColumnType("INTEGER");
-
- b.Property("SampleRate")
- .HasColumnType("INTEGER");
-
- b.Property("StreamType")
- .HasColumnType("INTEGER");
-
- b.Property("TimeBase")
- .HasColumnType("TEXT");
-
- b.Property("Title")
- .HasColumnType("TEXT");
-
- b.Property("Width")
- .HasColumnType("INTEGER");
-
- b.HasKey("ItemId", "StreamIndex");
-
- b.ToTable("MediaStreamInfos");
-
- b.HasAnnotation("Sqlite:UseSqlReturningClause", false);
- });
-
- modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.People", b =>
- {
- b.Property