diff --git a/back/src/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs b/back/src/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs index 25500bf2..96a885f8 100644 --- a/back/src/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs +++ b/back/src/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs @@ -20,7 +20,6 @@ using System; using System.Collections.Generic; using System.Data.Common; using System.IO; -using System.Linq.Expressions; using System.Threading.Tasks; using Kyoo.Abstractions.Controllers; using Kyoo.Abstractions.Models; @@ -66,9 +65,15 @@ namespace Kyoo.Core.Controllers if (items[0] is Show show && show.Id != 0) return show; if (items[1] is Movie movie && movie.Id != 0) + { + movie.Id = -movie.Id; return movie; + } if (items[2] is Collection collection && collection.Id != 0) + { + collection.Id += 10_000; return collection; + } throw new InvalidDataException(); } @@ -77,27 +82,48 @@ namespace Kyoo.Core.Controllers { } public async Task> GetAllOfCollection( - Expression> selector, - Expression>? where = null, + int collectionId, + Filter? filter = default, Sort? sort = default, - Pagination? limit = default, - Include? include = default) + Include? include = default, + Pagination? limit = default) { - throw new NotImplementedException(); - // return await ApplyFilters( - // _database.LibraryItems - // .Where(item => - // _database.Movies - // .Where(x => x.Id == -item.Id) - // .Any(x => x.Collections!.AsQueryable().Any(selector)) - // || _database.Shows - // .Where(x => x.Id == item.Id) - // .Any(x => x.Collections!.AsQueryable().Any(selector)) - // ), - // where, - // sort, - // limit, - // include); + // language=PostgreSQL + FormattableString sql = $""" + select + s.*, + m.* + /* includes */ + from ( + select + * -- Show + from + shows + inner join link_collection_show as ls on ls.show_id = id and ls.collection_id = {collectionId} + ) as s + full outer join ( + select + * -- Movie + from + movies + inner join link_collection_movie as lm on lm.movie_id = id and lm.collection_id = {collectionId} + ) as m on false + """; + + return await Database.Query( + sql, + new() + { + { "s", typeof(Show) }, + { "m", typeof(Movie) }, + }, + Mapper, + (id) => Get(id), + include, + filter, + sort ?? new Sort.Default(), + limit ?? new() + ); } } } diff --git a/back/src/Kyoo.Core/Views/Resources/CollectionApi.cs b/back/src/Kyoo.Core/Views/Resources/CollectionApi.cs index e8d3d285..74f6255f 100644 --- a/back/src/Kyoo.Core/Views/Resources/CollectionApi.cs +++ b/back/src/Kyoo.Core/Views/Resources/CollectionApi.cs @@ -144,17 +144,21 @@ namespace Kyoo.Core.Api [FromQuery] Pagination pagination, [FromQuery] Include? fields) { - // ICollection resources = await _items.GetAllOfCollection( - // identifier.IsSame(), - // filter, - // sortBy == new Sort.Default() ? new Sort.By(nameof(Movie.AirDate)) : sortBy, - // pagination, - // fields - // ); + int collectionId = await identifier.Match( + id => Task.FromResult(id), + async slug => (await _libraryManager.Collections.Get(slug)).Id + ); + ICollection resources = await _items.GetAllOfCollection( + collectionId, + filter, + sortBy == new Sort.Default() ? new Sort.By(nameof(Movie.AirDate)) : sortBy, + fields, + pagination + ); - // if (!resources.Any() && await _libraryManager.Collections.GetOrDefault(identifier.IsSame()) == null) + if (!resources.Any() && await _libraryManager.Collections.GetOrDefault(identifier.IsSame()) == null) return NotFound(); - // return Page(resources, pagination.Limit); + return Page(resources, pagination.Limit); } /// diff --git a/back/src/Kyoo.Meilisearch/SearchManager.cs b/back/src/Kyoo.Meilisearch/SearchManager.cs index f88f369d..dc49cb5e 100644 --- a/back/src/Kyoo.Meilisearch/SearchManager.cs +++ b/back/src/Kyoo.Meilisearch/SearchManager.cs @@ -88,7 +88,7 @@ public class SearchManager : ISearchManager }); // Since library items's ID are still ints mapped from real items ids, we must map it here to match the db's value. - // Look at the items Migration's sql to understand where magic numbers come from. + // Look at the LibraryItemRepository's Mapper to understand what those magic numbers are. List ids = res.Hits.Select(x => x.Kind switch { nameof(Show) => x.Id,