Merge remote-tracking branch 'upstream/master' into fix-byname-queries
This commit is contained in:
@@ -35,11 +35,40 @@ public sealed partial class BaseItemRepository
|
||||
{
|
||||
dbQuery = TranslateQuery(dbQuery, context, filter);
|
||||
dbQuery = ApplyGroupingFilter(context, dbQuery, filter);
|
||||
dbQuery = ApplyAdjacencyFilter(context, dbQuery, filter);
|
||||
dbQuery = ApplyQueryPaging(dbQuery, filter);
|
||||
dbQuery = ApplyNavigations(dbQuery, filter);
|
||||
return dbQuery;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trims an ordered query down to the AdjacentTo item and its immediate neighbours.
|
||||
/// </summary>
|
||||
private IQueryable<BaseItemEntity> ApplyAdjacencyFilter(JellyfinDbContext context, IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter)
|
||||
{
|
||||
if (filter.AdjacentTo.IsNullOrEmpty())
|
||||
{
|
||||
return dbQuery;
|
||||
}
|
||||
|
||||
// Adjacency is relative to the result set and the order the query asked for, so the ids have
|
||||
// to be read back in that order.
|
||||
var orderedIds = dbQuery.Select(e => e.Id).ToList();
|
||||
var index = orderedIds.IndexOf(filter.AdjacentTo.Value);
|
||||
if (index < 0)
|
||||
{
|
||||
// The item isn't part of this result set, so it has no neighbours in it either.
|
||||
return dbQuery.Take(0);
|
||||
}
|
||||
|
||||
var start = Math.Max(index - 1, 0);
|
||||
var adjacentIds = orderedIds.GetRange(start, Math.Min(index + 2, orderedIds.Count) - start);
|
||||
|
||||
var adjacentQuery = context.BaseItems.AsNoTracking().AsSingleQuery().Where(e => adjacentIds.Contains(e.Id));
|
||||
|
||||
return ApplyOrder(adjacentQuery, filter, context);
|
||||
}
|
||||
|
||||
private IQueryable<BaseItemEntity> ApplyQueryPaging(IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter)
|
||||
{
|
||||
if (filter.Limit.HasValue || filter.StartIndex.HasValue)
|
||||
@@ -244,8 +273,8 @@ public sealed partial class BaseItemRepository
|
||||
dbQuery = dbQuery.Include(e => e.Images);
|
||||
}
|
||||
|
||||
// Include LinkedChildEntities for container types and videos that use them
|
||||
// (BoxSet, Playlist, CollectionFolder for manual linking; Video, Movie for alternate versions).
|
||||
// Include LinkedChildEntities for container types and videos that use them (BoxSet, Playlist,
|
||||
// CollectionFolder for manual linking; every video type for alternate versions).
|
||||
// When IncludeItemTypes is empty (any type may be returned), always include them to ensure
|
||||
// LinkedChildren are loaded before items are saved back, preventing accidental deletion.
|
||||
var linkedChildTypes = new[]
|
||||
@@ -254,7 +283,10 @@ public sealed partial class BaseItemRepository
|
||||
BaseItemKind.Playlist,
|
||||
BaseItemKind.CollectionFolder,
|
||||
BaseItemKind.Video,
|
||||
BaseItemKind.Movie
|
||||
BaseItemKind.Movie,
|
||||
BaseItemKind.Episode,
|
||||
BaseItemKind.MusicVideo,
|
||||
BaseItemKind.Trailer
|
||||
};
|
||||
if (filter.IncludeItemTypes.Length == 0 || filter.IncludeItemTypes.Any(linkedChildTypes.Contains))
|
||||
{
|
||||
@@ -390,7 +422,8 @@ public sealed partial class BaseItemRepository
|
||||
|
||||
var baseQuery = context.BaseItems
|
||||
.AsNoTracking()
|
||||
.Where(b => allDescendantIds.Contains(b.Id) && !b.IsFolder && !b.IsVirtualItem);
|
||||
.Where(b => allDescendantIds.Contains(b.Id))
|
||||
.Where(DescendantQueryHelper.IsCountableLeaf);
|
||||
|
||||
return ApplyAccessFiltering(context, baseQuery, filter);
|
||||
}
|
||||
@@ -628,7 +661,7 @@ public sealed partial class BaseItemRepository
|
||||
|
||||
var leafItems = context.BaseItems
|
||||
.AsNoTracking()
|
||||
.Where(e => !e.IsFolder && !e.IsVirtualItem);
|
||||
.Where(DescendantQueryHelper.IsCountableLeaf);
|
||||
|
||||
return ApplyAccessFiltering(context, leafItems, new InternalItemsQuery(user) { IncludeOwnedItems = includeOwnedItems });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user