diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 2bcb10e9e1..5853ebf934 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -3253,7 +3253,7 @@ namespace Emby.Server.Implementations.Library public IReadOnlyList GetPeople(InternalPeopleQuery query) { - return _peopleRepository.GetPeople(query); + return _peopleRepository.GetPeople(query).Items; } public IReadOnlyList GetPeople(BaseItem item) @@ -3274,24 +3274,33 @@ namespace Emby.Server.Implementations.Library return []; } - public IReadOnlyList GetPeopleItems(InternalPeopleQuery query) + public QueryResult GetPeopleItems(InternalPeopleQuery query) { - return _peopleRepository.GetPeopleNames(query) - .Select(i => + var queryResult = _peopleRepository.GetPeople(query); + var baseItems = queryResult.Items.Select(i => + { + try + { + return GetPerson(i.Name); + } + catch (Exception ex) + { + _logger.LogError(ex, "error retrieving BaseItem for person: {0}", i.Name); + return null; + } + }) + .Where(i => i is not null) + .Where(i => query.User is null || i!.IsVisible(query.User)) + .OfType() + .ToList() + .AsReadOnly(); + + return new QueryResult { - try - { - return GetPerson(i); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error getting person"); - return null; - } - }) - .Where(i => i is not null) - .Where(i => query.User is null || i!.IsVisible(query.User)) - .ToList()!; // null values are filtered out + StartIndex = queryResult.StartIndex, + TotalRecordCount = queryResult.TotalRecordCount, + Items = baseItems, + }; } public IReadOnlyList GetPeopleNames(InternalPeopleQuery query) diff --git a/Jellyfin.Api/Controllers/PersonsController.cs b/Jellyfin.Api/Controllers/PersonsController.cs index 8e7026341d..9ffccaa9e9 100644 --- a/Jellyfin.Api/Controllers/PersonsController.cs +++ b/Jellyfin.Api/Controllers/PersonsController.cs @@ -116,9 +116,11 @@ public class PersonsController : BaseJellyfinApiController }); return new QueryResult( - peopleItems - .Select(person => _dtoService.GetItemByNameDto(person, dtoOptions, null, user)) - .ToArray()); + peopleItems.StartIndex, + peopleItems.TotalRecordCount, + peopleItems.Items + .Select(person => _dtoService.GetItemByNameDto(person, dtoOptions, null, user)) + .ToArray()); } /// diff --git a/Jellyfin.Server.Implementations/Item/PeopleRepository.cs b/Jellyfin.Server.Implementations/Item/PeopleRepository.cs index f918d45bcd..cfc4eb2162 100644 --- a/Jellyfin.Server.Implementations/Item/PeopleRepository.cs +++ b/Jellyfin.Server.Implementations/Item/PeopleRepository.cs @@ -1,14 +1,13 @@ using System; using System.Collections.Generic; -using System.Collections.Immutable; using System.Linq; using Jellyfin.Data.Enums; using Jellyfin.Database.Implementations; using Jellyfin.Database.Implementations.Entities; -using Jellyfin.Database.Implementations.Entities.Libraries; using Jellyfin.Extensions; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Model.Querying; using Microsoft.EntityFrameworkCore; namespace Jellyfin.Server.Implementations.Item; @@ -30,7 +29,7 @@ public class PeopleRepository(IDbContextFactory dbProvider, I private readonly IDbContextFactory _dbProvider = dbProvider; /// - public IReadOnlyList GetPeople(InternalPeopleQuery filter) + public QueryResult GetPeople(InternalPeopleQuery filter) { using var context = _dbProvider.CreateDbContext(); var dbQuery = TranslateQuery(context.Peoples.AsNoTracking(), context, filter); @@ -48,12 +47,23 @@ public class PeopleRepository(IDbContextFactory dbProvider, I dbQuery = dbQuery.OrderBy(e => e.Name); } + var count = dbQuery.Count(); + if (filter.StartIndex.HasValue && filter.StartIndex > 0) + { + dbQuery = dbQuery.Skip(filter.StartIndex.Value); + } + if (filter.Limit > 0) { dbQuery = dbQuery.Take(filter.Limit); } - return dbQuery.AsEnumerable().Select(Map).ToArray(); + return new QueryResult + { + StartIndex = filter.StartIndex ?? 0, + TotalRecordCount = count, + Items = dbQuery.AsEnumerable().Select(Map).ToArray(), + }; } /// diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 5c391098d3..7d27572052 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -558,7 +558,7 @@ namespace MediaBrowser.Controller.Library /// /// The query. /// List<Person>. - IReadOnlyList GetPeopleItems(InternalPeopleQuery query); + QueryResult GetPeopleItems(InternalPeopleQuery query); /// /// Updates the people. diff --git a/MediaBrowser.Controller/Persistence/IPeopleRepository.cs b/MediaBrowser.Controller/Persistence/IPeopleRepository.cs index 418289cb4c..a89f3ef9ee 100644 --- a/MediaBrowser.Controller/Persistence/IPeopleRepository.cs +++ b/MediaBrowser.Controller/Persistence/IPeopleRepository.cs @@ -1,13 +1,15 @@ #nullable disable -#pragma warning disable CS1591 - using System; using System.Collections.Generic; using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Querying; namespace MediaBrowser.Controller.Persistence; +/// +/// Provides methods for accessing Peoples. +/// public interface IPeopleRepository { /// @@ -15,7 +17,7 @@ public interface IPeopleRepository /// /// The query. /// The list of people matching the filter. - IReadOnlyList GetPeople(InternalPeopleQuery filter); + QueryResult GetPeople(InternalPeopleQuery filter); /// /// Updates the people.