Fix orphaned alt version cleanup

This commit is contained in:
Shadowghost
2026-02-15 17:34:06 +01:00
parent 50cabcd99d
commit 4ce03ffa21

View File

@@ -278,7 +278,7 @@ internal class MigrateLinkedChildren : IDatabaseMigrationRoutine
{
_logger.LogInformation("Starting cleanup of orphaned alternate version BaseItems...");
// Find BaseItems that have PrimaryVersionId set (they were alternate versions)
// Check 1: Find BaseItems that have PrimaryVersionId set (they were alternate versions)
// but no LinkedChild entry references them — meaning they're orphaned.
// This happens when a version file is renamed: the old BaseItem remains
// in the DB with a stale PrimaryVersionId but nothing links to it anymore.
@@ -288,15 +288,41 @@ internal class MigrateLinkedChildren : IDatabaseMigrationRoutine
.Select(b => b.Id)
.ToList();
if (orphanedVersionIds.Count == 0)
_logger.LogInformation("Found {Count} orphaned alternate versions with stale PrimaryVersionId.", orphanedVersionIds.Count);
// Check 2: Find generic Video items that share a parent folder with a Movie/Episode
// but are not linked as alternate versions. These are orphaned entries from renamed
// alternate version files where PrimaryVersionId was already cleared by the old server.
var specificVideoTypes = new[]
{
"MediaBrowser.Controller.Entities.Movies.Movie",
"MediaBrowser.Controller.Entities.TV.Episode"
};
var orphanedVideoIds = context.BaseItems
.Where(b => b.Type == "MediaBrowser.Controller.Entities.Video")
.Where(b => b.ExtraType == null && !b.OwnerId.HasValue)
.Where(b => !context.LinkedChildren.Any(lc => lc.ChildId.Equals(b.Id)))
.Where(b => b.ParentId.HasValue
&& context.BaseItems.Any(sibling =>
sibling.ParentId.Equals(b.ParentId)
&& specificVideoTypes.Contains(sibling.Type)))
.Select(b => b.Id)
.ToList();
_logger.LogInformation("Found {Count} orphaned generic Video items in movie/episode folders.", orphanedVideoIds.Count);
var allOrphanedIds = orphanedVersionIds.Union(orphanedVideoIds).ToList();
if (allOrphanedIds.Count == 0)
{
_logger.LogInformation("No orphaned alternate version BaseItems found.");
return;
}
_logger.LogInformation("Found {Count} orphaned alternate version BaseItems to remove.", orphanedVersionIds.Count);
_logger.LogInformation("Removing {Count} total orphaned alternate version BaseItems.", allOrphanedIds.Count);
foreach (var id in orphanedVersionIds)
foreach (var id in allOrphanedIds)
{
var item = _libraryManager.GetItemById(id);
if (item is not null)
@@ -305,7 +331,7 @@ internal class MigrateLinkedChildren : IDatabaseMigrationRoutine
}
}
_logger.LogInformation("Removed {Count} orphaned alternate version BaseItems.", orphanedVersionIds.Count);
_logger.LogInformation("Removed {Count} orphaned alternate version BaseItems.", allOrphanedIds.Count);
}
private void CleanupOrphanedLinkedChildren(JellyfinDbContext context)