Add sort by and try includes for library items

This commit is contained in:
Zoe Roux 2023-11-18 18:39:30 +01:00
parent d01ef02389
commit 0034f93caa

View File

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