diff options
| author | Shadowghost <Shadowghost@users.noreply.github.com> | 2026-09-15 11:13:45 -0400 |
|---|---|---|
| committer | Cody Robibero <cody@robibe.ro> | 2026-09-15 11:13:45 -0400 |
| commit | fb055aa1fc44b06a7069327fa047cff933f75810 (patch) | |
| tree | 371370b56e41a53f1752300d991423d9292b489f /Jellyfin.Server | |
| parent | b70e7f60ffe19847ef6259a13075c26fb6994363 (diff) | |
Backport pull request #17835 from jellyfin/release-12.z
Clean up invalid data before running migrations
Original-merge: 75d7b2010ea2d75fdb7554c700c4e6981331b484
Merged-by: crobibero <cody@robibe.ro>
Backported-by: Cody Robibero <cody@robibe.ro>
Diffstat (limited to 'Jellyfin.Server')
| -rw-r--r-- | Jellyfin.Server/Migrations/Routines/20260825200000_ConsolidateLocalizedUserViews.cs | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/Jellyfin.Server/Migrations/Routines/20260825200000_ConsolidateLocalizedUserViews.cs b/Jellyfin.Server/Migrations/Routines/20260825200000_ConsolidateLocalizedUserViews.cs index 3fc2387e09..8eefbdb63a 100644 --- a/Jellyfin.Server/Migrations/Routines/20260825200000_ConsolidateLocalizedUserViews.cs +++ b/Jellyfin.Server/Migrations/Routines/20260825200000_ConsolidateLocalizedUserViews.cs @@ -156,6 +156,7 @@ internal class ConsolidateLocalizedUserViews : IAsyncMigrationRoutine await MoveAncestorsAsync(dbContext, canonicalId, staleIds, cancellationToken).ConfigureAwait(false); await MoveUserSettingsAsync(dbContext, canonicalId, sourceId, staleIds, cancellationToken).ConfigureAwait(false); + await MoveRemainingReferencesAsync(dbContext, newParentId, staleIds, cancellationToken).ConfigureAwait(false); // Nothing points at them any more, and BaseItems cascades on ParentId, so this has to come last. await dbContext.BaseItems @@ -171,6 +172,31 @@ internal class ConsolidateLocalizedUserViews : IAsyncMigrationRoutine canonicalId); } + private static async Task MoveRemainingReferencesAsync( + JellyfinDbContext dbContext, + Guid? canonicalId, + IReadOnlyList<Guid> staleIds, + CancellationToken cancellationToken) + { + await dbContext.BaseItems + .Where(e => e.OwnerId.HasValue) + .WhereOneOrMany(staleIds, e => e.OwnerId!.Value) + .ExecuteUpdateAsync(e => e.SetProperty(f => f.OwnerId, canonicalId), cancellationToken) + .ConfigureAwait(false); + + // Keyed by (ParentId, SortOrder), so these cannot be repointed onto the canonical view + // without risking a collision, and a view listing linked children is meaningless anyway. + await dbContext.LinkedChildren + .WhereOneOrMany(staleIds, e => e.ParentId) + .ExecuteDeleteAsync(cancellationToken) + .ConfigureAwait(false); + + await dbContext.LinkedChildren + .WhereOneOrMany(staleIds, e => e.ChildId) + .ExecuteDeleteAsync(cancellationToken) + .ConfigureAwait(false); + } + private async Task<UserView> PickSourceAsync( JellyfinDbContext dbContext, IReadOnlyList<UserView> stale, @@ -294,8 +320,10 @@ internal class ConsolidateLocalizedUserViews : IAsyncMigrationRoutine IReadOnlyList<Guid> staleIds, CancellationToken cancellationToken) { + // Ancestry recorded against items that no longer exist is dead weight. var items = await dbContext.AncestorIds .WhereOneOrMany(staleIds, e => e.ParentItemId) + .Where(e => dbContext.BaseItems.Any(item => item.Id.Equals(e.ItemId))) .Select(e => e.ItemId) .Distinct() .ToListAsync(cancellationToken) |
