diff --git a/back/src/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs b/back/src/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs index 4b3008cd..93f9673d 100644 --- a/back/src/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs +++ b/back/src/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs @@ -20,7 +20,9 @@ using System; using System.Collections.Generic; using System.Data.Common; using System.IO; +using System.Linq; using System.Linq.Expressions; +using System.Runtime.CompilerServices; using System.Threading.Tasks; using Dapper; using Kyoo.Abstractions.Controllers; @@ -90,26 +92,41 @@ namespace Kyoo.Core.Controllers throw new NotImplementedException(); } + public string ProcessSort(Sort sort, string[] tables) + { + return sort switch + { + // TODO: Implement default sort by + Sort.Default => "", + Sort.By(string key, bool desc) => $"coalesce({tables.Select(x => $"{x}.{key}")}) {(desc ? "desc" : "asc")}", + Sort.Random(var seed) => $"md5({seed} || coalesce({tables.Select(x => $"{x}.id")}))", + Sort.Conglomerate(var list) => string.Join(", ", list.Select(x => ProcessSort(x, tables))), + _ => throw new SwitchExpressionException(), + }; + } + public async Task> GetAll( Expression>? where = null, Sort? sort = null, Pagination? limit = null, Include? include = null) { - List ret = new(limit.Limit); - // language=PostgreSQL string sql = @" - select s.*, m.*, c.* from shows as s full outer join ( + select s.*, m.*, c.*, st.* from shows as s full outer join ( select * from movies ) as m on false full outer join ( select * from collections ) as c on false + left join studios as st on st.id = coalesce(s.studio_id, m.studio_id) + order by @SortBy + limit @Take "; - var data = await _database.QueryAsync(sql, new[] { typeof(Show), typeof(Movie), typeof(Collection) }, items => + var data = await _database.QueryAsync(sql, new[] { typeof(Show), typeof(Movie), typeof(Collection), typeof(Studio) }, items => { + var studio = items[3] as Studio; if (items[0] is Show show && show.Id != 0) return show; if (items[1] is Movie movie && movie.Id != 0) @@ -117,7 +134,7 @@ namespace Kyoo.Core.Controllers if (items[2] is Collection collection && collection.Id != 0) return collection; throw new InvalidDataException(); - }, where); + }, new { SortBy = ProcessSort(sort, new[] { "s", "m", "c" }), Take = limit.Limit }); // await using DbDataReader reader = await _database.ExecuteReaderAsync(sql); // int kindOrdinal = reader.GetOrdinal("kind");