diff options
| author | Shadowghost <Shadowghost@users.noreply.github.com> | 2026-09-15 11:17:09 -0400 |
|---|---|---|
| committer | Cody Robibero <cody@robibe.ro> | 2026-09-15 11:17:09 -0400 |
| commit | 2151b992f96f6f0ba9d404977d536741a281584c (patch) | |
| tree | 5d3f1d098e49dbac3b74246a4e5ed5462d230bbe /MediaBrowser.Controller | |
| parent | 8cd2293ff9bf4e0a797d1bcdc7d9addda53324b2 (diff) | |
Backport pull request #18039 from jellyfin/release-12.z
Stop resolving items with every field where only stored columns are read
Original-merge: 408e5e01b1447e24689bd3653e2328bf173c8ce3
Merged-by: crobibero <cody@robibe.ro>
Backported-by: Cody Robibero <cody@robibe.ro>
Diffstat (limited to 'MediaBrowser.Controller')
| -rw-r--r-- | MediaBrowser.Controller/Dto/DtoOptions.cs | 14 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/Folder.cs | 18 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/Movies/BoxSet.cs | 15 |
3 files changed, 37 insertions, 10 deletions
diff --git a/MediaBrowser.Controller/Dto/DtoOptions.cs b/MediaBrowser.Controller/Dto/DtoOptions.cs index 052626355f..4259b7b65c 100644 --- a/MediaBrowser.Controller/Dto/DtoOptions.cs +++ b/MediaBrowser.Controller/Dto/DtoOptions.cs @@ -47,6 +47,20 @@ namespace MediaBrowser.Controller.Dto } /// <summary> + /// Gets options that populate nothing beyond the item's own stored columns. + /// </summary> + /// <remarks> + /// Each enabled field group is a collection the item query left-joins, so the rows returned are + /// the product of the item's provider, image and user data counts. Never use this for items that + /// get saved back: saving rewrites the owned rows from what the instance holds. + /// </remarks> + public static DtoOptions StoredColumnsOnly => new(false) + { + EnableImages = false, + EnableUserData = false + }; + + /// <summary> /// Gets or sets the fields to populate on the DTO. /// </summary> public IReadOnlyList<ItemFields> Fields { get; set; } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index dae4612aa1..626bc0d5a1 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -1687,7 +1687,17 @@ namespace MediaBrowser.Controller.Entities /// <returns>IEnumerable{BaseItem}.</returns> public List<BaseItem> GetLinkedChildren() { - var resolved = ResolveLinkedChildren(LinkedChildren); + return GetLinkedChildren(new DtoOptions()); + } + + /// <summary> + /// Gets the linked children, populating only what <paramref name="options"/> asks for. + /// </summary> + /// <param name="options">Fields to populate on the resolved children.</param> + /// <returns>The resolved children.</returns> + public List<BaseItem> GetLinkedChildren(DtoOptions options) + { + var resolved = ResolveLinkedChildren(LinkedChildren, options); var list = new List<BaseItem>(resolved.Count); foreach (var (_, item) in resolved) { @@ -1804,8 +1814,9 @@ namespace MediaBrowser.Controller.Entities /// path (legacy path-based resolution). /// </summary> /// <param name="linkedChildren">Linked children to resolve.</param> + /// <param name="options">Fields to populate on the resolved items; all fields when null.</param> /// <returns>Each input entry paired with its resolved item; entries that fail to resolve are dropped.</returns> - private List<(LinkedChild Info, BaseItem Item)> ResolveLinkedChildren(IReadOnlyList<LinkedChild> linkedChildren) + private List<(LinkedChild Info, BaseItem Item)> ResolveLinkedChildren(IReadOnlyList<LinkedChild> linkedChildren, DtoOptions options = null) { var resolved = new List<(LinkedChild Info, BaseItem Item)>(linkedChildren.Count); if (linkedChildren.Count == 0) @@ -1827,7 +1838,8 @@ namespace MediaBrowser.Controller.Entities { var batched = LibraryManager.GetItemList(new InternalItemsQuery { - ItemIds = [.. idsToBatch] + ItemIds = [.. idsToBatch], + DtoOptions = options ?? new DtoOptions() }); byId = new Dictionary<Guid, BaseItem>(batched.Count); foreach (var item in batched) diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index d7f9102be9..16d8bfe391 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -11,6 +11,7 @@ using Jellyfin.Data; using Jellyfin.Data.Enums; using Jellyfin.Database.Implementations.Entities; using Jellyfin.Database.Implementations.Enums; +using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Querying; @@ -89,7 +90,7 @@ namespace MediaBrowser.Controller.Entities.Movies return base.GetNonCachedChildren(directoryService); } - return Enumerable.Empty<BaseItem>(); + return []; } protected override IReadOnlyList<BaseItem> LoadChildren() @@ -172,7 +173,7 @@ namespace MediaBrowser.Controller.Entities.Movies var libraryFolderIds = LibraryFolderIds; if (libraryFolderIds is null) { - linkedItems = GetLinkedChildren(); + linkedItems = GetLinkedChildren(DtoOptions.StoredColumnsOnly); libraryFolderIds = GetLibraryFolderIds(linkedItems); } @@ -191,7 +192,7 @@ namespace MediaBrowser.Controller.Entities.Movies // If user has parental controls, hide the BoxSet when all children are restricted if (user.MaxParentalRatingScore.HasValue) { - linkedItems ??= GetLinkedChildren(); + linkedItems ??= GetLinkedChildren(DtoOptions.StoredColumnsOnly); if (linkedItems.Count > 0 && linkedItems.All(child => !child.IsParentalAllowed(user, true))) { return false; @@ -248,7 +249,7 @@ namespace MediaBrowser.Controller.Entities.Movies public Guid[] GetLibraryFolderIds() { - return GetLibraryFolderIds(GetLinkedChildren()); + return GetLibraryFolderIds(GetLinkedChildren(DtoOptions.StoredColumnsOnly)); } private Guid[] GetLibraryFolderIds(IEnumerable<BaseItem> linkedChildren) @@ -280,13 +281,13 @@ namespace MediaBrowser.Controller.Entities.Movies { expandedFolders.Add(item.Id); - return FlattenItems(boxset.GetLinkedChildren(), expandedFolders); + return FlattenItems(boxset.GetLinkedChildren(DtoOptions.StoredColumnsOnly), expandedFolders); } - return Array.Empty<BaseItem>(); + return []; } - return new[] { item }; + return [item]; } } } |
