diff options
| author | JPVenson <github@jpb.email> | 2026-05-15 20:10:33 +0000 |
|---|---|---|
| committer | JPVenson <github@jpb.email> | 2026-05-15 20:10:33 +0000 |
| commit | 9d20aefd89f5b7990f3d6809e4f49f10fad4d77f (patch) | |
| tree | 9dc8bff28bb874c559bfc6a185a67df5b0b8312c | |
| parent | f73fc1feb2f2204ac8c27b1162ec0724529f2d7c (diff) | |
Reorder migration handling for extra column
15 files changed, 95 insertions, 1885 deletions
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; /// <summary> /// Handles mapping between BaseItemEntity (database) and BaseItemDto (domain) objects. /// </summary> -internal static class BaseItemMapper +public static class BaseItemMapper { /// <summary> /// 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. /// </summary> -[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 /// <param name="logger">The startup logger.</param> /// <param name="dbContextFactory">The database context factory.</param> /// <param name="libraryManager">The library manager.</param> - /// <param name="itemRepository">The item repository.</param> - /// <param name="itemCountService">The item count service.</param> - /// <param name="channelManager">The channel manager.</param> - /// <param name="recordingsManager">The recordings manager.</param> - /// <param name="mediaSourceManager">The media source manager.</param> - /// <param name="mediaSegmentManager">The media segments manager.</param> - /// <param name="configurationManager">The configuration manager.</param> - /// <param name="fileSystem">The file system.</param> public CleanupOrphanedExtras( IStartupLogger<CleanupOrphanedExtras> logger, IDbContextFactory<JellyfinDbContext> 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; } /// <inheritdoc/> @@ -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<BaseItem>(); 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<string>("OfficialRating") .HasColumnType("TEXT"); + b.Property<string>("OriginalLanguage") + .HasColumnType("TEXT"); + b.Property<string>("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<bool>( + name: "IsOriginal", + table: "MediaStreamInfos", + type: "INTEGER", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn<string>( + 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); } /// <inheritdoc /> @@ -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<string>("OfficialRating") .HasColumnType("TEXT"); + b.Property<string>("OriginalLanguage") + .HasColumnType("TEXT"); + b.Property<string>("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<string>("OfficialRating") .HasColumnType("TEXT"); + b.Property<string>("OriginalLanguage") + .HasColumnType("TEXT"); + b.Property<string>("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<string>("OfficialRating") .HasColumnType("TEXT"); + b.Property<string>("OriginalLanguage") + .HasColumnType("TEXT"); + b.Property<string>("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<string>("OfficialRating") .HasColumnType("TEXT"); + b.Property<string>("OriginalLanguage") + .HasColumnType("TEXT"); + b.Property<string>("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<string>("OfficialRating") .HasColumnType("TEXT"); + b.Property<string>("OriginalLanguage") + .HasColumnType("TEXT"); + b.Property<string>("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<string>("OfficialRating") .HasColumnType("TEXT"); + b.Property<string>("OriginalLanguage") + .HasColumnType("TEXT"); + b.Property<string>("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<string>("OfficialRating") .HasColumnType("TEXT"); + b.Property<string>("OriginalLanguage") + .HasColumnType("TEXT"); + b.Property<string>("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<string>("OfficialRating") .HasColumnType("TEXT"); + b.Property<string>("OriginalLanguage") + .HasColumnType("TEXT"); + b.Property<string>("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 @@ -// <auto-generated /> -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 - { - /// <inheritdoc /> - 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<int>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property<int>("DayOfWeek") - .HasColumnType("INTEGER"); - - b.Property<double>("EndHour") - .HasColumnType("REAL"); - - b.Property<double>("StartHour") - .HasColumnType("REAL"); - - b.Property<Guid>("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<int>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property<DateTime>("DateCreated") - .HasColumnType("TEXT"); - - b.Property<string>("ItemId") - .HasMaxLength(256) - .HasColumnType("TEXT"); - - b.Property<int>("LogSeverity") - .HasColumnType("INTEGER"); - - b.Property<string>("Name") - .IsRequired() - .HasMaxLength(512) - .HasColumnType("TEXT"); - - b.Property<string>("Overview") - .HasMaxLength(512) - .HasColumnType("TEXT"); - - b.Property<uint>("RowVersion") - .IsConcurrencyToken() - .HasColumnType("INTEGER"); - - b.Property<string>("ShortOverview") - .HasMaxLength(512) - .HasColumnType("TEXT"); - - b.Property<string>("Type") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("TEXT"); - - b.Property<Guid>("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<Guid>("ItemId") - .HasColumnType("TEXT"); - - b.Property<Guid>("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<Guid>("ItemId") - .HasColumnType("TEXT"); - - b.Property<int>("Index") - .HasColumnType("INTEGER"); - - b.Property<string>("Codec") - .HasColumnType("TEXT"); - - b.Property<string>("CodecTag") - .HasColumnType("TEXT"); - - b.Property<string>("Comment") - .HasColumnType("TEXT"); - - b.Property<string>("Filename") - .HasColumnType("TEXT"); - - b.Property<string>("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<Guid>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property<string>("Album") - .HasColumnType("TEXT"); - - b.Property<string>("AlbumArtists") - .HasColumnType("TEXT"); - - b.Property<string>("Artists") - .HasColumnType("TEXT"); - - b.Property<int?>("Audio") - .HasColumnType("INTEGER"); - - b.Property<Guid?>("ChannelId") - .HasColumnType("TEXT"); - - b.Property<string>("CleanName") - .HasColumnType("TEXT"); - - b.Property<float?>("CommunityRating") - .HasColumnType("REAL"); - - b.Property<float?>("CriticRating") - .HasColumnType("REAL"); - - b.Property<string>("CustomRating") - .HasColumnType("TEXT"); - - b.Property<string>("Data") - .HasColumnType("TEXT"); - - b.Property<DateTime?>("DateCreated") - .HasColumnType("TEXT"); - - b.Property<DateTime?>("DateLastMediaAdded") - .HasColumnType("TEXT"); - - b.Property<DateTime?>("DateLastRefreshed") - .HasColumnType("TEXT"); - - b.Property<DateTime?>("DateLastSaved") - .HasColumnType("TEXT"); - - b.Property<DateTime?>("DateModified") - .HasColumnType("TEXT"); - - b.Property<DateTime?>("EndDate") - .HasColumnType("TEXT"); - - b.Property<string>("EpisodeTitle") - .HasColumnType("TEXT"); - - b.Property<string>("ExternalId") - .HasColumnType("TEXT"); - - b.Property<string>("ExternalSeriesId") - .HasColumnType("TEXT"); - - b.Property<string>("ExternalServiceId") - .HasColumnType("TEXT"); - - b.Property<int?>("ExtraType") - .HasColumnType("INTEGER"); - - b.Property<string>("ForcedSortName") - .HasColumnType("TEXT"); - - b.Property<string>("Genres") - .HasColumnType("TEXT"); - - b.Property<int?>("Height") - .HasColumnType("INTEGER"); - - b.Property<int?>("IndexNumber") - .HasColumnType("INTEGER"); - - b.Property<int?>("InheritedParentalRatingSubValue") - .HasColumnType("INTEGER"); - - b.Property<int?>("InheritedParentalRatingValue") - .HasColumnType("INTEGER"); - - b.Property<bool>("IsFolder") - .HasColumnType("INTEGER"); - - b.Property<bool>("IsInMixedFolder") - .HasColumnType("INTEGER"); - - b.Property<bool>("IsLocked") - .HasColumnType("INTEGER"); - - b.Property<bool>("IsMovie") - .HasColumnType("INTEGER"); - - b.Property<bool>("IsRepeat") - .HasColumnType("INTEGER"); - - b.Property<bool>("IsSeries") - .HasColumnType("INTEGER"); - - b.Property<bool>("IsVirtualItem") - .HasColumnType("INTEGER"); - - b.Property<float?>("LUFS") - .HasColumnType("REAL"); - - b.Property<string>("MediaType") - .HasColumnType("TEXT"); - - b.Property<string>("Name") - .HasColumnType("TEXT"); - - b.Property<float?>("NormalizationGain") - .HasColumnType("REAL"); - - b.Property<string>("OfficialRating") - .HasColumnType("TEXT"); - - b.Property<string>("OriginalLanguage") - .HasColumnType("TEXT"); - - b.Property<string>("OriginalTitle") - .HasColumnType("TEXT"); - - b.Property<string>("Overview") - .HasColumnType("TEXT"); - - b.Property<Guid?>("OwnerId") - .HasColumnType("TEXT"); - - b.Property<Guid?>("ParentId") - .HasColumnType("TEXT"); - - b.Property<int?>("ParentIndexNumber") - .HasColumnType("INTEGER"); - - b.Property<string>("Path") - .HasColumnType("TEXT"); - - b.Property<string>("PreferredMetadataCountryCode") - .HasColumnType("TEXT"); - - b.Property<string>("PreferredMetadataLanguage") - .HasColumnType("TEXT"); - - b.Property<DateTime?>("PremiereDate") - .HasColumnType("TEXT"); - - b.Property<string>("PresentationUniqueKey") - .HasColumnType("TEXT"); - - b.Property<Guid?>("PrimaryVersionId") - .HasColumnType("TEXT"); - - b.Property<string>("ProductionLocations") - .HasColumnType("TEXT"); - - b.Property<int?>("ProductionYear") - .HasColumnType("INTEGER"); - - b.Property<long?>("RunTimeTicks") - .HasColumnType("INTEGER"); - - b.Property<Guid?>("SeasonId") - .HasColumnType("TEXT"); - - b.Property<string>("SeasonName") - .HasColumnType("TEXT"); - - b.Property<Guid?>("SeriesId") - .HasColumnType("TEXT"); - - b.Property<string>("SeriesName") - .HasColumnType("TEXT"); - - b.Property<string>("SeriesPresentationUniqueKey") - .HasColumnType("TEXT"); - - b.Property<string>("ShowId") - .HasColumnType("TEXT"); - - b.Property<long?>("Size") - .HasColumnType("INTEGER"); - - b.Property<string>("SortName") - .HasColumnType("TEXT"); - - b.Property<DateTime?>("StartDate") - .HasColumnType("TEXT"); - - b.Property<string>("Studios") - .HasColumnType("TEXT"); - - b.Property<string>("Tagline") - .HasColumnType("TEXT"); - - b.Property<string>("Tags") - .HasColumnType("TEXT"); - - b.Property<Guid?>("TopParentId") - .HasColumnType("TEXT"); - - b.Property<int?>("TotalBitrate") - .HasColumnType("INTEGER"); - - b.Property<string>("Type") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property<string>("UnratedType") - .HasColumnType("TEXT"); - - b.Property<int?>("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<Guid>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property<byte[]>("Blurhash") - .HasColumnType("BLOB"); - - b.Property<DateTime?>("DateModified") - .HasColumnType("TEXT"); - - b.Property<int>("Height") - .HasColumnType("INTEGER"); - - b.Property<int>("ImageType") - .HasColumnType("INTEGER"); - - b.Property<Guid>("ItemId") - .HasColumnType("TEXT"); - - b.Property<string>("Path") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property<int>("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<int>("Id") - .HasColumnType("INTEGER"); - - b.Property<Guid>("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<Guid>("ItemId") - .HasColumnType("TEXT"); - - b.Property<string>("ProviderId") - .HasColumnType("TEXT"); - - b.Property<string>("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<int>("Id") - .HasColumnType("INTEGER"); - - b.Property<Guid>("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<Guid>("ItemId") - .HasColumnType("TEXT"); - - b.Property<int>("ChapterIndex") - .HasColumnType("INTEGER"); - - b.Property<DateTime?>("ImageDateModified") - .HasColumnType("TEXT"); - - b.Property<string>("ImagePath") - .HasColumnType("TEXT"); - - b.Property<string>("Name") - .HasColumnType("TEXT"); - - b.Property<long>("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<int>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property<string>("Client") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("TEXT"); - - b.Property<Guid>("ItemId") - .HasColumnType("TEXT"); - - b.Property<string>("Key") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property<Guid>("UserId") - .HasColumnType("TEXT"); - - b.Property<string>("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<int>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property<int>("ChromecastVersion") - .HasColumnType("INTEGER"); - - b.Property<string>("Client") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("TEXT"); - - b.Property<string>("DashboardTheme") - .HasMaxLength(32) - .HasColumnType("TEXT"); - - b.Property<bool>("EnableNextVideoInfoOverlay") - .HasColumnType("INTEGER"); - - b.Property<int?>("IndexBy") - .HasColumnType("INTEGER"); - - b.Property<Guid>("ItemId") - .HasColumnType("TEXT"); - - b.Property<int>("ScrollDirection") - .HasColumnType("INTEGER"); - - b.Property<bool>("ShowBackdrop") - .HasColumnType("INTEGER"); - - b.Property<bool>("ShowSidebar") - .HasColumnType("INTEGER"); - - b.Property<int>("SkipBackwardLength") - .HasColumnType("INTEGER"); - - b.Property<int>("SkipForwardLength") - .HasColumnType("INTEGER"); - - b.Property<string>("TvHome") - .HasMaxLength(32) - .HasColumnType("TEXT"); - - b.Property<Guid>("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<int>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property<int>("DisplayPreferencesId") - .HasColumnType("INTEGER"); - - b.Property<int>("Order") - .HasColumnType("INTEGER"); - - b.Property<int>("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<int>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property<DateTime>("LastModified") - .HasColumnType("TEXT"); - - b.Property<string>("Path") - .IsRequired() - .HasMaxLength(512) - .HasColumnType("TEXT"); - - b.Property<Guid?>("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<int>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property<string>("Client") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("TEXT"); - - b.Property<int?>("IndexBy") - .HasColumnType("INTEGER"); - - b.Property<Guid>("ItemId") - .HasColumnType("TEXT"); - - b.Property<bool>("RememberIndexing") - .HasColumnType("INTEGER"); - - b.Property<bool>("RememberSorting") - .HasColumnType("INTEGER"); - - b.Property<string>("SortBy") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("TEXT"); - - b.Property<int>("SortOrder") - .HasColumnType("INTEGER"); - - b.Property<Guid>("UserId") - .HasColumnType("TEXT"); - - b.Property<int>("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<Guid>("ItemValueId") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property<string>("CleanValue") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property<int>("Type") - .HasColumnType("INTEGER"); - - b.Property<string>("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<Guid>("ItemValueId") - .HasColumnType("TEXT"); - - b.Property<Guid>("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<Guid>("ItemId") - .HasColumnType("TEXT"); - - b.PrimitiveCollection<string>("KeyframeTicks") - .HasColumnType("TEXT"); - - b.Property<long>("TotalDuration") - .HasColumnType("INTEGER"); - - b.HasKey("ItemId"); - - b.ToTable("KeyframeData"); - - b.HasAnnotation("Sqlite:UseSqlReturningClause", false); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.LinkedChildEntity", b => - { - b.Property<Guid>("ParentId") - .HasColumnType("TEXT"); - - b.Property<Guid>("ChildId") - .HasColumnType("TEXT"); - - b.Property<int>("ChildType") - .HasColumnType("INTEGER"); - - b.Property<int?>("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<Guid>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property<long>("EndTicks") - .HasColumnType("INTEGER"); - - b.Property<Guid>("ItemId") - .HasColumnType("TEXT"); - - b.Property<string>("SegmentProviderId") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property<long>("StartTicks") - .HasColumnType("INTEGER"); - - b.Property<int>("Type") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.ToTable("MediaSegments"); - - b.HasAnnotation("Sqlite:UseSqlReturningClause", false); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.MediaStreamInfo", b => - { - b.Property<Guid>("ItemId") - .HasColumnType("TEXT"); - - b.Property<int>("StreamIndex") - .HasColumnType("INTEGER"); - - b.Property<string>("AspectRatio") - .HasColumnType("TEXT"); - - b.Property<float?>("AverageFrameRate") - .HasColumnType("REAL"); - - b.Property<int?>("BitDepth") - .HasColumnType("INTEGER"); - - b.Property<int?>("BitRate") - .HasColumnType("INTEGER"); - - b.Property<int?>("BlPresentFlag") - .HasColumnType("INTEGER"); - - b.Property<string>("ChannelLayout") - .HasColumnType("TEXT"); - - b.Property<int?>("Channels") - .HasColumnType("INTEGER"); - - b.Property<string>("Codec") - .HasColumnType("TEXT"); - - b.Property<string>("CodecTag") - .HasColumnType("TEXT"); - - b.Property<string>("CodecTimeBase") - .HasColumnType("TEXT"); - - b.Property<string>("ColorPrimaries") - .HasColumnType("TEXT"); - - b.Property<string>("ColorSpace") - .HasColumnType("TEXT"); - - b.Property<string>("ColorTransfer") - .HasColumnType("TEXT"); - - b.Property<string>("Comment") - .HasColumnType("TEXT"); - - b.Property<int?>("DvBlSignalCompatibilityId") - .HasColumnType("INTEGER"); - - b.Property<int?>("DvLevel") - .HasColumnType("INTEGER"); - - b.Property<int?>("DvProfile") - .HasColumnType("INTEGER"); - - b.Property<int?>("DvVersionMajor") - .HasColumnType("INTEGER"); - - b.Property<int?>("DvVersionMinor") - .HasColumnType("INTEGER"); - - b.Property<int?>("ElPresentFlag") - .HasColumnType("INTEGER"); - - b.Property<bool?>("Hdr10PlusPresentFlag") - .HasColumnType("INTEGER"); - - b.Property<int?>("Height") - .HasColumnType("INTEGER"); - - b.Property<bool?>("IsAnamorphic") - .HasColumnType("INTEGER"); - - b.Property<bool?>("IsAvc") - .HasColumnType("INTEGER"); - - b.Property<bool>("IsDefault") - .HasColumnType("INTEGER"); - - b.Property<bool>("IsExternal") - .HasColumnType("INTEGER"); - - b.Property<bool>("IsForced") - .HasColumnType("INTEGER"); - - b.Property<bool?>("IsHearingImpaired") - .HasColumnType("INTEGER"); - - b.Property<bool?>("IsInterlaced") - .HasColumnType("INTEGER"); - - b.Property<bool>("IsOriginal") - .HasColumnType("INTEGER"); - - b.Property<string>("KeyFrames") - .HasColumnType("TEXT"); - - b.Property<string>("Language") - .HasColumnType("TEXT"); - - b.Property<float?>("Level") - .HasColumnType("REAL"); - - b.Property<string>("NalLengthSize") - .HasColumnType("TEXT"); - - b.Property<string>("Path") - .HasColumnType("TEXT"); - - b.Property<string>("PixelFormat") - .HasColumnType("TEXT"); - - b.Property<string>("Profile") - .HasColumnType("TEXT"); - - b.Property<float?>("RealFrameRate") - .HasColumnType("REAL"); - - b.Property<int?>("RefFrames") - .HasColumnType("INTEGER"); - - b.Property<int?>("Rotation") - .HasColumnType("INTEGER"); - - b.Property<int?>("RpuPresentFlag") - .HasColumnType("INTEGER"); - - b.Property<int?>("SampleRate") - .HasColumnType("INTEGER"); - - b.Property<int>("StreamType") - .HasColumnType("INTEGER"); - - b.Property<string>("TimeBase") - .HasColumnType("TEXT"); - - b.Property<string>("Title") - .HasColumnType("TEXT"); - - b.Property<int?>("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<Guid>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property<string>("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property<string>("PersonType") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("Name"); - - b.ToTable("Peoples"); - - b.HasAnnotation("Sqlite:UseSqlReturningClause", false); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.PeopleBaseItemMap", b => - { - b.Property<Guid>("ItemId") - .HasColumnType("TEXT"); - - b.Property<Guid>("PeopleId") - .HasColumnType("TEXT"); - - b.Property<string>("Role") - .HasColumnType("TEXT"); - - b.Property<int?>("ListOrder") - .HasColumnType("INTEGER"); - - b.Property<int?>("SortOrder") - .HasColumnType("INTEGER"); - - b.HasKey("ItemId", "PeopleId", "Role"); - - b.HasIndex("PeopleId"); - - b.HasIndex("ItemId", "ListOrder"); - - b.HasIndex("ItemId", "SortOrder"); - - b.ToTable("PeopleBaseItemMap"); - - b.HasAnnotation("Sqlite:UseSqlReturningClause", false); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.Permission", b => - { - b.Property<int>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property<int>("Kind") - .HasColumnType("INTEGER"); - - b.Property<Guid?>("Permission_Permissions_Guid") - .HasColumnType("TEXT"); - - b.Property<uint>("RowVersion") - .IsConcurrencyToken() - .HasColumnType("INTEGER"); - - b.Property<Guid?>("UserId") - .HasColumnType("TEXT"); - - b.Property<bool>("Value") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("UserId", "Kind") - .IsUnique() - .HasFilter("[UserId] IS NOT NULL"); - - b.ToTable("Permissions"); - - b.HasAnnotation("Sqlite:UseSqlReturningClause", false); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.Preference", b => - { - b.Property<int>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property<int>("Kind") - .HasColumnType("INTEGER"); - - b.Property<Guid?>("Preference_Preferences_Guid") - .HasColumnType("TEXT"); - - b.Property<uint>("RowVersion") - .IsConcurrencyToken() - .HasColumnType("INTEGER"); - - b.Property<Guid?>("UserId") - .HasColumnType("TEXT"); - - b.Property<string>("Value") - .IsRequired() - .HasMaxLength(65535) - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("UserId", "Kind") - .IsUnique() - .HasFilter("[UserId] IS NOT NULL"); - - b.ToTable("Preferences"); - - b.HasAnnotation("Sqlite:UseSqlReturningClause", false); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.Security.ApiKey", b => - { - b.Property<int>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property<string>("AccessToken") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property<DateTime>("DateCreated") - .HasColumnType("TEXT"); - - b.Property<DateTime>("DateLastActivity") - .HasColumnType("TEXT"); - - b.Property<string>("Name") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("AccessToken") - .IsUnique(); - - b.ToTable("ApiKeys"); - - b.HasAnnotation("Sqlite:UseSqlReturningClause", false); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.Security.Device", b => - { - b.Property<int>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property<string>("AccessToken") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property<string>("AppName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("TEXT"); - - b.Property<string>("AppVersion") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("TEXT"); - - b.Property<DateTime>("DateCreated") - .HasColumnType("TEXT"); - - b.Property<DateTime>("DateLastActivity") - .HasColumnType("TEXT"); - - b.Property<DateTime>("DateModified") - .HasColumnType("TEXT"); - - b.Property<string>("DeviceId") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("TEXT"); - - b.Property<string>("DeviceName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("TEXT"); - - b.Property<bool>("IsActive") - .HasColumnType("INTEGER"); - - b.Property<Guid>("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("AccessToken", "DateLastActivity"); - - b.HasIndex("DeviceId", "DateLastActivity"); - - b.HasIndex("UserId", "DeviceId"); - - b.ToTable("Devices"); - - b.HasAnnotation("Sqlite:UseSqlReturningClause", false); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.Security.DeviceOptions", b => - { - b.Property<int>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property<string>("CustomName") - .HasColumnType("TEXT"); - - b.Property<string>("DeviceId") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("DeviceId") - .IsUnique(); - - b.ToTable("DeviceOptions"); - - b.HasAnnotation("Sqlite:UseSqlReturningClause", false); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.TrickplayInfo", b => - { - b.Property<Guid>("ItemId") - .HasColumnType("TEXT"); - - b.Property<int>("Width") - .HasColumnType("INTEGER"); - - b.Property<int>("Bandwidth") - .HasColumnType("INTEGER"); - - b.Property<int>("Height") - .HasColumnType("INTEGER"); - - b.Property<int>("Interval") - .HasColumnType("INTEGER"); - - b.Property<int>("ThumbnailCount") - .HasColumnType("INTEGER"); - - b.Property<int>("TileHeight") - .HasColumnType("INTEGER"); - - b.Property<int>("TileWidth") - .HasColumnType("INTEGER"); - - b.HasKey("ItemId", "Width"); - - b.ToTable("TrickplayInfos"); - - b.HasAnnotation("Sqlite:UseSqlReturningClause", false); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.User", b => - { - b.Property<Guid>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property<string>("AudioLanguagePreference") - .HasMaxLength(255) - .HasColumnType("TEXT"); - - b.Property<string>("AuthenticationProviderId") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("TEXT"); - - b.Property<string>("CastReceiverId") - .HasMaxLength(32) - .HasColumnType("TEXT"); - - b.Property<bool>("DisplayCollectionsView") - .HasColumnType("INTEGER"); - - b.Property<bool>("DisplayMissingEpisodes") - .HasColumnType("INTEGER"); - - b.Property<bool>("EnableAutoLogin") - .HasColumnType("INTEGER"); - - b.Property<bool>("EnableLocalPassword") - .HasColumnType("INTEGER"); - - b.Property<bool>("EnableNextEpisodeAutoPlay") - .HasColumnType("INTEGER"); - - b.Property<bool>("EnableUserPreferenceAccess") - .HasColumnType("INTEGER"); - - b.Property<bool>("HidePlayedInLatest") - .HasColumnType("INTEGER"); - - b.Property<long>("InternalId") - .HasColumnType("INTEGER"); - - b.Property<int>("InvalidLoginAttemptCount") - .HasColumnType("INTEGER"); - - b.Property<DateTime?>("LastActivityDate") - .HasColumnType("TEXT"); - - b.Property<DateTime?>("LastLoginDate") - .HasColumnType("TEXT"); - - b.Property<int?>("LoginAttemptsBeforeLockout") - .HasColumnType("INTEGER"); - - b.Property<int>("MaxActiveSessions") - .HasColumnType("INTEGER"); - - b.Property<int?>("MaxParentalRatingScore") - .HasColumnType("INTEGER"); - - b.Property<int?>("MaxParentalRatingSubScore") - .HasColumnType("INTEGER"); - - b.Property<bool>("MustUpdatePassword") - .HasColumnType("INTEGER"); - - b.Property<string>("Password") - .HasMaxLength(65535) - .HasColumnType("TEXT"); - - b.Property<string>("PasswordResetProviderId") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("TEXT"); - - b.Property<bool>("PlayDefaultAudioTrack") - .HasColumnType("INTEGER"); - - b.Property<bool>("RememberAudioSelections") - .HasColumnType("INTEGER"); - - b.Property<bool>("RememberSubtitleSelections") - .HasColumnType("INTEGER"); - - b.Property<int?>("RemoteClientBitrateLimit") - .HasColumnType("INTEGER"); - - b.Property<uint>("RowVersion") - .IsConcurrencyToken() - .HasColumnType("INTEGER"); - - b.Property<string>("SubtitleLanguagePreference") - .HasMaxLength(255) - .HasColumnType("TEXT"); - - b.Property<int>("SubtitleMode") - .HasColumnType("INTEGER"); - - b.Property<int>("SyncPlayAccess") - .HasColumnType("INTEGER"); - - b.Property<string>("Username") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("Username") - .IsUnique(); - - b.ToTable("Users"); - - b.HasAnnotation("Sqlite:UseSqlReturningClause", false); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.UserData", b => - { - b.Property<Guid>("ItemId") - .HasColumnType("TEXT"); - - b.Property<Guid>("UserId") - .HasColumnType("TEXT"); - - b.Property<string>("CustomDataKey") - .HasColumnType("TEXT"); - - b.Property<int?>("AudioStreamIndex") - .HasColumnType("INTEGER"); - - b.Property<bool>("IsFavorite") - .HasColumnType("INTEGER"); - - b.Property<DateTime?>("LastPlayedDate") - .HasColumnType("TEXT"); - - b.Property<bool?>("Likes") - .HasColumnType("INTEGER"); - - b.Property<int>("PlayCount") - .HasColumnType("INTEGER"); - - b.Property<long>("PlaybackPositionTicks") - .HasColumnType("INTEGER"); - - b.Property<bool>("Played") - .HasColumnType("INTEGER"); - - b.Property<double?>("Rating") - .HasColumnType("REAL"); - - b.Property<DateTime?>("RetentionDate") - .HasColumnType("TEXT"); - - b.Property<int?>("SubtitleStreamIndex") - .HasColumnType("INTEGER"); - - b.HasKey("ItemId", "UserId", "CustomDataKey"); - - b.HasIndex("ItemId", "UserId", "IsFavorite"); - - b.HasIndex("ItemId", "UserId", "LastPlayedDate"); - - b.HasIndex("ItemId", "UserId", "PlaybackPositionTicks"); - - b.HasIndex("ItemId", "UserId", "Played"); - - b.HasIndex("UserId", "IsFavorite", "ItemId"); - - b.HasIndex("UserId", "ItemId", "LastPlayedDate"); - - b.HasIndex("UserId", "Played", "ItemId"); - - b.ToTable("UserData"); - - b.HasAnnotation("Sqlite:UseSqlReturningClause", false); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.AccessSchedule", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.User", null) - .WithMany("AccessSchedules") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.AncestorId", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.BaseItemEntity", "Item") - .WithMany("Parents") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Jellyfin.Database.Implementations.Entities.BaseItemEntity", "ParentItem") - .WithMany("Children") - .HasForeignKey("ParentItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - - b.Navigation("ParentItem"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.AttachmentStreamInfo", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.BaseItemEntity", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.BaseItemEntity", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.BaseItemEntity", "Owner") - .WithMany("Extras") - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.NoAction); - - b.HasOne("Jellyfin.Database.Implementations.Entities.BaseItemEntity", "DirectParent") - .WithMany("DirectChildren") - .HasForeignKey("ParentId") - .OnDelete(DeleteBehavior.Cascade); - - b.Navigation("DirectParent"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.BaseItemImageInfo", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.BaseItemEntity", "Item") - .WithMany("Images") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.BaseItemMetadataField", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.BaseItemEntity", "Item") - .WithMany("LockedFields") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.BaseItemProvider", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.BaseItemEntity", "Item") - .WithMany("Provider") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.BaseItemTrailerType", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.BaseItemEntity", "Item") - .WithMany("TrailerTypes") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.Chapter", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.BaseItemEntity", "Item") - .WithMany("Chapters") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.DisplayPreferences", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.User", null) - .WithMany("DisplayPreferences") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.HomeSection", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.DisplayPreferences", null) - .WithMany("HomeSections") - .HasForeignKey("DisplayPreferencesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.ImageInfo", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.User", null) - .WithOne("ProfileImage") - .HasForeignKey("Jellyfin.Database.Implementations.Entities.ImageInfo", "UserId") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.ItemDisplayPreferences", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.User", null) - .WithMany("ItemDisplayPreferences") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.ItemValueMap", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.BaseItemEntity", "Item") - .WithMany("ItemValues") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Jellyfin.Database.Implementations.Entities.ItemValue", "ItemValue") - .WithMany("BaseItemsMap") - .HasForeignKey("ItemValueId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - - b.Navigation("ItemValue"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.KeyframeData", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.BaseItemEntity", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.LinkedChildEntity", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.BaseItemEntity", "Child") - .WithMany("LinkedChildOfEntities") - .HasForeignKey("ChildId") - .OnDelete(DeleteBehavior.NoAction) - .IsRequired(); - - b.HasOne("Jellyfin.Database.Implementations.Entities.BaseItemEntity", "Parent") - .WithMany("LinkedChildEntities") - .HasForeignKey("ParentId") - .OnDelete(DeleteBehavior.NoAction) - .IsRequired(); - - b.Navigation("Child"); - - b.Navigation("Parent"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.MediaStreamInfo", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.BaseItemEntity", "Item") - .WithMany("MediaStreams") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.PeopleBaseItemMap", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.BaseItemEntity", "Item") - .WithMany("Peoples") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Jellyfin.Database.Implementations.Entities.People", "People") - .WithMany("BaseItems") - .HasForeignKey("PeopleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - - b.Navigation("People"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.Permission", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.User", null) - .WithMany("Permissions") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.Preference", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.User", null) - .WithMany("Preferences") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.Security.Device", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.User", "User") - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.UserData", b => - { - b.HasOne("Jellyfin.Database.Implementations.Entities.BaseItemEntity", "Item") - .WithMany("UserData") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Jellyfin.Database.Implementations.Entities.User", "User") - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.BaseItemEntity", b => - { - b.Navigation("Chapters"); - - b.Navigation("Children"); - - b.Navigation("DirectChildren"); - - b.Navigation("Extras"); - - b.Navigation("Images"); - - b.Navigation("ItemValues"); - - b.Navigation("LinkedChildEntities"); - - b.Navigation("LinkedChildOfEntities"); - - b.Navigation("LockedFields"); - - b.Navigation("MediaStreams"); - - b.Navigation("Parents"); - - b.Navigation("Peoples"); - - b.Navigation("Provider"); - - b.Navigation("TrailerTypes"); - - b.Navigation("UserData"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.DisplayPreferences", b => - { - b.Navigation("HomeSections"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.ItemValue", b => - { - b.Navigation("BaseItemsMap"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.People", b => - { - b.Navigation("BaseItems"); - }); - - modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.User", b => - { - b.Navigation("AccessSchedules"); - - b.Navigation("DisplayPreferences"); - - b.Navigation("ItemDisplayPreferences"); - - b.Navigation("Permissions"); - - b.Navigation("Preferences"); - - b.Navigation("ProfileImage"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260504180809_AddOriginalLanguage.cs b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260504180809_AddOriginalLanguage.cs deleted file mode 100644 index cda226309a..0000000000 --- a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/Migrations/20260504180809_AddOriginalLanguage.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Jellyfin.Database.Providers.Sqlite.Migrations -{ - /// <inheritdoc /> - public partial class AddOriginalLanguage : Migration - { - /// <inheritdoc /> - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn<bool>( - name: "IsOriginal", - table: "MediaStreamInfos", - type: "INTEGER", - nullable: false, - defaultValue: false); - - migrationBuilder.AddColumn<string>( - 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); - } - - /// <inheritdoc /> - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "IsOriginal", - table: "MediaStreamInfos"); - - migrationBuilder.DropColumn( - name: "OriginalLanguage", - table: "BaseItems"); - } - } -} |
