Skip alternate version links when resolving link parents
This commit is contained in:
@@ -177,9 +177,17 @@ public static class DescendantQueryHelper
|
||||
// Resolves the folders whose linked children lead, at any depth, to a matching item.
|
||||
private static List<Guid> ResolveLinkParents(JellyfinDbContext context, IQueryable<Guid> matchingItemIds, IQueryable<Guid> ancestorsOfMatches)
|
||||
{
|
||||
// An alternate version is a second file for the item that links it, not a child of it, so that
|
||||
// edge is not walked. It is also the one link a non-folder owns, and there is one per remuxed
|
||||
// movie: walking it would swell this list from the BoxSet and Playlist count to the item count,
|
||||
// and the list is bound into every statement the returned queryable is embedded in.
|
||||
var containerLinks = context.LinkedChildren
|
||||
.Where(e => e.ChildType != LinkedChildType.LocalAlternateVersion
|
||||
&& e.ChildType != LinkedChildType.LinkedAlternateVersion);
|
||||
|
||||
// A link sits above the closure and above another link alike, so the hop repeats until nothing
|
||||
// new turns up. Only link owners are collected, which bounds it by BoxSets and Playlists.
|
||||
var resolved = context.LinkedChildren
|
||||
// new turns up.
|
||||
var resolved = containerLinks
|
||||
.Where(e => matchingItemIds.Contains(e.ChildId) || ancestorsOfMatches.Contains(e.ChildId))
|
||||
.Select(e => e.ParentId)
|
||||
.Distinct()
|
||||
@@ -193,11 +201,11 @@ public static class DescendantQueryHelper
|
||||
.WhereOneOrMany(frontier, e => e.ItemId)
|
||||
.Select(e => e.ParentItemId);
|
||||
|
||||
var directLinkParents = context.LinkedChildren
|
||||
var directLinkParents = containerLinks
|
||||
.WhereOneOrMany(frontier, e => e.ChildId)
|
||||
.Select(e => e.ParentId);
|
||||
|
||||
var indirectLinkParents = context.LinkedChildren
|
||||
var indirectLinkParents = containerLinks
|
||||
.Where(e => containingFolders.Contains(e.ChildId))
|
||||
.Select(e => e.ParentId);
|
||||
|
||||
|
||||
@@ -363,6 +363,44 @@ public sealed class DescendantQueryHelperTests : SqliteDbTestFixture
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFolderIdsMatching_AlternateVersionLinks_AreNotWalked()
|
||||
{
|
||||
var collections = Guid.NewGuid();
|
||||
var boxSet = Guid.NewGuid();
|
||||
var library = Guid.NewGuid();
|
||||
var movie = Guid.NewGuid();
|
||||
var alternateVersion = Guid.NewGuid();
|
||||
|
||||
using (var ctx = CreateDbContext())
|
||||
{
|
||||
AddFolder(ctx, collections);
|
||||
AddItem(ctx, boxSet, BoxSetType, isFolder: true);
|
||||
AddFolder(ctx, library);
|
||||
AddItem(ctx, movie, MovieType);
|
||||
AddItem(ctx, alternateVersion, MovieType);
|
||||
|
||||
AddAncestors(ctx, boxSet, collections);
|
||||
AddAncestors(ctx, movie, library);
|
||||
AddAncestors(ctx, alternateVersion, library);
|
||||
// Only the second file carries the subtitles, and it hangs off the movie by an alternate
|
||||
// version link. The movie is not a folder, so that link is not a parent-child edge.
|
||||
AddLink(ctx, movie, alternateVersion, LinkedChildType.LocalAlternateVersion);
|
||||
AddLink(ctx, boxSet, movie);
|
||||
AddStream(ctx, alternateVersion, MediaStreamTypeEntity.Subtitle);
|
||||
ctx.SaveChanges();
|
||||
}
|
||||
|
||||
using (var ctx = CreateDbContext())
|
||||
{
|
||||
var folders = DescendantQueryHelper.GetFolderIdsMatching(ctx, new HasSubtitles()).ToHashSet();
|
||||
|
||||
// The library still matches: the alternate version carries its own closure. The box set does
|
||||
// not, matching the descendant side, which does not follow a non-folder's links either.
|
||||
Assert.Equal([library], folders);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetOwnedDescendantIds_IgnoresLinkedChildren()
|
||||
{
|
||||
@@ -472,7 +510,7 @@ public sealed class DescendantQueryHelperTests : SqliteDbTestFixture
|
||||
}
|
||||
|
||||
// LinkedChildren is keyed on (ParentId, SortOrder), so every link of a parent needs its own slot.
|
||||
private void AddLink(JellyfinDbContext context, Guid parentId, Guid childId)
|
||||
private void AddLink(JellyfinDbContext context, Guid parentId, Guid childId, LinkedChildType childType = LinkedChildType.Manual)
|
||||
{
|
||||
_linkCounters.TryGetValue(parentId, out var sortOrder);
|
||||
_linkCounters[parentId] = sortOrder + 1;
|
||||
@@ -481,7 +519,7 @@ public sealed class DescendantQueryHelperTests : SqliteDbTestFixture
|
||||
{
|
||||
ParentId = parentId,
|
||||
ChildId = childId,
|
||||
ChildType = LinkedChildType.Manual,
|
||||
ChildType = childType,
|
||||
SortOrder = sortOrder
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user