From fe9c96d052d6815f0d32833711a865c2f33d9999 Mon Sep 17 00:00:00 2001 From: JPVenson Date: Wed, 9 Oct 2024 23:55:28 +0000 Subject: [PATCH] Used enum value for ItemValueType --- Jellyfin.Data/Entities/ItemValue.cs | 2 +- Jellyfin.Data/Entities/ItemValueType.cs | 41 +++++++++ .../Item/BaseItemRepository.cs | 90 +++++++------------ .../Migrations/Routines/MigrateLibraryDb.cs | 2 +- 4 files changed, 77 insertions(+), 58 deletions(-) create mode 100644 Jellyfin.Data/Entities/ItemValueType.cs diff --git a/Jellyfin.Data/Entities/ItemValue.cs b/Jellyfin.Data/Entities/ItemValue.cs index 78da478b1c..bfa53cd465 100644 --- a/Jellyfin.Data/Entities/ItemValue.cs +++ b/Jellyfin.Data/Entities/ItemValue.cs @@ -23,7 +23,7 @@ public class ItemValue /// /// Gets or Sets the Type. /// - public required int Type { get; set; } + public required ItemValueType Type { get; set; } /// /// Gets or Sets the Value. diff --git a/Jellyfin.Data/Entities/ItemValueType.cs b/Jellyfin.Data/Entities/ItemValueType.cs new file mode 100644 index 0000000000..006036b40e --- /dev/null +++ b/Jellyfin.Data/Entities/ItemValueType.cs @@ -0,0 +1,41 @@ +namespace Jellyfin.Data.Entities; + +/// +/// Provides the Value types for an . +/// +#pragma warning disable CA1027 // Mark enums with FlagsAttribute +public enum ItemValueType +#pragma warning restore CA1027 // Mark enums with FlagsAttribute +{ + /// + /// Artists. + /// +#pragma warning disable CA1008 // Enums should have zero value. Cannot apply here. + Artist = 0, +#pragma warning restore CA1008 // Enums should have zero value + + /// + /// Album. + /// + AlbumArtist = 1, + + /// + /// Genre. + /// + Genre = 2, + + /// + /// Studios. + /// + Studios = 3, + + /// + /// Tags. + /// + Tags = 4, + + /// + /// InheritedTags. + /// + InheritedTags = 6, +} diff --git a/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs b/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs index 6603b15e29..702e72f0ce 100644 --- a/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs +++ b/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs @@ -21,6 +21,7 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Querying; using Microsoft.EntityFrameworkCore; +using SQLitePCL; using BaseItemDto = MediaBrowser.Controller.Entities.BaseItem; using BaseItemEntity = Jellyfin.Data.Entities.BaseItemEntity; #pragma warning disable RS0030 // Do not use banned APIs @@ -82,23 +83,23 @@ public sealed class BaseItemRepository(IDbContextFactory dbPr using var context = dbProvider.CreateDbContext(); using var transaction = context.Database.BeginTransaction(); - context.ItemValues.Where(e => e.Type == 6).ExecuteDelete(); - context.ItemValues.AddRange(context.ItemValues.Where(e => e.Type == 4).Select(e => new ItemValue() + context.ItemValues.Where(e => e.Type == ItemValueType.InheritedTags).ExecuteDelete(); + context.ItemValues.AddRange(context.ItemValues.Where(e => e.Type == ItemValueType.Tags).Select(e => new ItemValue() { CleanValue = e.CleanValue, ItemId = e.ItemId, - Type = 6, + Type = ItemValueType.InheritedTags, Value = e.Value, Item = null! })); context.ItemValues.AddRange( - context.AncestorIds.Join(context.ItemValues.Where(e => e.Value != null && e.Type == 4), e => e.ParentItemId, e => e.ItemId, (e, f) => new ItemValue() + context.AncestorIds.Join(context.ItemValues.Where(e => e.Value != null && e.Type == ItemValueType.Tags), e => e.ParentItemId, e => e.ItemId, (e, f) => new ItemValue() { CleanValue = f.CleanValue, ItemId = e.ItemId, Item = null!, - Type = 6, + Type = ItemValueType.InheritedTags, Value = f.Value })); context.SaveChanges(); @@ -721,13 +722,13 @@ public sealed class BaseItemRepository(IDbContextFactory dbPr if (filter.ArtistIds.Length > 0) { baseQuery = baseQuery - .Where(e => e.ItemValues!.Any(f => f.Type <= 1 && artistQuery.Any(w => w.CleanName == f.CleanValue))); + .Where(e => e.ItemValues!.Any(f => f.Type <= ItemValueType.Artist && artistQuery.Any(w => w.CleanName == f.CleanValue))); } if (filter.AlbumArtistIds.Length > 0) { baseQuery = baseQuery - .Where(e => e.ItemValues!.Any(f => f.Type == 1 && artistQuery.Any(w => w.CleanName == f.CleanValue))); + .Where(e => e.ItemValues!.Any(f => f.Type == ItemValueType.Artist && artistQuery.Any(w => w.CleanName == f.CleanValue))); } if (filter.ContributingArtistIds.Length > 0) @@ -745,40 +746,40 @@ public sealed class BaseItemRepository(IDbContextFactory dbPr { var excludeArtistQuery = context.BaseItems.Where(w => filter.ExcludeArtistIds.Contains(w.Id)); baseQuery = baseQuery - .Where(e => !e.ItemValues!.Any(f => f.Type <= 1 && artistQuery.Any(w => w.CleanName == f.CleanValue))); + .Where(e => !e.ItemValues!.Any(f => f.Type <= ItemValueType.Artist && artistQuery.Any(w => w.CleanName == f.CleanValue))); } if (filter.GenreIds.Count > 0) { baseQuery = baseQuery - .Where(e => e.ItemValues!.Any(f => f.Type == 2 && context.BaseItems.Where(w => filter.GenreIds.Contains(w.Id)).Any(w => w.CleanName == f.CleanValue))); + .Where(e => e.ItemValues!.Any(f => f.Type == ItemValueType.Genre && context.BaseItems.Where(w => filter.GenreIds.Contains(w.Id)).Any(w => w.CleanName == f.CleanValue))); } if (filter.Genres.Count > 0) { var cleanGenres = filter.Genres.Select(e => GetCleanValue(e)).ToArray(); baseQuery = baseQuery - .Where(e => e.ItemValues!.Any(f => f.Type == 2 && cleanGenres.Contains(f.CleanValue))); + .Where(e => e.ItemValues!.Any(f => f.Type == ItemValueType.Genre && cleanGenres.Contains(f.CleanValue))); } if (tags.Count > 0) { var cleanValues = tags.Select(e => GetCleanValue(e)).ToArray(); baseQuery = baseQuery - .Where(e => e.ItemValues!.Any(f => f.Type == 4 && cleanValues.Contains(f.CleanValue))); + .Where(e => e.ItemValues!.Any(f => f.Type == ItemValueType.Tags && cleanValues.Contains(f.CleanValue))); } if (excludeTags.Count > 0) { var cleanValues = excludeTags.Select(e => GetCleanValue(e)).ToArray(); baseQuery = baseQuery - .Where(e => !e.ItemValues!.Any(f => f.Type == 4 && cleanValues.Contains(f.CleanValue))); + .Where(e => !e.ItemValues!.Any(f => f.Type == ItemValueType.Tags && cleanValues.Contains(f.CleanValue))); } if (filter.StudioIds.Length > 0) { baseQuery = baseQuery - .Where(e => e.ItemValues!.Any(f => f.Type == 3 && context.BaseItems.Where(w => filter.StudioIds.Contains(w.Id)).Any(w => w.CleanName == f.CleanValue))); + .Where(e => e.ItemValues!.Any(f => f.Type == ItemValueType.Studios && context.BaseItems.Where(w => filter.StudioIds.Contains(w.Id)).Any(w => w.CleanName == f.CleanValue))); } if (filter.OfficialRatings.Length > 0) @@ -935,13 +936,13 @@ public sealed class BaseItemRepository(IDbContextFactory dbPr if (filter.IsDeadArtist.HasValue && filter.IsDeadArtist.Value) { baseQuery = baseQuery - .Where(e => e.ItemValues!.Any(f => (f.Type == 0 || f.Type == 1) && f.CleanValue == e.CleanName)); + .Where(e => e.ItemValues!.Any(f => (f.Type == 0 || f.Type == ItemValueType.AlbumArtist) && f.CleanValue == e.CleanName)); } if (filter.IsDeadStudio.HasValue && filter.IsDeadStudio.Value) { baseQuery = baseQuery - .Where(e => e.ItemValues!.Any(f => f.Type == 3 && f.CleanValue == e.CleanName)); + .Where(e => e.ItemValues!.Any(f => f.Type == ItemValueType.Studios && f.CleanValue == e.CleanName)); } if (filter.IsDeadPerson.HasValue && filter.IsDeadPerson.Value) @@ -1080,7 +1081,7 @@ public sealed class BaseItemRepository(IDbContextFactory dbPr if (filter.ExcludeInheritedTags.Length > 0) { baseQuery = baseQuery - .Where(e => !e.ItemValues!.Where(e => e.Type == 6) + .Where(e => !e.ItemValues!.Where(e => e.Type == ItemValueType.InheritedTags) .Any(f => filter.ExcludeInheritedTags.Contains(f.CleanValue))); } @@ -1091,10 +1092,10 @@ public sealed class BaseItemRepository(IDbContextFactory dbPr if (includeTypes.Length == 1 && includeTypes.FirstOrDefault() is BaseItemKind.Episode) { baseQuery = baseQuery - .Where(e => e.ItemValues!.Where(e => e.Type == 6) + .Where(e => e.ItemValues!.Where(e => e.Type == ItemValueType.InheritedTags) .Any(f => filter.IncludeInheritedTags.Contains(f.CleanValue)) || - (e.ParentId.HasValue && context.ItemValues.Where(w => w.ItemId == e.ParentId.Value)!.Where(e => e.Type == 6) + (e.ParentId.HasValue && context.ItemValues.Where(w => w.ItemId == e.ParentId.Value)!.Where(e => e.Type == ItemValueType.InheritedTags) .Any(f => filter.IncludeInheritedTags.Contains(f.CleanValue)))); } @@ -1102,14 +1103,14 @@ public sealed class BaseItemRepository(IDbContextFactory dbPr else if (includeTypes.Length == 1 && includeTypes.FirstOrDefault() is BaseItemKind.Playlist) { baseQuery = baseQuery - .Where(e => e.ItemValues!.Where(e => e.Type == 6) + .Where(e => e.ItemValues!.Where(e => e.Type == ItemValueType.InheritedTags) .Any(f => filter.IncludeInheritedTags.Contains(f.CleanValue)) || e.Data!.Contains($"OwnerUserId\":\"{filter.User!.Id:N}\"")); // d ^^ this is stupid it hate this. } else { baseQuery = baseQuery - .Where(e => e.ItemValues!.Where(e => e.Type == 6) + .Where(e => e.ItemValues!.Where(e => e.Type == ItemValueType.InheritedTags) .Any(f => filter.IncludeInheritedTags.Contains(f.CleanValue))); } } @@ -1288,7 +1289,7 @@ public sealed class BaseItemRepository(IDbContextFactory dbPr entity.ItemValues.Add(new() { Item = entity, - Type = itemValue.MagicNumber, + Type = (ItemValueType)itemValue.MagicNumber, Value = itemValue.Value, CleanValue = GetCleanValue(itemValue.Value), ItemId = entity.Id @@ -1643,7 +1644,7 @@ public sealed class BaseItemRepository(IDbContextFactory dbPr using var context = dbProvider.CreateDbContext(); var query = context.ItemValues - .Where(e => itemValueTypes.Contains(e.Type)); + .Where(e => itemValueTypes.Any(w => (ItemValueType)w == e.Type)); if (withItemTypes.Count > 0) { query = query.Where(e => context.BaseItems.Where(e => withItemTypes.Contains(e.Type)).Any(f => f.ItemValues!.Any(w => w.ItemId == e.ItemId))); @@ -1694,31 +1695,7 @@ public sealed class BaseItemRepository(IDbContextFactory dbPr }; var query = TranslateQuery(context.BaseItems, context, innerQuery); - query = query.Where(e => e.Type == returnType && e.ItemValues!.Any(f => e.CleanName == f.CleanValue && itemValueTypes.Contains(f.Type))); - - var outerQuery = new InternalItemsQuery(filter.User) - { - IsPlayed = filter.IsPlayed, - IsFavorite = filter.IsFavorite, - IsFavoriteOrLiked = filter.IsFavoriteOrLiked, - IsLiked = filter.IsLiked, - IsLocked = filter.IsLocked, - NameLessThan = filter.NameLessThan, - NameStartsWith = filter.NameStartsWith, - NameStartsWithOrGreater = filter.NameStartsWithOrGreater, - Tags = filter.Tags, - OfficialRatings = filter.OfficialRatings, - StudioIds = filter.StudioIds, - GenreIds = filter.GenreIds, - Genres = filter.Genres, - Years = filter.Years, - NameContains = filter.NameContains, - SearchTerm = filter.SearchTerm, - SimilarTo = filter.SimilarTo, - ExcludeItemIds = filter.ExcludeItemIds - }; - query = TranslateQuery(query, context, outerQuery) - .OrderBy(e => e.PresentationUniqueKey); + query = query.Where(e => e.Type == returnType && e.ItemValues!.Any(f => e.CleanName == f.CleanValue && itemValueTypes.Any(w => (ItemValueType)w == f.Type))); if (filter.OrderBy.Count != 0 || filter.SimilarTo is not null @@ -1756,15 +1733,16 @@ public sealed class BaseItemRepository(IDbContextFactory dbPr var resultQuery = query.Select(e => new { item = e, + // TODO: This is bad refactor! itemCount = new ItemCounts() { - SeriesCount = e.ItemValues!.Count(e => e.Type == (int)BaseItemKind.Series), - EpisodeCount = e.ItemValues!.Count(e => e.Type == (int)BaseItemKind.Episode), - MovieCount = e.ItemValues!.Count(e => e.Type == (int)BaseItemKind.Movie), - AlbumCount = e.ItemValues!.Count(e => e.Type == (int)BaseItemKind.MusicAlbum), - ArtistCount = e.ItemValues!.Count(e => e.Type == 0 || e.Type == 1), - SongCount = e.ItemValues!.Count(e => e.Type == (int)BaseItemKind.MusicAlbum), - TrailerCount = e.ItemValues!.Count(e => e.Type == (int)BaseItemKind.Trailer), + SeriesCount = context.ItemValues.Count(f => e.ItemValues!.Any(w => w.Type == f.Type && w.CleanValue == f.CleanValue && f.Item.Type == typeof(Series).FullName)), + EpisodeCount = context.ItemValues.Count(f => e.ItemValues!.Any(w => w.Type == f.Type && w.CleanValue == f.CleanValue && f.Item.Type == typeof(Episode).FullName)), + MovieCount = context.ItemValues.Count(f => e.ItemValues!.Any(w => w.Type == f.Type && w.CleanValue == f.CleanValue && f.Item.Type == typeof(Data.Entities.Libraries.Movie).FullName)), + AlbumCount = context.ItemValues.Count(f => e.ItemValues!.Any(w => w.Type == f.Type && w.CleanValue == f.CleanValue && f.Item.Type == typeof(MusicAlbum).FullName)), + ArtistCount = context.ItemValues.Count(f => e.ItemValues!.Any(w => w.Type == f.Type && w.CleanValue == f.CleanValue && f.Item.Type == typeof(MusicArtist).FullName)), + SongCount = context.ItemValues.Count(f => e.ItemValues!.Any(w => w.Type == f.Type && w.CleanValue == f.CleanValue && f.Item.Type == typeof(Audio).FullName)), + TrailerCount = context.ItemValues.Count(f => e.ItemValues!.Any(w => w.Type == f.Type && w.CleanValue == f.CleanValue && f.Item.Type == typeof(Trailer).FullName)), } }); @@ -1995,8 +1973,8 @@ public sealed class BaseItemRepository(IDbContextFactory dbPr ItemSortBy.IsUnplayed => e => !e.UserData!.FirstOrDefault(f => f.UserId == query.User!.Id && f.Key == e.UserDataKey)!.Played, ItemSortBy.DateLastContentAdded => e => e.DateLastMediaAdded, ItemSortBy.Artist => e => e.ItemValues!.Where(f => f.Type == 0).Select(f => f.CleanValue), - ItemSortBy.AlbumArtist => e => e.ItemValues!.Where(f => f.Type == 1).Select(f => f.CleanValue), - ItemSortBy.Studio => e => e.ItemValues!.Where(f => f.Type == 3).Select(f => f.CleanValue), + ItemSortBy.AlbumArtist => e => e.ItemValues!.Where(f => f.Type == ItemValueType.AlbumArtist).Select(f => f.CleanValue), + ItemSortBy.Studio => e => e.ItemValues!.Where(f => f.Type == ItemValueType.Studios).Select(f => f.CleanValue), ItemSortBy.OfficialRating => e => e.InheritedParentalRatingValue, // ItemSortBy.SeriesDatePlayed => "(Select MAX(LastPlayedDate) from TypedBaseItems B" + GetJoinUserDataText(query) + " where Played=1 and B.SeriesPresentationUniqueKey=A.PresentationUniqueKey)", ItemSortBy.SeriesSortName => e => e.SeriesName, diff --git a/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs index be5dd0ce0f..85d537380b 100644 --- a/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs +++ b/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs @@ -227,7 +227,7 @@ public class MigrateLibraryDb : IMigrationRoutine return new ItemValue { ItemId = reader.GetGuid(0), - Type = reader.GetInt32(1), + Type = (ItemValueType)reader.GetInt32(1), Value = reader.GetString(2), CleanValue = reader.GetString(3), Item = null!