Applied review comments

This commit is contained in:
JPVenson 2024-11-24 10:58:09 +00:00
parent 80cace4321
commit 6a08361f6f
2 changed files with 92 additions and 68 deletions

View File

@ -42,20 +42,7 @@ namespace Jellyfin.Server.Implementations.Item;
/// <summary> /// <summary>
/// Handles all storage logic for BaseItems. /// Handles all storage logic for BaseItems.
/// </summary> /// </summary>
/// <remarks> public sealed class BaseItemRepository
/// Initializes a new instance of the <see cref="BaseItemRepository"/> class.
/// </remarks>
/// <param name="dbProvider">The db factory.</param>
/// <param name="appHost">The Application host.</param>
/// <param name="itemTypeLookup">The static type lookup.</param>
/// <param name="serverConfigurationManager">The server Configuration manager.</param>
/// <param name="logger">System logger.</param>
public sealed class BaseItemRepository(
IDbContextFactory<JellyfinDbContext> dbProvider,
IServerApplicationHost appHost,
IItemTypeLookup itemTypeLookup,
IServerConfigurationManager serverConfigurationManager,
ILogger<BaseItemRepository> logger)
: IItemRepository, IDisposable : IItemRepository, IDisposable
{ {
/// <summary> /// <summary>
@ -63,8 +50,41 @@ public sealed class BaseItemRepository(
/// so that we can de-serialize properly when we don't have strong types. /// so that we can de-serialize properly when we don't have strong types.
/// </summary> /// </summary>
private static readonly ConcurrentDictionary<string, Type?> _typeMap = new ConcurrentDictionary<string, Type?>(); private static readonly ConcurrentDictionary<string, Type?> _typeMap = new ConcurrentDictionary<string, Type?>();
private readonly IDbContextFactory<JellyfinDbContext> _dbProvider;
private readonly IServerApplicationHost _appHost;
private readonly IItemTypeLookup _itemTypeLookup;
private readonly IServerConfigurationManager _serverConfigurationManager;
private readonly ILogger<BaseItemRepository> _logger;
private bool _disposed; private bool _disposed;
private static readonly IReadOnlyList<ItemValueType> _getAllArtistsValueTypes = [ItemValueType.Artist, ItemValueType.AlbumArtist];
private static readonly IReadOnlyList<ItemValueType> _getArtistValueTypes = [ItemValueType.Artist];
private static readonly IReadOnlyList<ItemValueType> _getAlbumArtistValueTypes = [ItemValueType.AlbumArtist];
private static readonly IReadOnlyList<ItemValueType> _getStudiosValueTypes = [ItemValueType.Studios];
private static readonly IReadOnlyList<ItemValueType> _getGenreValueTypes = [ItemValueType.Studios];
/// <summary>
/// Initializes a new instance of the <see cref="BaseItemRepository"/> class.
/// </summary>
/// <param name="dbProvider">The db factory.</param>
/// <param name="appHost">The Application host.</param>
/// <param name="itemTypeLookup">The static type lookup.</param>
/// <param name="serverConfigurationManager">The server Configuration manager.</param>
/// <param name="logger">System logger.</param>
public BaseItemRepository(
IDbContextFactory<JellyfinDbContext> dbProvider,
IServerApplicationHost appHost,
IItemTypeLookup itemTypeLookup,
IServerConfigurationManager serverConfigurationManager,
ILogger<BaseItemRepository> logger)
{
_dbProvider = dbProvider;
_appHost = appHost;
_itemTypeLookup = itemTypeLookup;
_serverConfigurationManager = serverConfigurationManager;
_logger = logger;
}
/// <inheritdoc/> /// <inheritdoc/>
public void Dispose() public void Dispose()
{ {
@ -81,7 +101,7 @@ public sealed class BaseItemRepository(
{ {
ArgumentNullException.ThrowIfNull(id.IsEmpty() ? null : id); ArgumentNullException.ThrowIfNull(id.IsEmpty() ? null : id);
using var context = dbProvider.CreateDbContext(); using var context = _dbProvider.CreateDbContext();
using var transaction = context.Database.BeginTransaction(); using var transaction = context.Database.BeginTransaction();
context.PeopleBaseItemMap.Where(e => e.ItemId == id).ExecuteDelete(); context.PeopleBaseItemMap.Where(e => e.ItemId == id).ExecuteDelete();
context.Peoples.Where(e => e.BaseItems!.Count == 0).ExecuteDelete(); context.Peoples.Where(e => e.BaseItems!.Count == 0).ExecuteDelete();
@ -100,11 +120,11 @@ public sealed class BaseItemRepository(
/// <inheritdoc /> /// <inheritdoc />
public void UpdateInheritedValues() public void UpdateInheritedValues()
{ {
using var context = dbProvider.CreateDbContext(); using var context = _dbProvider.CreateDbContext();
using var transaction = context.Database.BeginTransaction(); using var transaction = context.Database.BeginTransaction();
context.ItemValuesMap.Where(e => e.ItemValue.Type == ItemValueType.InheritedTags).ExecuteDelete(); context.ItemValuesMap.Where(e => e.ItemValue.Type == ItemValueType.InheritedTags).ExecuteDelete();
// ItemValue Inheritence is now correctly mapped via AncestorId on demand // ItemValue Inheritance is now correctly mapped via AncestorId on demand
context.SaveChanges(); context.SaveChanges();
transaction.Commit(); transaction.Commit();
@ -116,64 +136,64 @@ public sealed class BaseItemRepository(
ArgumentNullException.ThrowIfNull(filter); ArgumentNullException.ThrowIfNull(filter);
PrepareFilterQuery(filter); PrepareFilterQuery(filter);
using var context = dbProvider.CreateDbContext(); using var context = _dbProvider.CreateDbContext();
return ApplyQueryFilter(context.BaseItems.AsNoTracking(), context, filter).Select(e => e.Id).ToArray(); return ApplyQueryFilter(context.BaseItems.AsNoTracking(), context, filter).Select(e => e.Id).ToArray();
} }
/// <inheritdoc /> /// <inheritdoc />
public QueryResult<(BaseItemDto Item, ItemCounts ItemCounts)> GetAllArtists(InternalItemsQuery filter) public QueryResult<(BaseItemDto Item, ItemCounts ItemCounts)> GetAllArtists(InternalItemsQuery filter)
{ {
return GetItemValues(filter, [ItemValueType.Artist, ItemValueType.AlbumArtist], itemTypeLookup.BaseItemKindNames[BaseItemKind.MusicArtist]!); return GetItemValues(filter, _getAllArtistsValueTypes, _itemTypeLookup.BaseItemKindNames[BaseItemKind.MusicArtist]);
} }
/// <inheritdoc /> /// <inheritdoc />
public QueryResult<(BaseItemDto Item, ItemCounts ItemCounts)> GetArtists(InternalItemsQuery filter) public QueryResult<(BaseItemDto Item, ItemCounts ItemCounts)> GetArtists(InternalItemsQuery filter)
{ {
return GetItemValues(filter, [ItemValueType.Artist], itemTypeLookup.BaseItemKindNames[BaseItemKind.MusicArtist]!); return GetItemValues(filter, _getArtistValueTypes, _itemTypeLookup.BaseItemKindNames[BaseItemKind.MusicArtist]);
} }
/// <inheritdoc /> /// <inheritdoc />
public QueryResult<(BaseItemDto Item, ItemCounts ItemCounts)> GetAlbumArtists(InternalItemsQuery filter) public QueryResult<(BaseItemDto Item, ItemCounts ItemCounts)> GetAlbumArtists(InternalItemsQuery filter)
{ {
return GetItemValues(filter, [ItemValueType.AlbumArtist], itemTypeLookup.BaseItemKindNames[BaseItemKind.MusicArtist]!); return GetItemValues(filter, _getAlbumArtistValueTypes, _itemTypeLookup.BaseItemKindNames[BaseItemKind.MusicArtist]);
} }
/// <inheritdoc /> /// <inheritdoc />
public QueryResult<(BaseItemDto Item, ItemCounts ItemCounts)> GetStudios(InternalItemsQuery filter) public QueryResult<(BaseItemDto Item, ItemCounts ItemCounts)> GetStudios(InternalItemsQuery filter)
{ {
return GetItemValues(filter, [ItemValueType.Studios], itemTypeLookup.BaseItemKindNames[BaseItemKind.Studio]!); return GetItemValues(filter, _getStudiosValueTypes, _itemTypeLookup.BaseItemKindNames[BaseItemKind.Studio]);
} }
/// <inheritdoc /> /// <inheritdoc />
public QueryResult<(BaseItemDto Item, ItemCounts ItemCounts)> GetGenres(InternalItemsQuery filter) public QueryResult<(BaseItemDto Item, ItemCounts ItemCounts)> GetGenres(InternalItemsQuery filter)
{ {
return GetItemValues(filter, [ItemValueType.Genre], itemTypeLookup.BaseItemKindNames[BaseItemKind.Genre]!); return GetItemValues(filter, _getGenreValueTypes, _itemTypeLookup.BaseItemKindNames[BaseItemKind.Genre]);
} }
/// <inheritdoc /> /// <inheritdoc />
public QueryResult<(BaseItemDto Item, ItemCounts ItemCounts)> GetMusicGenres(InternalItemsQuery filter) public QueryResult<(BaseItemDto Item, ItemCounts ItemCounts)> GetMusicGenres(InternalItemsQuery filter)
{ {
return GetItemValues(filter, [ItemValueType.Genre], itemTypeLookup.BaseItemKindNames[BaseItemKind.MusicGenre]!); return GetItemValues(filter, _getGenreValueTypes, _itemTypeLookup.BaseItemKindNames[BaseItemKind.MusicGenre]);
} }
/// <inheritdoc /> /// <inheritdoc />
public IReadOnlyList<string> GetStudioNames() public IReadOnlyList<string> GetStudioNames()
{ {
return GetItemValueNames([ItemValueType.Studios], [], []); return GetItemValueNames(_getStudiosValueTypes, [], []);
} }
/// <inheritdoc /> /// <inheritdoc />
public IReadOnlyList<string> GetAllArtistNames() public IReadOnlyList<string> GetAllArtistNames()
{ {
return GetItemValueNames([ItemValueType.Artist, ItemValueType.AlbumArtist], [], []); return GetItemValueNames(_getAllArtistsValueTypes, [], []);
} }
/// <inheritdoc /> /// <inheritdoc />
public IReadOnlyList<string> GetMusicGenreNames() public IReadOnlyList<string> GetMusicGenreNames()
{ {
return GetItemValueNames( return GetItemValueNames(
[ItemValueType.Genre], _getGenreValueTypes,
itemTypeLookup.MusicGenreTypes, _itemTypeLookup.MusicGenreTypes,
[]); []);
} }
@ -181,9 +201,9 @@ public sealed class BaseItemRepository(
public IReadOnlyList<string> GetGenreNames() public IReadOnlyList<string> GetGenreNames()
{ {
return GetItemValueNames( return GetItemValueNames(
[ItemValueType.Genre], _getGenreValueTypes,
[], [],
itemTypeLookup.MusicGenreTypes); _itemTypeLookup.MusicGenreTypes);
} }
/// <inheritdoc cref="IItemRepository"/> /// <inheritdoc cref="IItemRepository"/>
@ -202,12 +222,11 @@ public sealed class BaseItemRepository(
PrepareFilterQuery(filter); PrepareFilterQuery(filter);
var result = new QueryResult<BaseItemDto>(); var result = new QueryResult<BaseItemDto>();
using var context = dbProvider.CreateDbContext(); using var context = _dbProvider.CreateDbContext();
IQueryable<BaseItemEntity> dbQuery = PrepareItemQuery(context, filter); IQueryable<BaseItemEntity> dbQuery = PrepareItemQuery(context, filter);
dbQuery = TranslateQuery(dbQuery, context, filter); dbQuery = TranslateQuery(dbQuery, context, filter);
// dbQuery = dbQuery.Distinct();
if (filter.EnableTotalRecordCount) if (filter.EnableTotalRecordCount)
{ {
result.TotalRecordCount = dbQuery.Count(); result.TotalRecordCount = dbQuery.Count();
@ -227,11 +246,11 @@ public sealed class BaseItemRepository(
ArgumentNullException.ThrowIfNull(filter); ArgumentNullException.ThrowIfNull(filter);
PrepareFilterQuery(filter); PrepareFilterQuery(filter);
using var context = dbProvider.CreateDbContext(); using var context = _dbProvider.CreateDbContext();
IQueryable<BaseItemEntity> dbQuery = PrepareItemQuery(context, filter); IQueryable<BaseItemEntity> dbQuery = PrepareItemQuery(context, filter);
dbQuery = TranslateQuery(dbQuery, context, filter); dbQuery = TranslateQuery(dbQuery, context, filter);
// dbQuery = dbQuery.Distinct();
dbQuery = ApplyGroupingFilter(dbQuery, filter); dbQuery = ApplyGroupingFilter(dbQuery, filter);
dbQuery = ApplyQueryPageing(dbQuery, filter); dbQuery = ApplyQueryPageing(dbQuery, filter);
@ -240,6 +259,11 @@ public sealed class BaseItemRepository(
private IQueryable<BaseItemEntity> ApplyGroupingFilter(IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter) private IQueryable<BaseItemEntity> ApplyGroupingFilter(IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter)
{ {
// This whole block is needed to filter duplicate entries on request
// for the time beeing it cannot be used because it would destroy the ordering
// this results in "duplicate" responses for queries that try to lookup individual series or multiple versions but
// for that case the invoker has to run a DistinctBy(e => e.PresentationUniqueKey) on their own
// var enableGroupByPresentationUniqueKey = EnableGroupByPresentationUniqueKey(filter); // var enableGroupByPresentationUniqueKey = EnableGroupByPresentationUniqueKey(filter);
// if (enableGroupByPresentationUniqueKey && filter.GroupBySeriesPresentationUniqueKey) // if (enableGroupByPresentationUniqueKey && filter.GroupBySeriesPresentationUniqueKey)
// { // {
@ -318,7 +342,7 @@ public sealed class BaseItemRepository(
// Hack for right now since we currently don't support filtering out these duplicates within a query // Hack for right now since we currently don't support filtering out these duplicates within a query
PrepareFilterQuery(filter); PrepareFilterQuery(filter);
using var context = dbProvider.CreateDbContext(); using var context = _dbProvider.CreateDbContext();
var dbQuery = TranslateQuery(context.BaseItems.AsNoTracking(), context, filter); var dbQuery = TranslateQuery(context.BaseItems.AsNoTracking(), context, filter);
return dbQuery.Count(); return dbQuery.Count();
@ -346,7 +370,7 @@ public sealed class BaseItemRepository(
ArgumentNullException.ThrowIfNull(item); ArgumentNullException.ThrowIfNull(item);
var images = item.ImageInfos.Select(e => Map(item.Id, e)); var images = item.ImageInfos.Select(e => Map(item.Id, e));
using var context = dbProvider.CreateDbContext(); using var context = _dbProvider.CreateDbContext();
using var transaction = context.Database.BeginTransaction(); using var transaction = context.Database.BeginTransaction();
context.BaseItemImageInfos.Where(e => e.ItemId == item.Id).ExecuteDelete(); context.BaseItemImageInfos.Where(e => e.ItemId == item.Id).ExecuteDelete();
context.BaseItemImageInfos.AddRange(images); context.BaseItemImageInfos.AddRange(images);
@ -382,9 +406,9 @@ public sealed class BaseItemRepository(
tuples.Add((item, ancestorIds, topParent, userdataKey, inheritedTags)); tuples.Add((item, ancestorIds, topParent, userdataKey, inheritedTags));
} }
var localFuckingItemValueCache = new Dictionary<(int MagicNumber, string Value), Guid>(); var localItemValueCache = new Dictionary<(int MagicNumber, string Value), Guid>();
using var context = dbProvider.CreateDbContext(); using var context = _dbProvider.CreateDbContext();
using var transaction = context.Database.BeginTransaction(); using var transaction = context.Database.BeginTransaction();
foreach (var item in tuples) foreach (var item in tuples)
{ {
@ -427,7 +451,7 @@ public sealed class BaseItemRepository(
context.ItemValuesMap.Where(e => e.ItemId == entity.Id).ExecuteDelete(); context.ItemValuesMap.Where(e => e.ItemId == entity.Id).ExecuteDelete();
foreach (var itemValue in itemValuesToSave) foreach (var itemValue in itemValuesToSave)
{ {
if (!localFuckingItemValueCache.TryGetValue(itemValue, out var refValue)) if (!localItemValueCache.TryGetValue(itemValue, out var refValue))
{ {
refValue = context.ItemValues refValue = context.ItemValues
.Where(f => f.CleanValue == GetCleanValue(itemValue.Value) && (int)f.Type == itemValue.MagicNumber) .Where(f => f.CleanValue == GetCleanValue(itemValue.Value) && (int)f.Type == itemValue.MagicNumber)
@ -444,7 +468,7 @@ public sealed class BaseItemRepository(
ItemValueId = refValue = Guid.NewGuid(), ItemValueId = refValue = Guid.NewGuid(),
Value = itemValue.Value Value = itemValue.Value
}); });
localFuckingItemValueCache[itemValue] = refValue; localItemValueCache[itemValue] = refValue;
} }
context.ItemValuesMap.Add(new ItemValueMap() context.ItemValuesMap.Add(new ItemValueMap()
@ -469,7 +493,7 @@ public sealed class BaseItemRepository(
throw new ArgumentException("Guid can't be empty", nameof(id)); throw new ArgumentException("Guid can't be empty", nameof(id));
} }
using var context = dbProvider.CreateDbContext(); using var context = _dbProvider.CreateDbContext();
var item = PrepareItemQuery(context, new() var item = PrepareItemQuery(context, new()
{ {
DtoOptions = new() DtoOptions = new()
@ -813,9 +837,9 @@ public sealed class BaseItemRepository(
return entity; return entity;
} }
private string[] GetItemValueNames(ItemValueType[] itemValueTypes, IReadOnlyList<string> withItemTypes, IReadOnlyList<string> excludeItemTypes) private string[] GetItemValueNames(IReadOnlyList<ItemValueType> itemValueTypes, IReadOnlyList<string> withItemTypes, IReadOnlyList<string> excludeItemTypes)
{ {
using var context = dbProvider.CreateDbContext(); using var context = _dbProvider.CreateDbContext();
var query = context.ItemValuesMap var query = context.ItemValuesMap
.AsNoTracking() .AsNoTracking()
@ -842,7 +866,7 @@ public sealed class BaseItemRepository(
private BaseItemDto DeserialiseBaseItem(BaseItemEntity baseItemEntity, bool skipDeserialization = false) private BaseItemDto DeserialiseBaseItem(BaseItemEntity baseItemEntity, bool skipDeserialization = false)
{ {
ArgumentNullException.ThrowIfNull(baseItemEntity, nameof(baseItemEntity)); ArgumentNullException.ThrowIfNull(baseItemEntity, nameof(baseItemEntity));
if (serverConfigurationManager?.Configuration is null) if (_serverConfigurationManager?.Configuration is null)
{ {
throw new InvalidOperationException("Server Configuration manager or configuration is null"); throw new InvalidOperationException("Server Configuration manager or configuration is null");
} }
@ -850,9 +874,9 @@ public sealed class BaseItemRepository(
var typeToSerialise = GetType(baseItemEntity.Type); var typeToSerialise = GetType(baseItemEntity.Type);
return BaseItemRepository.DeserialiseBaseItem( return BaseItemRepository.DeserialiseBaseItem(
baseItemEntity, baseItemEntity,
logger, _logger,
appHost, _appHost,
skipDeserialization || (serverConfigurationManager.Configuration.SkipDeserializationForBasicTypes && (typeToSerialise == typeof(Channel) || typeToSerialise == typeof(UserRootFolder)))); skipDeserialization || (_serverConfigurationManager.Configuration.SkipDeserializationForBasicTypes && (typeToSerialise == typeof(Channel) || typeToSerialise == typeof(UserRootFolder))));
} }
/// <summary> /// <summary>
@ -889,7 +913,7 @@ public sealed class BaseItemRepository(
return Map(baseItemEntity, dto, appHost); return Map(baseItemEntity, dto, appHost);
} }
private QueryResult<(BaseItemDto Item, ItemCounts ItemCounts)> GetItemValues(InternalItemsQuery filter, ItemValueType[] itemValueTypes, string returnType) private QueryResult<(BaseItemDto Item, ItemCounts ItemCounts)> GetItemValues(InternalItemsQuery filter, IReadOnlyList<ItemValueType> itemValueTypes, string returnType)
{ {
ArgumentNullException.ThrowIfNull(filter); ArgumentNullException.ThrowIfNull(filter);
@ -898,7 +922,7 @@ public sealed class BaseItemRepository(
filter.EnableTotalRecordCount = false; filter.EnableTotalRecordCount = false;
} }
using var context = dbProvider.CreateDbContext(); using var context = _dbProvider.CreateDbContext();
var innerQuery = new InternalItemsQuery(filter.User) var innerQuery = new InternalItemsQuery(filter.User)
{ {
@ -951,13 +975,13 @@ public sealed class BaseItemRepository(
result.TotalRecordCount = query.GroupBy(e => e.PresentationUniqueKey).Select(e => e.First()).Count(); result.TotalRecordCount = query.GroupBy(e => e.PresentationUniqueKey).Select(e => e.First()).Count();
} }
var seriesTypeName = itemTypeLookup.BaseItemKindNames[BaseItemKind.Series]; var seriesTypeName = _itemTypeLookup.BaseItemKindNames[BaseItemKind.Series];
var movieTypeName = itemTypeLookup.BaseItemKindNames[BaseItemKind.Movie]; var movieTypeName = _itemTypeLookup.BaseItemKindNames[BaseItemKind.Movie];
var episodeTypeName = itemTypeLookup.BaseItemKindNames[BaseItemKind.Episode]; var episodeTypeName = _itemTypeLookup.BaseItemKindNames[BaseItemKind.Episode];
var musicAlbumTypeName = itemTypeLookup.BaseItemKindNames[BaseItemKind.MusicAlbum]; var musicAlbumTypeName = _itemTypeLookup.BaseItemKindNames[BaseItemKind.MusicAlbum];
var musicArtistTypeName = itemTypeLookup.BaseItemKindNames[BaseItemKind.MusicArtist]; var musicArtistTypeName = _itemTypeLookup.BaseItemKindNames[BaseItemKind.MusicArtist];
var audioTypeName = itemTypeLookup.BaseItemKindNames[BaseItemKind.Audio]; var audioTypeName = _itemTypeLookup.BaseItemKindNames[BaseItemKind.Audio];
var trailerTypeName = itemTypeLookup.BaseItemKindNames[BaseItemKind.Trailer]; var trailerTypeName = _itemTypeLookup.BaseItemKindNames[BaseItemKind.Trailer];
var resultQuery = query.Select(e => new var resultQuery = query.Select(e => new
{ {
@ -1071,7 +1095,7 @@ public sealed class BaseItemRepository(
return null; return null;
} }
return appHost.ReverseVirtualPath(path); return _appHost.ReverseVirtualPath(path);
} }
private List<string> GetItemByNameTypesInQuery(InternalItemsQuery query) private List<string> GetItemByNameTypesInQuery(InternalItemsQuery query)
@ -1080,27 +1104,27 @@ public sealed class BaseItemRepository(
if (IsTypeInQuery(BaseItemKind.Person, query)) if (IsTypeInQuery(BaseItemKind.Person, query))
{ {
list.Add(itemTypeLookup.BaseItemKindNames[BaseItemKind.Person]!); list.Add(_itemTypeLookup.BaseItemKindNames[BaseItemKind.Person]!);
} }
if (IsTypeInQuery(BaseItemKind.Genre, query)) if (IsTypeInQuery(BaseItemKind.Genre, query))
{ {
list.Add(itemTypeLookup.BaseItemKindNames[BaseItemKind.Genre]!); list.Add(_itemTypeLookup.BaseItemKindNames[BaseItemKind.Genre]!);
} }
if (IsTypeInQuery(BaseItemKind.MusicGenre, query)) if (IsTypeInQuery(BaseItemKind.MusicGenre, query))
{ {
list.Add(itemTypeLookup.BaseItemKindNames[BaseItemKind.MusicGenre]!); list.Add(_itemTypeLookup.BaseItemKindNames[BaseItemKind.MusicGenre]!);
} }
if (IsTypeInQuery(BaseItemKind.MusicArtist, query)) if (IsTypeInQuery(BaseItemKind.MusicArtist, query))
{ {
list.Add(itemTypeLookup.BaseItemKindNames[BaseItemKind.MusicArtist]!); list.Add(_itemTypeLookup.BaseItemKindNames[BaseItemKind.MusicArtist]!);
} }
if (IsTypeInQuery(BaseItemKind.Studio, query)) if (IsTypeInQuery(BaseItemKind.Studio, query))
{ {
list.Add(itemTypeLookup.BaseItemKindNames[BaseItemKind.Studio]!); list.Add(_itemTypeLookup.BaseItemKindNames[BaseItemKind.Studio]!);
} }
return list; return list;
@ -1193,7 +1217,7 @@ public sealed class BaseItemRepository(
private IQueryable<BaseItemEntity> ApplyOrder(IQueryable<BaseItemEntity> query, InternalItemsQuery filter) private IQueryable<BaseItemEntity> ApplyOrder(IQueryable<BaseItemEntity> query, InternalItemsQuery filter)
{ {
var orderBy = filter.OrderBy; var orderBy = filter.OrderBy;
bool hasSearch = !string.IsNullOrEmpty(filter.SearchTerm); var hasSearch = !string.IsNullOrEmpty(filter.SearchTerm);
if (hasSearch) if (hasSearch)
{ {
@ -1390,7 +1414,7 @@ public sealed class BaseItemRepository(
var excludeTypes = filter.ExcludeItemTypes; var excludeTypes = filter.ExcludeItemTypes;
if (excludeTypes.Length == 1) if (excludeTypes.Length == 1)
{ {
if (itemTypeLookup.BaseItemKindNames.TryGetValue(excludeTypes[0], out var excludeTypeName)) if (_itemTypeLookup.BaseItemKindNames.TryGetValue(excludeTypes[0], out var excludeTypeName))
{ {
baseQuery = baseQuery.Where(e => e.Type != excludeTypeName); baseQuery = baseQuery.Where(e => e.Type != excludeTypeName);
} }
@ -1400,7 +1424,7 @@ public sealed class BaseItemRepository(
var excludeTypeName = new List<string>(); var excludeTypeName = new List<string>();
foreach (var excludeType in excludeTypes) foreach (var excludeType in excludeTypes)
{ {
if (itemTypeLookup.BaseItemKindNames.TryGetValue(excludeType, out var baseItemKindName)) if (_itemTypeLookup.BaseItemKindNames.TryGetValue(excludeType, out var baseItemKindName))
{ {
excludeTypeName.Add(baseItemKindName!); excludeTypeName.Add(baseItemKindName!);
} }
@ -1411,7 +1435,7 @@ public sealed class BaseItemRepository(
} }
else if (includeTypes.Length == 1) else if (includeTypes.Length == 1)
{ {
if (itemTypeLookup.BaseItemKindNames.TryGetValue(includeTypes[0], out var includeTypeName)) if (_itemTypeLookup.BaseItemKindNames.TryGetValue(includeTypes[0], out var includeTypeName))
{ {
baseQuery = baseQuery.Where(e => e.Type == includeTypeName); baseQuery = baseQuery.Where(e => e.Type == includeTypeName);
} }
@ -1421,7 +1445,7 @@ public sealed class BaseItemRepository(
var includeTypeName = new List<string>(); var includeTypeName = new List<string>();
foreach (var includeType in includeTypes) foreach (var includeType in includeTypes)
{ {
if (itemTypeLookup.BaseItemKindNames.TryGetValue(includeType, out var baseItemKindName)) if (_itemTypeLookup.BaseItemKindNames.TryGetValue(includeType, out var baseItemKindName))
{ {
includeTypeName.Add(baseItemKindName!); includeTypeName.Add(baseItemKindName!);
} }

View File

@ -18,5 +18,5 @@ public interface IItemTypeLookup
/// <summary> /// <summary>
/// Gets mapping for all BaseItemKinds and their expected serialization target. /// Gets mapping for all BaseItemKinds and their expected serialization target.
/// </summary> /// </summary>
public IReadOnlyDictionary<BaseItemKind, string> BaseItemKindNames { get; } IReadOnlyDictionary<BaseItemKind, string> BaseItemKindNames { get; }
} }