mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-17 15:53:42 +01:00
Merge pull request #12798 from JPVenson/feature/EFUserData
Refactor library.db into jellyfin.db and EFCore
This commit is contained in:
@@ -21,7 +21,7 @@ public static class ServiceCollectionExtensions
|
||||
serviceCollection.AddPooledDbContextFactory<JellyfinDbContext>((serviceProvider, opt) =>
|
||||
{
|
||||
var applicationPaths = serviceProvider.GetRequiredService<IApplicationPaths>();
|
||||
opt.UseSqlite($"Filename={Path.Combine(applicationPaths.DataPath, "jellyfin.db")}");
|
||||
opt.UseSqlite($"Filename={Path.Combine(applicationPaths.DataPath, "jellyfin.db")};Pooling=false");
|
||||
});
|
||||
|
||||
return serviceCollection;
|
||||
|
||||
2176
Jellyfin.Server.Implementations/Item/BaseItemRepository.cs
Normal file
2176
Jellyfin.Server.Implementations/Item/BaseItemRepository.cs
Normal file
File diff suppressed because it is too large
Load Diff
123
Jellyfin.Server.Implementations/Item/ChapterRepository.cs
Normal file
123
Jellyfin.Server.Implementations/Item/ChapterRepository.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using Jellyfin.Data.Entities;
|
||||
using MediaBrowser.Controller.Chapters;
|
||||
using MediaBrowser.Controller.Drawing;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.Item;
|
||||
|
||||
/// <summary>
|
||||
/// The Chapter manager.
|
||||
/// </summary>
|
||||
public class ChapterRepository : IChapterRepository
|
||||
{
|
||||
private readonly IDbContextFactory<JellyfinDbContext> _dbProvider;
|
||||
private readonly IImageProcessor _imageProcessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChapterRepository"/> class.
|
||||
/// </summary>
|
||||
/// <param name="dbProvider">The EFCore provider.</param>
|
||||
/// <param name="imageProcessor">The Image Processor.</param>
|
||||
public ChapterRepository(IDbContextFactory<JellyfinDbContext> dbProvider, IImageProcessor imageProcessor)
|
||||
{
|
||||
_dbProvider = dbProvider;
|
||||
_imageProcessor = imageProcessor;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IChapterRepository"/>
|
||||
public ChapterInfo? GetChapter(BaseItemDto baseItem, int index)
|
||||
{
|
||||
return GetChapter(baseItem.Id, index);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IChapterRepository"/>
|
||||
public IReadOnlyList<ChapterInfo> GetChapters(BaseItemDto baseItem)
|
||||
{
|
||||
return GetChapters(baseItem.Id);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IChapterRepository"/>
|
||||
public ChapterInfo? GetChapter(Guid baseItemId, int index)
|
||||
{
|
||||
using var context = _dbProvider.CreateDbContext();
|
||||
var chapter = context.Chapters.AsNoTracking()
|
||||
.Select(e => new
|
||||
{
|
||||
chapter = e,
|
||||
baseItemPath = e.Item.Path
|
||||
})
|
||||
.FirstOrDefault(e => e.chapter.ItemId.Equals(baseItemId) && e.chapter.ChapterIndex == index);
|
||||
if (chapter is not null)
|
||||
{
|
||||
return Map(chapter.chapter, chapter.baseItemPath!);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IChapterRepository"/>
|
||||
public IReadOnlyList<ChapterInfo> GetChapters(Guid baseItemId)
|
||||
{
|
||||
using var context = _dbProvider.CreateDbContext();
|
||||
return context.Chapters.AsNoTracking().Where(e => e.ItemId.Equals(baseItemId))
|
||||
.Select(e => new
|
||||
{
|
||||
chapter = e,
|
||||
baseItemPath = e.Item.Path
|
||||
})
|
||||
.AsEnumerable()
|
||||
.Select(e => Map(e.chapter, e.baseItemPath!))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IChapterRepository"/>
|
||||
public void SaveChapters(Guid itemId, IReadOnlyList<ChapterInfo> chapters)
|
||||
{
|
||||
using var context = _dbProvider.CreateDbContext();
|
||||
using (var transaction = context.Database.BeginTransaction())
|
||||
{
|
||||
context.Chapters.Where(e => e.ItemId.Equals(itemId)).ExecuteDelete();
|
||||
for (var i = 0; i < chapters.Count; i++)
|
||||
{
|
||||
var chapter = chapters[i];
|
||||
context.Chapters.Add(Map(chapter, i, itemId));
|
||||
}
|
||||
|
||||
context.SaveChanges();
|
||||
transaction.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
private Chapter Map(ChapterInfo chapterInfo, int index, Guid itemId)
|
||||
{
|
||||
return new Chapter()
|
||||
{
|
||||
ChapterIndex = index,
|
||||
StartPositionTicks = chapterInfo.StartPositionTicks,
|
||||
ImageDateModified = chapterInfo.ImageDateModified,
|
||||
ImagePath = chapterInfo.ImagePath,
|
||||
ItemId = itemId,
|
||||
Name = chapterInfo.Name,
|
||||
Item = null!
|
||||
};
|
||||
}
|
||||
|
||||
private ChapterInfo Map(Chapter chapterInfo, string baseItemPath)
|
||||
{
|
||||
var chapterEntity = new ChapterInfo()
|
||||
{
|
||||
StartPositionTicks = chapterInfo.StartPositionTicks,
|
||||
ImageDateModified = chapterInfo.ImageDateModified.GetValueOrDefault(),
|
||||
ImagePath = chapterInfo.ImagePath,
|
||||
Name = chapterInfo.Name,
|
||||
};
|
||||
chapterEntity.ImageTag = _imageProcessor.GetImageCacheTag(baseItemPath, chapterEntity.ImageDateModified);
|
||||
return chapterEntity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Jellyfin.Data.Entities;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.Item;
|
||||
|
||||
/// <summary>
|
||||
/// Manager for handling Media Attachments.
|
||||
/// </summary>
|
||||
/// <param name="dbProvider">Efcore Factory.</param>
|
||||
public class MediaAttachmentRepository(IDbContextFactory<JellyfinDbContext> dbProvider) : IMediaAttachmentRepository
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public void SaveMediaAttachments(
|
||||
Guid id,
|
||||
IReadOnlyList<MediaAttachment> attachments,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
using var context = dbProvider.CreateDbContext();
|
||||
using var transaction = context.Database.BeginTransaction();
|
||||
context.AttachmentStreamInfos.Where(e => e.ItemId.Equals(id)).ExecuteDelete();
|
||||
context.AttachmentStreamInfos.AddRange(attachments.Select(e => Map(e, id)));
|
||||
context.SaveChanges();
|
||||
transaction.Commit();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<MediaAttachment> GetMediaAttachments(MediaAttachmentQuery filter)
|
||||
{
|
||||
using var context = dbProvider.CreateDbContext();
|
||||
var query = context.AttachmentStreamInfos.AsNoTracking().Where(e => e.ItemId.Equals(filter.ItemId));
|
||||
if (filter.Index.HasValue)
|
||||
{
|
||||
query = query.Where(e => e.Index == filter.Index);
|
||||
}
|
||||
|
||||
return query.AsEnumerable().Select(Map).ToArray();
|
||||
}
|
||||
|
||||
private MediaAttachment Map(AttachmentStreamInfo attachment)
|
||||
{
|
||||
return new MediaAttachment()
|
||||
{
|
||||
Codec = attachment.Codec,
|
||||
CodecTag = attachment.CodecTag,
|
||||
Comment = attachment.Comment,
|
||||
FileName = attachment.Filename,
|
||||
Index = attachment.Index,
|
||||
MimeType = attachment.MimeType,
|
||||
};
|
||||
}
|
||||
|
||||
private AttachmentStreamInfo Map(MediaAttachment attachment, Guid id)
|
||||
{
|
||||
return new AttachmentStreamInfo()
|
||||
{
|
||||
Codec = attachment.Codec,
|
||||
CodecTag = attachment.CodecTag,
|
||||
Comment = attachment.Comment,
|
||||
Filename = attachment.FileName,
|
||||
Index = attachment.Index,
|
||||
MimeType = attachment.MimeType,
|
||||
ItemId = id,
|
||||
Item = null!
|
||||
};
|
||||
}
|
||||
}
|
||||
213
Jellyfin.Server.Implementations/Item/MediaStreamRepository.cs
Normal file
213
Jellyfin.Server.Implementations/Item/MediaStreamRepository.cs
Normal file
@@ -0,0 +1,213 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Jellyfin.Data.Entities;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Globalization;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.Item;
|
||||
|
||||
/// <summary>
|
||||
/// Repository for obtaining MediaStreams.
|
||||
/// </summary>
|
||||
public class MediaStreamRepository : IMediaStreamRepository
|
||||
{
|
||||
private readonly IDbContextFactory<JellyfinDbContext> _dbProvider;
|
||||
private readonly IServerApplicationHost _serverApplicationHost;
|
||||
private readonly ILocalizationManager _localization;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MediaStreamRepository"/> class.
|
||||
/// </summary>
|
||||
/// <param name="dbProvider">The EFCore db factory.</param>
|
||||
/// <param name="serverApplicationHost">The Application host.</param>
|
||||
/// <param name="localization">The Localisation Provider.</param>
|
||||
public MediaStreamRepository(IDbContextFactory<JellyfinDbContext> dbProvider, IServerApplicationHost serverApplicationHost, ILocalizationManager localization)
|
||||
{
|
||||
_dbProvider = dbProvider;
|
||||
_serverApplicationHost = serverApplicationHost;
|
||||
_localization = localization;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SaveMediaStreams(Guid id, IReadOnlyList<MediaStream> streams, CancellationToken cancellationToken)
|
||||
{
|
||||
using var context = _dbProvider.CreateDbContext();
|
||||
using var transaction = context.Database.BeginTransaction();
|
||||
|
||||
context.MediaStreamInfos.Where(e => e.ItemId.Equals(id)).ExecuteDelete();
|
||||
context.MediaStreamInfos.AddRange(streams.Select(f => Map(f, id)));
|
||||
context.SaveChanges();
|
||||
|
||||
transaction.Commit();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<MediaStream> GetMediaStreams(MediaStreamQuery filter)
|
||||
{
|
||||
using var context = _dbProvider.CreateDbContext();
|
||||
return TranslateQuery(context.MediaStreamInfos.AsNoTracking(), filter).AsEnumerable().Select(Map).ToArray();
|
||||
}
|
||||
|
||||
private string? GetPathToSave(string? path)
|
||||
{
|
||||
if (path is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return _serverApplicationHost.ReverseVirtualPath(path);
|
||||
}
|
||||
|
||||
private string? RestorePath(string? path)
|
||||
{
|
||||
if (path is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return _serverApplicationHost.ExpandVirtualPath(path);
|
||||
}
|
||||
|
||||
private IQueryable<MediaStreamInfo> TranslateQuery(IQueryable<MediaStreamInfo> query, MediaStreamQuery filter)
|
||||
{
|
||||
query = query.Where(e => e.ItemId.Equals(filter.ItemId));
|
||||
if (filter.Index.HasValue)
|
||||
{
|
||||
query = query.Where(e => e.StreamIndex == filter.Index);
|
||||
}
|
||||
|
||||
if (filter.Type.HasValue)
|
||||
{
|
||||
var typeValue = (MediaStreamTypeEntity)filter.Type.Value;
|
||||
query = query.Where(e => e.StreamType == typeValue);
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
private MediaStream Map(MediaStreamInfo entity)
|
||||
{
|
||||
var dto = new MediaStream();
|
||||
dto.Index = entity.StreamIndex;
|
||||
dto.Type = (MediaStreamType)entity.StreamType;
|
||||
|
||||
dto.IsAVC = entity.IsAvc;
|
||||
dto.Codec = entity.Codec;
|
||||
dto.Language = entity.Language;
|
||||
dto.ChannelLayout = entity.ChannelLayout;
|
||||
dto.Profile = entity.Profile;
|
||||
dto.AspectRatio = entity.AspectRatio;
|
||||
dto.Path = RestorePath(entity.Path);
|
||||
dto.IsInterlaced = entity.IsInterlaced.GetValueOrDefault();
|
||||
dto.BitRate = entity.BitRate;
|
||||
dto.Channels = entity.Channels;
|
||||
dto.SampleRate = entity.SampleRate;
|
||||
dto.IsDefault = entity.IsDefault;
|
||||
dto.IsForced = entity.IsForced;
|
||||
dto.IsExternal = entity.IsExternal;
|
||||
dto.Height = entity.Height;
|
||||
dto.Width = entity.Width;
|
||||
dto.AverageFrameRate = entity.AverageFrameRate;
|
||||
dto.RealFrameRate = entity.RealFrameRate;
|
||||
dto.Level = entity.Level;
|
||||
dto.PixelFormat = entity.PixelFormat;
|
||||
dto.BitDepth = entity.BitDepth;
|
||||
dto.IsAnamorphic = entity.IsAnamorphic;
|
||||
dto.RefFrames = entity.RefFrames;
|
||||
dto.CodecTag = entity.CodecTag;
|
||||
dto.Comment = entity.Comment;
|
||||
dto.NalLengthSize = entity.NalLengthSize;
|
||||
dto.Title = entity.Title;
|
||||
dto.TimeBase = entity.TimeBase;
|
||||
dto.CodecTimeBase = entity.CodecTimeBase;
|
||||
dto.ColorPrimaries = entity.ColorPrimaries;
|
||||
dto.ColorSpace = entity.ColorSpace;
|
||||
dto.ColorTransfer = entity.ColorTransfer;
|
||||
dto.DvVersionMajor = entity.DvVersionMajor;
|
||||
dto.DvVersionMinor = entity.DvVersionMinor;
|
||||
dto.DvProfile = entity.DvProfile;
|
||||
dto.DvLevel = entity.DvLevel;
|
||||
dto.RpuPresentFlag = entity.RpuPresentFlag;
|
||||
dto.ElPresentFlag = entity.ElPresentFlag;
|
||||
dto.BlPresentFlag = entity.BlPresentFlag;
|
||||
dto.DvBlSignalCompatibilityId = entity.DvBlSignalCompatibilityId;
|
||||
dto.IsHearingImpaired = entity.IsHearingImpaired;
|
||||
dto.Rotation = entity.Rotation;
|
||||
|
||||
if (dto.Type is MediaStreamType.Audio or MediaStreamType.Subtitle)
|
||||
{
|
||||
dto.LocalizedDefault = _localization.GetLocalizedString("Default");
|
||||
dto.LocalizedExternal = _localization.GetLocalizedString("External");
|
||||
|
||||
if (dto.Type is MediaStreamType.Subtitle)
|
||||
{
|
||||
dto.LocalizedUndefined = _localization.GetLocalizedString("Undefined");
|
||||
dto.LocalizedForced = _localization.GetLocalizedString("Forced");
|
||||
dto.LocalizedHearingImpaired = _localization.GetLocalizedString("HearingImpaired");
|
||||
}
|
||||
}
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
private MediaStreamInfo Map(MediaStream dto, Guid itemId)
|
||||
{
|
||||
var entity = new MediaStreamInfo
|
||||
{
|
||||
Item = null!,
|
||||
ItemId = itemId,
|
||||
StreamIndex = dto.Index,
|
||||
StreamType = (MediaStreamTypeEntity)dto.Type,
|
||||
IsAvc = dto.IsAVC,
|
||||
|
||||
Codec = dto.Codec,
|
||||
Language = dto.Language,
|
||||
ChannelLayout = dto.ChannelLayout,
|
||||
Profile = dto.Profile,
|
||||
AspectRatio = dto.AspectRatio,
|
||||
Path = GetPathToSave(dto.Path) ?? dto.Path,
|
||||
IsInterlaced = dto.IsInterlaced,
|
||||
BitRate = dto.BitRate,
|
||||
Channels = dto.Channels,
|
||||
SampleRate = dto.SampleRate,
|
||||
IsDefault = dto.IsDefault,
|
||||
IsForced = dto.IsForced,
|
||||
IsExternal = dto.IsExternal,
|
||||
Height = dto.Height,
|
||||
Width = dto.Width,
|
||||
AverageFrameRate = dto.AverageFrameRate,
|
||||
RealFrameRate = dto.RealFrameRate,
|
||||
Level = dto.Level.HasValue ? (float)dto.Level : null,
|
||||
PixelFormat = dto.PixelFormat,
|
||||
BitDepth = dto.BitDepth,
|
||||
IsAnamorphic = dto.IsAnamorphic,
|
||||
RefFrames = dto.RefFrames,
|
||||
CodecTag = dto.CodecTag,
|
||||
Comment = dto.Comment,
|
||||
NalLengthSize = dto.NalLengthSize,
|
||||
Title = dto.Title,
|
||||
TimeBase = dto.TimeBase,
|
||||
CodecTimeBase = dto.CodecTimeBase,
|
||||
ColorPrimaries = dto.ColorPrimaries,
|
||||
ColorSpace = dto.ColorSpace,
|
||||
ColorTransfer = dto.ColorTransfer,
|
||||
DvVersionMajor = dto.DvVersionMajor,
|
||||
DvVersionMinor = dto.DvVersionMinor,
|
||||
DvProfile = dto.DvProfile,
|
||||
DvLevel = dto.DvLevel,
|
||||
RpuPresentFlag = dto.RpuPresentFlag,
|
||||
ElPresentFlag = dto.ElPresentFlag,
|
||||
BlPresentFlag = dto.BlPresentFlag,
|
||||
DvBlSignalCompatibilityId = dto.DvBlSignalCompatibilityId,
|
||||
IsHearingImpaired = dto.IsHearingImpaired,
|
||||
Rotation = dto.Rotation
|
||||
};
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
186
Jellyfin.Server.Implementations/Item/PeopleRepository.cs
Normal file
186
Jellyfin.Server.Implementations/Item/PeopleRepository.cs
Normal file
@@ -0,0 +1,186 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Extensions;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.Item;
|
||||
#pragma warning disable RS0030 // Do not use banned APIs
|
||||
|
||||
/// <summary>
|
||||
/// Manager for handling people.
|
||||
/// </summary>
|
||||
/// <param name="dbProvider">Efcore Factory.</param>
|
||||
/// <param name="itemTypeLookup">Items lookup service.</param>
|
||||
/// <remarks>
|
||||
/// Initializes a new instance of the <see cref="PeopleRepository"/> class.
|
||||
/// </remarks>
|
||||
public class PeopleRepository(IDbContextFactory<JellyfinDbContext> dbProvider, IItemTypeLookup itemTypeLookup) : IPeopleRepository
|
||||
{
|
||||
private readonly IDbContextFactory<JellyfinDbContext> _dbProvider = dbProvider;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReadOnlyList<PersonInfo> GetPeople(InternalPeopleQuery filter)
|
||||
{
|
||||
using var context = _dbProvider.CreateDbContext();
|
||||
var dbQuery = TranslateQuery(context.Peoples.AsNoTracking(), context, filter);
|
||||
|
||||
// dbQuery = dbQuery.OrderBy(e => e.ListOrder);
|
||||
if (filter.Limit > 0)
|
||||
{
|
||||
dbQuery = dbQuery.Take(filter.Limit);
|
||||
}
|
||||
|
||||
return dbQuery.AsEnumerable().Select(Map).ToArray();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReadOnlyList<string> GetPeopleNames(InternalPeopleQuery filter)
|
||||
{
|
||||
using var context = _dbProvider.CreateDbContext();
|
||||
var dbQuery = TranslateQuery(context.Peoples.AsNoTracking(), context, filter);
|
||||
|
||||
// dbQuery = dbQuery.OrderBy(e => e.ListOrder);
|
||||
if (filter.Limit > 0)
|
||||
{
|
||||
dbQuery = dbQuery.Take(filter.Limit);
|
||||
}
|
||||
|
||||
return dbQuery.Select(e => e.Name).ToArray();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void UpdatePeople(Guid itemId, IReadOnlyList<PersonInfo> people)
|
||||
{
|
||||
using var context = _dbProvider.CreateDbContext();
|
||||
using var transaction = context.Database.BeginTransaction();
|
||||
|
||||
context.PeopleBaseItemMap.Where(e => e.ItemId == itemId).ExecuteDelete();
|
||||
// TODO: yes for __SOME__ reason there can be duplicates.
|
||||
foreach (var item in people.DistinctBy(e => e.Id))
|
||||
{
|
||||
var personEntity = Map(item);
|
||||
var existingEntity = context.Peoples.FirstOrDefault(e => e.Id == personEntity.Id);
|
||||
if (existingEntity is null)
|
||||
{
|
||||
context.Peoples.Add(personEntity);
|
||||
existingEntity = personEntity;
|
||||
}
|
||||
|
||||
context.PeopleBaseItemMap.Add(new PeopleBaseItemMap()
|
||||
{
|
||||
Item = null!,
|
||||
ItemId = itemId,
|
||||
People = existingEntity,
|
||||
PeopleId = existingEntity.Id,
|
||||
ListOrder = item.SortOrder,
|
||||
SortOrder = item.SortOrder,
|
||||
Role = item.Role
|
||||
});
|
||||
}
|
||||
|
||||
context.SaveChanges();
|
||||
transaction.Commit();
|
||||
}
|
||||
|
||||
private PersonInfo Map(People people)
|
||||
{
|
||||
var personInfo = new PersonInfo()
|
||||
{
|
||||
Id = people.Id,
|
||||
Name = people.Name,
|
||||
};
|
||||
if (Enum.TryParse<PersonKind>(people.PersonType, out var kind))
|
||||
{
|
||||
personInfo.Type = kind;
|
||||
}
|
||||
|
||||
return personInfo;
|
||||
}
|
||||
|
||||
private People Map(PersonInfo people)
|
||||
{
|
||||
var personInfo = new People()
|
||||
{
|
||||
Name = people.Name,
|
||||
PersonType = people.Type.ToString(),
|
||||
Id = people.Id,
|
||||
};
|
||||
|
||||
return personInfo;
|
||||
}
|
||||
|
||||
private IQueryable<People> TranslateQuery(IQueryable<People> query, JellyfinDbContext context, InternalPeopleQuery filter)
|
||||
{
|
||||
if (filter.User is not null && filter.IsFavorite.HasValue)
|
||||
{
|
||||
var personType = itemTypeLookup.BaseItemKindNames[BaseItemKind.Person];
|
||||
query = query.Where(e => e.PersonType == personType)
|
||||
.Where(e => context.BaseItems.Where(d => d.UserData!.Any(w => w.IsFavorite == filter.IsFavorite && w.UserId.Equals(filter.User.Id)))
|
||||
.Select(f => f.Name).Contains(e.Name));
|
||||
}
|
||||
|
||||
if (!filter.ItemId.IsEmpty())
|
||||
{
|
||||
query = query.Where(e => e.BaseItems!.Any(w => w.ItemId.Equals(filter.ItemId)));
|
||||
}
|
||||
|
||||
if (!filter.AppearsInItemId.IsEmpty())
|
||||
{
|
||||
query = query.Where(e => e.BaseItems!.Any(w => w.ItemId.Equals(filter.AppearsInItemId)));
|
||||
}
|
||||
|
||||
var queryPersonTypes = filter.PersonTypes.Where(IsValidPersonType).ToList();
|
||||
if (queryPersonTypes.Count > 0)
|
||||
{
|
||||
query = query.Where(e => queryPersonTypes.Contains(e.PersonType));
|
||||
}
|
||||
|
||||
var queryExcludePersonTypes = filter.ExcludePersonTypes.Where(IsValidPersonType).ToList();
|
||||
|
||||
if (queryExcludePersonTypes.Count > 0)
|
||||
{
|
||||
query = query.Where(e => !queryPersonTypes.Contains(e.PersonType));
|
||||
}
|
||||
|
||||
if (filter.MaxListOrder.HasValue && !filter.ItemId.IsEmpty())
|
||||
{
|
||||
query = query.Where(e => e.BaseItems!.First(w => w.ItemId == filter.ItemId).ListOrder <= filter.MaxListOrder.Value);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(filter.NameContains))
|
||||
{
|
||||
query = query.Where(e => e.Name.Contains(filter.NameContains));
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
private bool IsAlphaNumeric(string str)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(str))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < str.Length; i++)
|
||||
{
|
||||
if (!char.IsLetter(str[i]) && !char.IsNumber(str[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool IsValidPersonType(string value)
|
||||
{
|
||||
return IsAlphaNumeric(value);
|
||||
}
|
||||
}
|
||||
@@ -4,20 +4,18 @@ using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Entities.Security;
|
||||
using Jellyfin.Data.Interfaces;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Jellyfin.Server.Implementations;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public class JellyfinDbContext : DbContext
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JellyfinDbContext"/> class.
|
||||
/// </summary>
|
||||
/// <param name="options">The database context options.</param>
|
||||
/// <param name="logger">Logger.</param>
|
||||
public class JellyfinDbContext(DbContextOptions<JellyfinDbContext> options, ILogger<JellyfinDbContext> logger) : DbContext(options)
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JellyfinDbContext"/> class.
|
||||
/// </summary>
|
||||
/// <param name="options">The database context options.</param>
|
||||
public JellyfinDbContext(DbContextOptions<JellyfinDbContext> options) : base(options)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DbSet{TEntity}"/> containing the access schedules.
|
||||
/// </summary>
|
||||
@@ -88,6 +86,76 @@ public class JellyfinDbContext : DbContext
|
||||
/// </summary>
|
||||
public DbSet<MediaSegment> MediaSegments => Set<MediaSegment>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
|
||||
/// </summary>
|
||||
public DbSet<UserData> UserData => Set<UserData>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
|
||||
/// </summary>
|
||||
public DbSet<AncestorId> AncestorIds => Set<AncestorId>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
|
||||
/// </summary>
|
||||
public DbSet<AttachmentStreamInfo> AttachmentStreamInfos => Set<AttachmentStreamInfo>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
|
||||
/// </summary>
|
||||
public DbSet<BaseItemEntity> BaseItems => Set<BaseItemEntity>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
|
||||
/// </summary>
|
||||
public DbSet<Chapter> Chapters => Set<Chapter>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DbSet{TEntity}"/>.
|
||||
/// </summary>
|
||||
public DbSet<ItemValue> ItemValues => Set<ItemValue>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DbSet{TEntity}"/>.
|
||||
/// </summary>
|
||||
public DbSet<ItemValueMap> ItemValuesMap => Set<ItemValueMap>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DbSet{TEntity}"/>.
|
||||
/// </summary>
|
||||
public DbSet<MediaStreamInfo> MediaStreamInfos => Set<MediaStreamInfo>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DbSet{TEntity}"/>.
|
||||
/// </summary>
|
||||
public DbSet<People> Peoples => Set<People>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DbSet{TEntity}"/>.
|
||||
/// </summary>
|
||||
public DbSet<PeopleBaseItemMap> PeopleBaseItemMap => Set<PeopleBaseItemMap>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DbSet{TEntity}"/> containing the referenced Providers with ids.
|
||||
/// </summary>
|
||||
public DbSet<BaseItemProvider> BaseItemProviders => Set<BaseItemProvider>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DbSet{TEntity}"/>.
|
||||
/// </summary>
|
||||
public DbSet<BaseItemImageInfo> BaseItemImageInfos => Set<BaseItemImageInfo>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DbSet{TEntity}"/>.
|
||||
/// </summary>
|
||||
public DbSet<BaseItemMetadataField> BaseItemMetadataFields => Set<BaseItemMetadataField>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DbSet{TEntity}"/>.
|
||||
/// </summary>
|
||||
public DbSet<BaseItemTrailerType> BaseItemTrailerTypes => Set<BaseItemTrailerType>();
|
||||
|
||||
/*public DbSet<Artwork> Artwork => Set<Artwork>();
|
||||
|
||||
public DbSet<Book> Books => Set<Book>();
|
||||
@@ -183,7 +251,15 @@ public class JellyfinDbContext : DbContext
|
||||
saveEntity.OnSavingChanges();
|
||||
}
|
||||
|
||||
return base.SaveChanges();
|
||||
try
|
||||
{
|
||||
return base.SaveChanges();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogError(e, "Error trying to save changes.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
1607
Jellyfin.Server.Implementations/Migrations/20241020103111_LibraryDbMigration.Designer.cs
generated
Normal file
1607
Jellyfin.Server.Implementations/Migrations/20241020103111_LibraryDbMigration.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,639 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Jellyfin.Server.Implementations.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class LibraryDbMigration : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "BaseItems",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
Type = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Data = table.Column<string>(type: "TEXT", nullable: true),
|
||||
Path = table.Column<string>(type: "TEXT", nullable: true),
|
||||
StartDate = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
EndDate = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
ChannelId = table.Column<string>(type: "TEXT", nullable: true),
|
||||
IsMovie = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
CommunityRating = table.Column<float>(type: "REAL", nullable: true),
|
||||
CustomRating = table.Column<string>(type: "TEXT", nullable: true),
|
||||
IndexNumber = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
IsLocked = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
Name = table.Column<string>(type: "TEXT", nullable: true),
|
||||
OfficialRating = table.Column<string>(type: "TEXT", nullable: true),
|
||||
MediaType = table.Column<string>(type: "TEXT", nullable: true),
|
||||
Overview = table.Column<string>(type: "TEXT", nullable: true),
|
||||
ParentIndexNumber = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
PremiereDate = table.Column<DateTime>(type: "TEXT", nullable: true),
|
||||
ProductionYear = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
Genres = table.Column<string>(type: "TEXT", nullable: true),
|
||||
SortName = table.Column<string>(type: "TEXT", nullable: true),
|
||||
ForcedSortName = table.Column<string>(type: "TEXT", nullable: true),
|
||||
RunTimeTicks = table.Column<long>(type: "INTEGER", nullable: true),
|
||||
DateCreated = table.Column<DateTime>(type: "TEXT", nullable: true),
|
||||
DateModified = table.Column<DateTime>(type: "TEXT", nullable: true),
|
||||
IsSeries = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
EpisodeTitle = table.Column<string>(type: "TEXT", nullable: true),
|
||||
IsRepeat = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
PreferredMetadataLanguage = table.Column<string>(type: "TEXT", nullable: true),
|
||||
PreferredMetadataCountryCode = table.Column<string>(type: "TEXT", nullable: true),
|
||||
DateLastRefreshed = table.Column<DateTime>(type: "TEXT", nullable: true),
|
||||
DateLastSaved = table.Column<DateTime>(type: "TEXT", nullable: true),
|
||||
IsInMixedFolder = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
Studios = table.Column<string>(type: "TEXT", nullable: true),
|
||||
ExternalServiceId = table.Column<string>(type: "TEXT", nullable: true),
|
||||
Tags = table.Column<string>(type: "TEXT", nullable: true),
|
||||
IsFolder = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
InheritedParentalRatingValue = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
UnratedType = table.Column<string>(type: "TEXT", nullable: true),
|
||||
CriticRating = table.Column<float>(type: "REAL", nullable: true),
|
||||
CleanName = table.Column<string>(type: "TEXT", nullable: true),
|
||||
PresentationUniqueKey = table.Column<string>(type: "TEXT", nullable: true),
|
||||
OriginalTitle = table.Column<string>(type: "TEXT", nullable: true),
|
||||
PrimaryVersionId = table.Column<string>(type: "TEXT", nullable: true),
|
||||
DateLastMediaAdded = table.Column<DateTime>(type: "TEXT", nullable: true),
|
||||
Album = table.Column<string>(type: "TEXT", nullable: true),
|
||||
LUFS = table.Column<float>(type: "REAL", nullable: true),
|
||||
NormalizationGain = table.Column<float>(type: "REAL", nullable: true),
|
||||
IsVirtualItem = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
SeriesName = table.Column<string>(type: "TEXT", nullable: true),
|
||||
SeasonName = table.Column<string>(type: "TEXT", nullable: true),
|
||||
ExternalSeriesId = table.Column<string>(type: "TEXT", nullable: true),
|
||||
Tagline = table.Column<string>(type: "TEXT", nullable: true),
|
||||
ProductionLocations = table.Column<string>(type: "TEXT", nullable: true),
|
||||
ExtraIds = table.Column<string>(type: "TEXT", nullable: true),
|
||||
TotalBitrate = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
ExtraType = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
Artists = table.Column<string>(type: "TEXT", nullable: true),
|
||||
AlbumArtists = table.Column<string>(type: "TEXT", nullable: true),
|
||||
ExternalId = table.Column<string>(type: "TEXT", nullable: true),
|
||||
SeriesPresentationUniqueKey = table.Column<string>(type: "TEXT", nullable: true),
|
||||
ShowId = table.Column<string>(type: "TEXT", nullable: true),
|
||||
OwnerId = table.Column<string>(type: "TEXT", nullable: true),
|
||||
Width = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
Height = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
Size = table.Column<long>(type: "INTEGER", nullable: true),
|
||||
Audio = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
ParentId = table.Column<Guid>(type: "TEXT", nullable: true),
|
||||
TopParentId = table.Column<Guid>(type: "TEXT", nullable: true),
|
||||
SeasonId = table.Column<Guid>(type: "TEXT", nullable: true),
|
||||
SeriesId = table.Column<Guid>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_BaseItems", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ItemValues",
|
||||
columns: table => new
|
||||
{
|
||||
ItemValueId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
Type = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Value = table.Column<string>(type: "TEXT", nullable: false),
|
||||
CleanValue = table.Column<string>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ItemValues", x => x.ItemValueId);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Peoples",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
Name = table.Column<string>(type: "TEXT", nullable: false),
|
||||
PersonType = table.Column<string>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Peoples", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AncestorIds",
|
||||
columns: table => new
|
||||
{
|
||||
ParentItemId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
ItemId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
BaseItemEntityId = table.Column<Guid>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AncestorIds", x => new { x.ItemId, x.ParentItemId });
|
||||
table.ForeignKey(
|
||||
name: "FK_AncestorIds_BaseItems_BaseItemEntityId",
|
||||
column: x => x.BaseItemEntityId,
|
||||
principalTable: "BaseItems",
|
||||
principalColumn: "Id");
|
||||
table.ForeignKey(
|
||||
name: "FK_AncestorIds_BaseItems_ItemId",
|
||||
column: x => x.ItemId,
|
||||
principalTable: "BaseItems",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_AncestorIds_BaseItems_ParentItemId",
|
||||
column: x => x.ParentItemId,
|
||||
principalTable: "BaseItems",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AttachmentStreamInfos",
|
||||
columns: table => new
|
||||
{
|
||||
ItemId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
Index = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Codec = table.Column<string>(type: "TEXT", nullable: false),
|
||||
CodecTag = table.Column<string>(type: "TEXT", nullable: true),
|
||||
Comment = table.Column<string>(type: "TEXT", nullable: true),
|
||||
Filename = table.Column<string>(type: "TEXT", nullable: true),
|
||||
MimeType = table.Column<string>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AttachmentStreamInfos", x => new { x.ItemId, x.Index });
|
||||
table.ForeignKey(
|
||||
name: "FK_AttachmentStreamInfos_BaseItems_ItemId",
|
||||
column: x => x.ItemId,
|
||||
principalTable: "BaseItems",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "BaseItemImageInfos",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
Path = table.Column<string>(type: "TEXT", nullable: false),
|
||||
DateModified = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
ImageType = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Width = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Height = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Blurhash = table.Column<byte[]>(type: "BLOB", nullable: true),
|
||||
ItemId = table.Column<Guid>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_BaseItemImageInfos", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_BaseItemImageInfos_BaseItems_ItemId",
|
||||
column: x => x.ItemId,
|
||||
principalTable: "BaseItems",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "BaseItemMetadataFields",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
ItemId = table.Column<Guid>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_BaseItemMetadataFields", x => new { x.Id, x.ItemId });
|
||||
table.ForeignKey(
|
||||
name: "FK_BaseItemMetadataFields_BaseItems_ItemId",
|
||||
column: x => x.ItemId,
|
||||
principalTable: "BaseItems",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "BaseItemProviders",
|
||||
columns: table => new
|
||||
{
|
||||
ItemId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
ProviderId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
ProviderValue = table.Column<string>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_BaseItemProviders", x => new { x.ItemId, x.ProviderId });
|
||||
table.ForeignKey(
|
||||
name: "FK_BaseItemProviders_BaseItems_ItemId",
|
||||
column: x => x.ItemId,
|
||||
principalTable: "BaseItems",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "BaseItemTrailerTypes",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
ItemId = table.Column<Guid>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_BaseItemTrailerTypes", x => new { x.Id, x.ItemId });
|
||||
table.ForeignKey(
|
||||
name: "FK_BaseItemTrailerTypes_BaseItems_ItemId",
|
||||
column: x => x.ItemId,
|
||||
principalTable: "BaseItems",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Chapters",
|
||||
columns: table => new
|
||||
{
|
||||
ItemId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
ChapterIndex = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
StartPositionTicks = table.Column<long>(type: "INTEGER", nullable: false),
|
||||
Name = table.Column<string>(type: "TEXT", nullable: true),
|
||||
ImagePath = table.Column<string>(type: "TEXT", nullable: true),
|
||||
ImageDateModified = table.Column<DateTime>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Chapters", x => new { x.ItemId, x.ChapterIndex });
|
||||
table.ForeignKey(
|
||||
name: "FK_Chapters_BaseItems_ItemId",
|
||||
column: x => x.ItemId,
|
||||
principalTable: "BaseItems",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "MediaStreamInfos",
|
||||
columns: table => new
|
||||
{
|
||||
ItemId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
StreamIndex = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
StreamType = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
Codec = table.Column<string>(type: "TEXT", nullable: true),
|
||||
Language = table.Column<string>(type: "TEXT", nullable: true),
|
||||
ChannelLayout = table.Column<string>(type: "TEXT", nullable: true),
|
||||
Profile = table.Column<string>(type: "TEXT", nullable: true),
|
||||
AspectRatio = table.Column<string>(type: "TEXT", nullable: true),
|
||||
Path = table.Column<string>(type: "TEXT", nullable: true),
|
||||
IsInterlaced = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
BitRate = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Channels = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
SampleRate = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
IsDefault = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
IsForced = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
IsExternal = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
Height = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Width = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
AverageFrameRate = table.Column<float>(type: "REAL", nullable: false),
|
||||
RealFrameRate = table.Column<float>(type: "REAL", nullable: false),
|
||||
Level = table.Column<float>(type: "REAL", nullable: false),
|
||||
PixelFormat = table.Column<string>(type: "TEXT", nullable: true),
|
||||
BitDepth = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
IsAnamorphic = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
RefFrames = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
CodecTag = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Comment = table.Column<string>(type: "TEXT", nullable: false),
|
||||
NalLengthSize = table.Column<string>(type: "TEXT", nullable: false),
|
||||
IsAvc = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
Title = table.Column<string>(type: "TEXT", nullable: false),
|
||||
TimeBase = table.Column<string>(type: "TEXT", nullable: false),
|
||||
CodecTimeBase = table.Column<string>(type: "TEXT", nullable: false),
|
||||
ColorPrimaries = table.Column<string>(type: "TEXT", nullable: false),
|
||||
ColorSpace = table.Column<string>(type: "TEXT", nullable: false),
|
||||
ColorTransfer = table.Column<string>(type: "TEXT", nullable: false),
|
||||
DvVersionMajor = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
DvVersionMinor = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
DvProfile = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
DvLevel = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
RpuPresentFlag = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
ElPresentFlag = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
BlPresentFlag = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
DvBlSignalCompatibilityId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
IsHearingImpaired = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
Rotation = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
KeyFrames = table.Column<string>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_MediaStreamInfos", x => new { x.ItemId, x.StreamIndex });
|
||||
table.ForeignKey(
|
||||
name: "FK_MediaStreamInfos_BaseItems_ItemId",
|
||||
column: x => x.ItemId,
|
||||
principalTable: "BaseItems",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "UserData",
|
||||
columns: table => new
|
||||
{
|
||||
ItemId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
UserId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
Rating = table.Column<double>(type: "REAL", nullable: true),
|
||||
PlaybackPositionTicks = table.Column<long>(type: "INTEGER", nullable: false),
|
||||
PlayCount = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
IsFavorite = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
LastPlayedDate = table.Column<DateTime>(type: "TEXT", nullable: true),
|
||||
Played = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
AudioStreamIndex = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
SubtitleStreamIndex = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
Likes = table.Column<bool>(type: "INTEGER", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_UserData", x => new { x.ItemId, x.UserId });
|
||||
table.ForeignKey(
|
||||
name: "FK_UserData_BaseItems_ItemId",
|
||||
column: x => x.ItemId,
|
||||
principalTable: "BaseItems",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_UserData_Users_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ItemValuesMap",
|
||||
columns: table => new
|
||||
{
|
||||
ItemId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
ItemValueId = table.Column<Guid>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ItemValuesMap", x => new { x.ItemValueId, x.ItemId });
|
||||
table.ForeignKey(
|
||||
name: "FK_ItemValuesMap_BaseItems_ItemId",
|
||||
column: x => x.ItemId,
|
||||
principalTable: "BaseItems",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_ItemValuesMap_ItemValues_ItemValueId",
|
||||
column: x => x.ItemValueId,
|
||||
principalTable: "ItemValues",
|
||||
principalColumn: "ItemValueId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "PeopleBaseItemMap",
|
||||
columns: table => new
|
||||
{
|
||||
ItemId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
PeopleId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
SortOrder = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
ListOrder = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
Role = table.Column<string>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_PeopleBaseItemMap", x => new { x.ItemId, x.PeopleId });
|
||||
table.ForeignKey(
|
||||
name: "FK_PeopleBaseItemMap_BaseItems_ItemId",
|
||||
column: x => x.ItemId,
|
||||
principalTable: "BaseItems",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_PeopleBaseItemMap_Peoples_PeopleId",
|
||||
column: x => x.PeopleId,
|
||||
principalTable: "Peoples",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AncestorIds_BaseItemEntityId",
|
||||
table: "AncestorIds",
|
||||
column: "BaseItemEntityId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AncestorIds_ParentItemId",
|
||||
table: "AncestorIds",
|
||||
column: "ParentItemId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BaseItemImageInfos_ItemId",
|
||||
table: "BaseItemImageInfos",
|
||||
column: "ItemId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BaseItemMetadataFields_ItemId",
|
||||
table: "BaseItemMetadataFields",
|
||||
column: "ItemId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BaseItemProviders_ProviderId_ProviderValue_ItemId",
|
||||
table: "BaseItemProviders",
|
||||
columns: new[] { "ProviderId", "ProviderValue", "ItemId" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BaseItems_Id_Type_IsFolder_IsVirtualItem",
|
||||
table: "BaseItems",
|
||||
columns: new[] { "Id", "Type", "IsFolder", "IsVirtualItem" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BaseItems_IsFolder_TopParentId_IsVirtualItem_PresentationUniqueKey_DateCreated",
|
||||
table: "BaseItems",
|
||||
columns: new[] { "IsFolder", "TopParentId", "IsVirtualItem", "PresentationUniqueKey", "DateCreated" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BaseItems_MediaType_TopParentId_IsVirtualItem_PresentationUniqueKey",
|
||||
table: "BaseItems",
|
||||
columns: new[] { "MediaType", "TopParentId", "IsVirtualItem", "PresentationUniqueKey" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BaseItems_ParentId",
|
||||
table: "BaseItems",
|
||||
column: "ParentId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BaseItems_Path",
|
||||
table: "BaseItems",
|
||||
column: "Path");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BaseItems_PresentationUniqueKey",
|
||||
table: "BaseItems",
|
||||
column: "PresentationUniqueKey");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BaseItems_TopParentId_Id",
|
||||
table: "BaseItems",
|
||||
columns: new[] { "TopParentId", "Id" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BaseItems_Type_SeriesPresentationUniqueKey_IsFolder_IsVirtualItem",
|
||||
table: "BaseItems",
|
||||
columns: new[] { "Type", "SeriesPresentationUniqueKey", "IsFolder", "IsVirtualItem" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BaseItems_Type_SeriesPresentationUniqueKey_PresentationUniqueKey_SortName",
|
||||
table: "BaseItems",
|
||||
columns: new[] { "Type", "SeriesPresentationUniqueKey", "PresentationUniqueKey", "SortName" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BaseItems_Type_TopParentId_Id",
|
||||
table: "BaseItems",
|
||||
columns: new[] { "Type", "TopParentId", "Id" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BaseItems_Type_TopParentId_IsVirtualItem_PresentationUniqueKey_DateCreated",
|
||||
table: "BaseItems",
|
||||
columns: new[] { "Type", "TopParentId", "IsVirtualItem", "PresentationUniqueKey", "DateCreated" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BaseItems_Type_TopParentId_PresentationUniqueKey",
|
||||
table: "BaseItems",
|
||||
columns: new[] { "Type", "TopParentId", "PresentationUniqueKey" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BaseItems_Type_TopParentId_StartDate",
|
||||
table: "BaseItems",
|
||||
columns: new[] { "Type", "TopParentId", "StartDate" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BaseItemTrailerTypes_ItemId",
|
||||
table: "BaseItemTrailerTypes",
|
||||
column: "ItemId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ItemValues_Type_CleanValue",
|
||||
table: "ItemValues",
|
||||
columns: new[] { "Type", "CleanValue" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ItemValuesMap_ItemId",
|
||||
table: "ItemValuesMap",
|
||||
column: "ItemId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MediaStreamInfos_StreamIndex",
|
||||
table: "MediaStreamInfos",
|
||||
column: "StreamIndex");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MediaStreamInfos_StreamIndex_StreamType",
|
||||
table: "MediaStreamInfos",
|
||||
columns: new[] { "StreamIndex", "StreamType" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MediaStreamInfos_StreamIndex_StreamType_Language",
|
||||
table: "MediaStreamInfos",
|
||||
columns: new[] { "StreamIndex", "StreamType", "Language" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MediaStreamInfos_StreamType",
|
||||
table: "MediaStreamInfos",
|
||||
column: "StreamType");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_PeopleBaseItemMap_ItemId_ListOrder",
|
||||
table: "PeopleBaseItemMap",
|
||||
columns: new[] { "ItemId", "ListOrder" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_PeopleBaseItemMap_ItemId_SortOrder",
|
||||
table: "PeopleBaseItemMap",
|
||||
columns: new[] { "ItemId", "SortOrder" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_PeopleBaseItemMap_PeopleId",
|
||||
table: "PeopleBaseItemMap",
|
||||
column: "PeopleId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Peoples_Name",
|
||||
table: "Peoples",
|
||||
column: "Name");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserData_ItemId_UserId_IsFavorite",
|
||||
table: "UserData",
|
||||
columns: new[] { "ItemId", "UserId", "IsFavorite" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserData_ItemId_UserId_LastPlayedDate",
|
||||
table: "UserData",
|
||||
columns: new[] { "ItemId", "UserId", "LastPlayedDate" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserData_ItemId_UserId_PlaybackPositionTicks",
|
||||
table: "UserData",
|
||||
columns: new[] { "ItemId", "UserId", "PlaybackPositionTicks" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserData_ItemId_UserId_Played",
|
||||
table: "UserData",
|
||||
columns: new[] { "ItemId", "UserId", "Played" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserData_UserId",
|
||||
table: "UserData",
|
||||
column: "UserId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "AncestorIds");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AttachmentStreamInfos");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "BaseItemImageInfos");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "BaseItemMetadataFields");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "BaseItemProviders");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "BaseItemTrailerTypes");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Chapters");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ItemValuesMap");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "MediaStreamInfos");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "PeopleBaseItemMap");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "UserData");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ItemValues");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Peoples");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "BaseItems");
|
||||
}
|
||||
}
|
||||
}
|
||||
1610
Jellyfin.Server.Implementations/Migrations/20241111131257_AddedCustomDataKey.Designer.cs
generated
Normal file
1610
Jellyfin.Server.Implementations/Migrations/20241111131257_AddedCustomDataKey.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,28 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Jellyfin.Server.Implementations.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddedCustomDataKey : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "CustomDataKey",
|
||||
table: "UserData",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "CustomDataKey",
|
||||
table: "UserData");
|
||||
}
|
||||
}
|
||||
}
|
||||
1610
Jellyfin.Server.Implementations/Migrations/20241111135439_AddedCustomDataKeyKey.Designer.cs
generated
Normal file
1610
Jellyfin.Server.Implementations/Migrations/20241111135439_AddedCustomDataKeyKey.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,54 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Jellyfin.Server.Implementations.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddedCustomDataKeyKey : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_UserData",
|
||||
table: "UserData");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "CustomDataKey",
|
||||
table: "UserData",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_UserData",
|
||||
table: "UserData",
|
||||
columns: new[] { "ItemId", "UserId", "CustomDataKey" });
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_UserData",
|
||||
table: "UserData");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "CustomDataKey",
|
||||
table: "UserData",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_UserData",
|
||||
table: "UserData",
|
||||
columns: new[] { "ItemId", "UserId" });
|
||||
}
|
||||
}
|
||||
}
|
||||
1603
Jellyfin.Server.Implementations/Migrations/20241112152323_FixAncestorIdConfig.Designer.cs
generated
Normal file
1603
Jellyfin.Server.Implementations/Migrations/20241112152323_FixAncestorIdConfig.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Jellyfin.Server.Implementations.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class FixAncestorIdConfig : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_AncestorIds_BaseItems_BaseItemEntityId",
|
||||
table: "AncestorIds");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_AncestorIds_BaseItemEntityId",
|
||||
table: "AncestorIds");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "BaseItemEntityId",
|
||||
table: "AncestorIds");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "BaseItemEntityId",
|
||||
table: "AncestorIds",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AncestorIds_BaseItemEntityId",
|
||||
table: "AncestorIds",
|
||||
column: "BaseItemEntityId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_AncestorIds_BaseItems_BaseItemEntityId",
|
||||
table: "AncestorIds",
|
||||
column: "BaseItemEntityId",
|
||||
principalTable: "BaseItems",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
}
|
||||
}
|
||||
1600
Jellyfin.Server.Implementations/Migrations/20241112232041_fixMediaStreams.Designer.cs
generated
Normal file
1600
Jellyfin.Server.Implementations/Migrations/20241112232041_fixMediaStreams.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,702 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Jellyfin.Server.Implementations.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class FixMediaStreams : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "Width",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Title",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "TimeBase",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "StreamType",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "SampleRate",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "RpuPresentFlag",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "Rotation",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "RefFrames",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<float>(
|
||||
name: "RealFrameRate",
|
||||
table: "MediaStreamInfos",
|
||||
type: "REAL",
|
||||
nullable: true,
|
||||
oldClrType: typeof(float),
|
||||
oldType: "REAL");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Profile",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Path",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "NalLengthSize",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<float>(
|
||||
name: "Level",
|
||||
table: "MediaStreamInfos",
|
||||
type: "REAL",
|
||||
nullable: true,
|
||||
oldClrType: typeof(float),
|
||||
oldType: "REAL");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Language",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<bool>(
|
||||
name: "IsHearingImpaired",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(bool),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<bool>(
|
||||
name: "IsAvc",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(bool),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<bool>(
|
||||
name: "IsAnamorphic",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(bool),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "Height",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "ElPresentFlag",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "DvVersionMinor",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "DvVersionMajor",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "DvProfile",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "DvLevel",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "DvBlSignalCompatibilityId",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Comment",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ColorTransfer",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ColorSpace",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ColorPrimaries",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "CodecTimeBase",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "CodecTag",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Codec",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "Channels",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ChannelLayout",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "BlPresentFlag",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "BitRate",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "BitDepth",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<float>(
|
||||
name: "AverageFrameRate",
|
||||
table: "MediaStreamInfos",
|
||||
type: "REAL",
|
||||
nullable: true,
|
||||
oldClrType: typeof(float),
|
||||
oldType: "REAL");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "AspectRatio",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "Width",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Title",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "TimeBase",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "StreamType",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "SampleRate",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "RpuPresentFlag",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "Rotation",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "RefFrames",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<float>(
|
||||
name: "RealFrameRate",
|
||||
table: "MediaStreamInfos",
|
||||
type: "REAL",
|
||||
nullable: false,
|
||||
defaultValue: 0f,
|
||||
oldClrType: typeof(float),
|
||||
oldType: "REAL",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Profile",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Path",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "NalLengthSize",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<float>(
|
||||
name: "Level",
|
||||
table: "MediaStreamInfos",
|
||||
type: "REAL",
|
||||
nullable: false,
|
||||
defaultValue: 0f,
|
||||
oldClrType: typeof(float),
|
||||
oldType: "REAL",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Language",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<bool>(
|
||||
name: "IsHearingImpaired",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: false,
|
||||
oldClrType: typeof(bool),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<bool>(
|
||||
name: "IsAvc",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: false,
|
||||
oldClrType: typeof(bool),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<bool>(
|
||||
name: "IsAnamorphic",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: false,
|
||||
oldClrType: typeof(bool),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "Height",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "ElPresentFlag",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "DvVersionMinor",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "DvVersionMajor",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "DvProfile",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "DvLevel",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "DvBlSignalCompatibilityId",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Comment",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ColorTransfer",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ColorSpace",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ColorPrimaries",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "CodecTimeBase",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "CodecTag",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Codec",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "Channels",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ChannelLayout",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "BlPresentFlag",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "BitRate",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "BitDepth",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<float>(
|
||||
name: "AverageFrameRate",
|
||||
table: "MediaStreamInfos",
|
||||
type: "REAL",
|
||||
nullable: false,
|
||||
defaultValue: 0f,
|
||||
oldClrType: typeof(float),
|
||||
oldType: "REAL",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "AspectRatio",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
}
|
||||
}
|
||||
}
|
||||
1594
Jellyfin.Server.Implementations/Migrations/20241112234144_FixMediaStreams2.Designer.cs
generated
Normal file
1594
Jellyfin.Server.Implementations/Migrations/20241112234144_FixMediaStreams2.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,144 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Jellyfin.Server.Implementations.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class FixMediaStreams2 : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Profile",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Path",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Language",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<bool>(
|
||||
name: "IsInterlaced",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(bool),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Codec",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ChannelLayout",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "AspectRatio",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Profile",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Path",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Language",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<bool>(
|
||||
name: "IsInterlaced",
|
||||
table: "MediaStreamInfos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: false,
|
||||
oldClrType: typeof(bool),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Codec",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ChannelLayout",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "AspectRatio",
|
||||
table: "MediaStreamInfos",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: string.Empty,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
1595
Jellyfin.Server.Implementations/Migrations/20241113133548_EnforceUniqueItemValue.Designer.cs
generated
Normal file
1595
Jellyfin.Server.Implementations/Migrations/20241113133548_EnforceUniqueItemValue.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,37 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Jellyfin.Server.Implementations.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class EnforceUniqueItemValue : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ItemValues_Type_CleanValue",
|
||||
table: "ItemValues");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ItemValues_Type_CleanValue",
|
||||
table: "ItemValues",
|
||||
columns: new[] { "Type", "CleanValue" },
|
||||
unique: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ItemValues_Type_CleanValue",
|
||||
table: "ItemValues");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ItemValues_Type_CleanValue",
|
||||
table: "ItemValues",
|
||||
columns: new[] { "Type", "CleanValue" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Design;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.Migrations
|
||||
{
|
||||
@@ -14,7 +15,7 @@ namespace Jellyfin.Server.Implementations.Migrations
|
||||
var optionsBuilder = new DbContextOptionsBuilder<JellyfinDbContext>();
|
||||
optionsBuilder.UseSqlite("Data Source=jellyfin.db");
|
||||
|
||||
return new JellyfinDbContext(optionsBuilder.Options);
|
||||
return new JellyfinDbContext(optionsBuilder.Options, NullLogger<JellyfinDbContext>.Instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Jellyfin.Server.Implementations.Migrations
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.8");
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.10");
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.AccessSchedule", b =>
|
||||
{
|
||||
@@ -90,6 +90,407 @@ namespace Jellyfin.Server.Implementations.Migrations
|
||||
b.ToTable("ActivityLogs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.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");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.AttachmentStreamInfo", b =>
|
||||
{
|
||||
b.Property<Guid>("ItemId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Index")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Codec")
|
||||
.IsRequired()
|
||||
.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");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.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<string>("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<string>("ExtraIds")
|
||||
.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?>("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>("OriginalTitle")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Overview")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("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<string>("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("ParentId");
|
||||
|
||||
b.HasIndex("Path");
|
||||
|
||||
b.HasIndex("PresentationUniqueKey");
|
||||
|
||||
b.HasIndex("TopParentId", "Id");
|
||||
|
||||
b.HasIndex("Type", "TopParentId", "Id");
|
||||
|
||||
b.HasIndex("Type", "TopParentId", "PresentationUniqueKey");
|
||||
|
||||
b.HasIndex("Type", "TopParentId", "StartDate");
|
||||
|
||||
b.HasIndex("Id", "Type", "IsFolder", "IsVirtualItem");
|
||||
|
||||
b.HasIndex("MediaType", "TopParentId", "IsVirtualItem", "PresentationUniqueKey");
|
||||
|
||||
b.HasIndex("Type", "SeriesPresentationUniqueKey", "IsFolder", "IsVirtualItem");
|
||||
|
||||
b.HasIndex("Type", "SeriesPresentationUniqueKey", "PresentationUniqueKey", "SortName");
|
||||
|
||||
b.HasIndex("IsFolder", "TopParentId", "IsVirtualItem", "PresentationUniqueKey", "DateCreated");
|
||||
|
||||
b.HasIndex("Type", "TopParentId", "IsVirtualItem", "PresentationUniqueKey", "DateCreated");
|
||||
|
||||
b.ToTable("BaseItems");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.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");
|
||||
|
||||
b.ToTable("BaseItemImageInfos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.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");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.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", "ProviderValue", "ItemId");
|
||||
|
||||
b.ToTable("BaseItemProviders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.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");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.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");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.CustomItemDisplayPreferences", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -270,6 +671,46 @@ namespace Jellyfin.Server.Implementations.Migrations
|
||||
b.ToTable("ItemDisplayPreferences");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.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")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("ItemValues");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.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");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.MediaSegment", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
@@ -297,6 +738,207 @@ namespace Jellyfin.Server.Implementations.Migrations
|
||||
b.ToTable("MediaSegments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.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<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<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.HasIndex("StreamIndex");
|
||||
|
||||
b.HasIndex("StreamType");
|
||||
|
||||
b.HasIndex("StreamIndex", "StreamType");
|
||||
|
||||
b.HasIndex("StreamIndex", "StreamType", "Language");
|
||||
|
||||
b.ToTable("MediaStreamInfos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.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");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.PeopleBaseItemMap", b =>
|
||||
{
|
||||
b.Property<Guid>("ItemId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("PeopleId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("ListOrder")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Role")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("SortOrder")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("ItemId", "PeopleId");
|
||||
|
||||
b.HasIndex("PeopleId");
|
||||
|
||||
b.HasIndex("ItemId", "ListOrder");
|
||||
|
||||
b.HasIndex("ItemId", "SortOrder");
|
||||
|
||||
b.ToTable("PeopleBaseItemMap");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.Permission", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -613,6 +1255,59 @@ namespace Jellyfin.Server.Implementations.Migrations
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.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<int?>("SubtitleStreamIndex")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("ItemId", "UserId", "CustomDataKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.HasIndex("ItemId", "UserId", "IsFavorite");
|
||||
|
||||
b.HasIndex("ItemId", "UserId", "LastPlayedDate");
|
||||
|
||||
b.HasIndex("ItemId", "UserId", "PlaybackPositionTicks");
|
||||
|
||||
b.HasIndex("ItemId", "UserId", "Played");
|
||||
|
||||
b.ToTable("UserData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.AccessSchedule", b =>
|
||||
{
|
||||
b.HasOne("Jellyfin.Data.Entities.User", null)
|
||||
@@ -622,6 +1317,91 @@ namespace Jellyfin.Server.Implementations.Migrations
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.AncestorId", b =>
|
||||
{
|
||||
b.HasOne("Jellyfin.Data.Entities.BaseItemEntity", "Item")
|
||||
.WithMany("Children")
|
||||
.HasForeignKey("ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Jellyfin.Data.Entities.BaseItemEntity", "ParentItem")
|
||||
.WithMany("ParentAncestors")
|
||||
.HasForeignKey("ParentItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Item");
|
||||
|
||||
b.Navigation("ParentItem");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.AttachmentStreamInfo", b =>
|
||||
{
|
||||
b.HasOne("Jellyfin.Data.Entities.BaseItemEntity", "Item")
|
||||
.WithMany()
|
||||
.HasForeignKey("ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Item");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.BaseItemImageInfo", b =>
|
||||
{
|
||||
b.HasOne("Jellyfin.Data.Entities.BaseItemEntity", "Item")
|
||||
.WithMany("Images")
|
||||
.HasForeignKey("ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Item");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.BaseItemMetadataField", b =>
|
||||
{
|
||||
b.HasOne("Jellyfin.Data.Entities.BaseItemEntity", "Item")
|
||||
.WithMany("LockedFields")
|
||||
.HasForeignKey("ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Item");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.BaseItemProvider", b =>
|
||||
{
|
||||
b.HasOne("Jellyfin.Data.Entities.BaseItemEntity", "Item")
|
||||
.WithMany("Provider")
|
||||
.HasForeignKey("ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Item");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.BaseItemTrailerType", b =>
|
||||
{
|
||||
b.HasOne("Jellyfin.Data.Entities.BaseItemEntity", "Item")
|
||||
.WithMany("TrailerTypes")
|
||||
.HasForeignKey("ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Item");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.Chapter", b =>
|
||||
{
|
||||
b.HasOne("Jellyfin.Data.Entities.BaseItemEntity", "Item")
|
||||
.WithMany("Chapters")
|
||||
.HasForeignKey("ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Item");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.DisplayPreferences", b =>
|
||||
{
|
||||
b.HasOne("Jellyfin.Data.Entities.User", null)
|
||||
@@ -657,6 +1437,55 @@ namespace Jellyfin.Server.Implementations.Migrations
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.ItemValueMap", b =>
|
||||
{
|
||||
b.HasOne("Jellyfin.Data.Entities.BaseItemEntity", "Item")
|
||||
.WithMany("ItemValues")
|
||||
.HasForeignKey("ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Jellyfin.Data.Entities.ItemValue", "ItemValue")
|
||||
.WithMany("BaseItemsMap")
|
||||
.HasForeignKey("ItemValueId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Item");
|
||||
|
||||
b.Navigation("ItemValue");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.MediaStreamInfo", b =>
|
||||
{
|
||||
b.HasOne("Jellyfin.Data.Entities.BaseItemEntity", "Item")
|
||||
.WithMany("MediaStreams")
|
||||
.HasForeignKey("ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Item");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.PeopleBaseItemMap", b =>
|
||||
{
|
||||
b.HasOne("Jellyfin.Data.Entities.BaseItemEntity", "Item")
|
||||
.WithMany("Peoples")
|
||||
.HasForeignKey("ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Jellyfin.Data.Entities.People", "People")
|
||||
.WithMany("BaseItems")
|
||||
.HasForeignKey("PeopleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Item");
|
||||
|
||||
b.Navigation("People");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.Permission", b =>
|
||||
{
|
||||
b.HasOne("Jellyfin.Data.Entities.User", null)
|
||||
@@ -684,11 +1513,65 @@ namespace Jellyfin.Server.Implementations.Migrations
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.UserData", b =>
|
||||
{
|
||||
b.HasOne("Jellyfin.Data.Entities.BaseItemEntity", "Item")
|
||||
.WithMany("UserData")
|
||||
.HasForeignKey("ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Jellyfin.Data.Entities.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Item");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.BaseItemEntity", b =>
|
||||
{
|
||||
b.Navigation("Chapters");
|
||||
|
||||
b.Navigation("Children");
|
||||
|
||||
b.Navigation("Images");
|
||||
|
||||
b.Navigation("ItemValues");
|
||||
|
||||
b.Navigation("LockedFields");
|
||||
|
||||
b.Navigation("MediaStreams");
|
||||
|
||||
b.Navigation("ParentAncestors");
|
||||
|
||||
b.Navigation("Peoples");
|
||||
|
||||
b.Navigation("Provider");
|
||||
|
||||
b.Navigation("TrailerTypes");
|
||||
|
||||
b.Navigation("UserData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.DisplayPreferences", b =>
|
||||
{
|
||||
b.Navigation("HomeSections");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.ItemValue", b =>
|
||||
{
|
||||
b.Navigation("BaseItemsMap");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.People", b =>
|
||||
{
|
||||
b.Navigation("BaseItems");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jellyfin.Data.Entities.User", b =>
|
||||
{
|
||||
b.Navigation("AccessSchedules");
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.ModelConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// AncestorId configuration.
|
||||
/// </summary>
|
||||
public class AncestorIdConfiguration : IEntityTypeConfiguration<AncestorId>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public void Configure(EntityTypeBuilder<AncestorId> builder)
|
||||
{
|
||||
builder.HasKey(e => new { e.ItemId, e.ParentItemId });
|
||||
builder.HasIndex(e => e.ParentItemId);
|
||||
builder.HasOne(e => e.ParentItem).WithMany(e => e.ParentAncestors).HasForeignKey(f => f.ParentItemId);
|
||||
builder.HasOne(e => e.Item).WithMany(e => e.Children).HasForeignKey(f => f.ItemId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using Jellyfin.Data.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.ModelConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// FluentAPI configuration for the AttachmentStreamInfo entity.
|
||||
/// </summary>
|
||||
public class AttachmentStreamInfoConfiguration : IEntityTypeConfiguration<AttachmentStreamInfo>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public void Configure(EntityTypeBuilder<AttachmentStreamInfo> builder)
|
||||
{
|
||||
builder.HasKey(e => new { e.ItemId, e.Index });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using SQLitePCL;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.ModelConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// Configuration for BaseItem.
|
||||
/// </summary>
|
||||
public class BaseItemConfiguration : IEntityTypeConfiguration<BaseItemEntity>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public void Configure(EntityTypeBuilder<BaseItemEntity> builder)
|
||||
{
|
||||
builder.HasKey(e => e.Id);
|
||||
// TODO: See rant in entity file.
|
||||
// builder.HasOne(e => e.Parent).WithMany(e => e.DirectChildren).HasForeignKey(e => e.ParentId);
|
||||
// builder.HasOne(e => e.TopParent).WithMany(e => e.AllChildren).HasForeignKey(e => e.TopParentId);
|
||||
// builder.HasOne(e => e.Season).WithMany(e => e.SeasonEpisodes).HasForeignKey(e => e.SeasonId);
|
||||
// builder.HasOne(e => e.Series).WithMany(e => e.SeriesEpisodes).HasForeignKey(e => e.SeriesId);
|
||||
builder.HasMany(e => e.Peoples);
|
||||
builder.HasMany(e => e.UserData);
|
||||
builder.HasMany(e => e.ItemValues);
|
||||
builder.HasMany(e => e.MediaStreams);
|
||||
builder.HasMany(e => e.Chapters);
|
||||
builder.HasMany(e => e.Provider);
|
||||
builder.HasMany(e => e.ParentAncestors);
|
||||
builder.HasMany(e => e.Children);
|
||||
builder.HasMany(e => e.LockedFields);
|
||||
builder.HasMany(e => e.TrailerTypes);
|
||||
builder.HasMany(e => e.Images);
|
||||
|
||||
builder.HasIndex(e => e.Path);
|
||||
builder.HasIndex(e => e.ParentId);
|
||||
builder.HasIndex(e => e.PresentationUniqueKey);
|
||||
builder.HasIndex(e => new { e.Id, e.Type, e.IsFolder, e.IsVirtualItem });
|
||||
|
||||
// covering index
|
||||
builder.HasIndex(e => new { e.TopParentId, e.Id });
|
||||
// series
|
||||
builder.HasIndex(e => new { e.Type, e.SeriesPresentationUniqueKey, e.PresentationUniqueKey, e.SortName });
|
||||
// series counts
|
||||
// seriesdateplayed sort order
|
||||
builder.HasIndex(e => new { e.Type, e.SeriesPresentationUniqueKey, e.IsFolder, e.IsVirtualItem });
|
||||
// live tv programs
|
||||
builder.HasIndex(e => new { e.Type, e.TopParentId, e.StartDate });
|
||||
// covering index for getitemvalues
|
||||
builder.HasIndex(e => new { e.Type, e.TopParentId, e.Id });
|
||||
// used by movie suggestions
|
||||
builder.HasIndex(e => new { e.Type, e.TopParentId, e.PresentationUniqueKey });
|
||||
// latest items
|
||||
builder.HasIndex(e => new { e.Type, e.TopParentId, e.IsVirtualItem, e.PresentationUniqueKey, e.DateCreated });
|
||||
builder.HasIndex(e => new { e.IsFolder, e.TopParentId, e.IsVirtualItem, e.PresentationUniqueKey, e.DateCreated });
|
||||
// resume
|
||||
builder.HasIndex(e => new { e.MediaType, e.TopParentId, e.IsVirtualItem, e.PresentationUniqueKey });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Jellyfin.Data.Entities;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using SQLitePCL;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.ModelConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// Provides configuration for the BaseItemMetadataField entity.
|
||||
/// </summary>
|
||||
public class BaseItemMetadataFieldConfiguration : IEntityTypeConfiguration<BaseItemMetadataField>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public void Configure(EntityTypeBuilder<BaseItemMetadataField> builder)
|
||||
{
|
||||
builder.HasKey(e => new { e.Id, e.ItemId });
|
||||
builder.HasOne(e => e.Item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.ModelConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// BaseItemProvider configuration.
|
||||
/// </summary>
|
||||
public class BaseItemProviderConfiguration : IEntityTypeConfiguration<BaseItemProvider>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public void Configure(EntityTypeBuilder<BaseItemProvider> builder)
|
||||
{
|
||||
builder.HasKey(e => new { e.ItemId, e.ProviderId });
|
||||
builder.HasOne(e => e.Item);
|
||||
builder.HasIndex(e => new { e.ProviderId, e.ProviderValue, e.ItemId });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Jellyfin.Data.Entities;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using SQLitePCL;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.ModelConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// Provides configuration for the BaseItemMetadataField entity.
|
||||
/// </summary>
|
||||
public class BaseItemTrailerTypeConfiguration : IEntityTypeConfiguration<BaseItemTrailerType>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public void Configure(EntityTypeBuilder<BaseItemTrailerType> builder)
|
||||
{
|
||||
builder.HasKey(e => new { e.Id, e.ItemId });
|
||||
builder.HasOne(e => e.Item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.ModelConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// Chapter configuration.
|
||||
/// </summary>
|
||||
public class ChapterConfiguration : IEntityTypeConfiguration<Chapter>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public void Configure(EntityTypeBuilder<Chapter> builder)
|
||||
{
|
||||
builder.HasKey(e => new { e.ItemId, e.ChapterIndex });
|
||||
builder.HasOne(e => e.Item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.ModelConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// itemvalues Configuration.
|
||||
/// </summary>
|
||||
public class ItemValuesConfiguration : IEntityTypeConfiguration<ItemValue>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public void Configure(EntityTypeBuilder<ItemValue> builder)
|
||||
{
|
||||
builder.HasKey(e => e.ItemValueId);
|
||||
builder.HasIndex(e => new { e.Type, e.CleanValue }).IsUnique();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.ModelConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// itemvalues Configuration.
|
||||
/// </summary>
|
||||
public class ItemValuesMapConfiguration : IEntityTypeConfiguration<ItemValueMap>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public void Configure(EntityTypeBuilder<ItemValueMap> builder)
|
||||
{
|
||||
builder.HasKey(e => new { e.ItemValueId, e.ItemId });
|
||||
builder.HasOne(e => e.Item);
|
||||
builder.HasOne(e => e.ItemValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.ModelConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// People configuration.
|
||||
/// </summary>
|
||||
public class MediaStreamInfoConfiguration : IEntityTypeConfiguration<MediaStreamInfo>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public void Configure(EntityTypeBuilder<MediaStreamInfo> builder)
|
||||
{
|
||||
builder.HasKey(e => new { e.ItemId, e.StreamIndex });
|
||||
builder.HasIndex(e => e.StreamIndex);
|
||||
builder.HasIndex(e => e.StreamType);
|
||||
builder.HasIndex(e => new { e.StreamIndex, e.StreamType });
|
||||
builder.HasIndex(e => new { e.StreamIndex, e.StreamType, e.Language });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.ModelConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// People configuration.
|
||||
/// </summary>
|
||||
public class PeopleBaseItemMapConfiguration : IEntityTypeConfiguration<PeopleBaseItemMap>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public void Configure(EntityTypeBuilder<PeopleBaseItemMap> builder)
|
||||
{
|
||||
builder.HasKey(e => new { e.ItemId, e.PeopleId });
|
||||
builder.HasIndex(e => new { e.ItemId, e.SortOrder });
|
||||
builder.HasIndex(e => new { e.ItemId, e.ListOrder });
|
||||
builder.HasOne(e => e.Item);
|
||||
builder.HasOne(e => e.People);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.ModelConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// People configuration.
|
||||
/// </summary>
|
||||
public class PeopleConfiguration : IEntityTypeConfiguration<People>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public void Configure(EntityTypeBuilder<People> builder)
|
||||
{
|
||||
builder.HasKey(e => e.Id);
|
||||
builder.HasIndex(e => e.Name);
|
||||
builder.HasMany(e => e.BaseItems);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.ModelConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// FluentAPI configuration for the UserData entity.
|
||||
/// </summary>
|
||||
public class UserDataConfiguration : IEntityTypeConfiguration<UserData>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public void Configure(EntityTypeBuilder<UserData> builder)
|
||||
{
|
||||
builder.HasKey(d => new { d.ItemId, d.UserId, d.CustomDataKey });
|
||||
builder.HasIndex(d => new { d.ItemId, d.UserId, d.Played });
|
||||
builder.HasIndex(d => new { d.ItemId, d.UserId, d.PlaybackPositionTicks });
|
||||
builder.HasIndex(d => new { d.ItemId, d.UserId, d.IsFavorite });
|
||||
builder.HasIndex(d => new { d.ItemId, d.UserId, d.LastPlayedDate });
|
||||
builder.HasOne(e => e.Item);
|
||||
}
|
||||
}
|
||||
@@ -179,7 +179,7 @@ public class TrickplayManager : ITrickplayManager
|
||||
{
|
||||
// Extract images
|
||||
// Note: Media sources under parent items exist as their own video/item as well. Only use this video stream for trickplay.
|
||||
var mediaSource = video.GetMediaSources(false).Find(source => Guid.Parse(source.Id).Equals(video.Id));
|
||||
var mediaSource = video.GetMediaSources(false).FirstOrDefault(source => Guid.Parse(source.Id).Equals(video.Id));
|
||||
|
||||
if (mediaSource is null)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user