Solving the afterID lambda

This commit is contained in:
Zoe Roux 2020-07-03 17:10:27 +02:00
parent 1da26b449b
commit 4e9096ae76
4 changed files with 30 additions and 11 deletions

View File

@ -237,6 +237,18 @@ namespace Kyoo
return member.Member.Name;
}
public static Expression StringCompatibleExpression(Func<Expression, Expression, BinaryExpression> operand,
Expression left,
Expression right)
{
if (left is MemberExpression member && ((PropertyInfo)member.Member).PropertyType == typeof(string))
{
MethodCallExpression call = Expression.Call(typeof(string), "Compare", null, left, right);
return operand(call, Expression.Constant(0));
}
return operand(left, right);
}
public static Expression<Func<T, bool>> ParseWhere<T>(Dictionary<string, string> where)
{
if (where == null || where.Count == 0)
@ -259,16 +271,21 @@ namespace Kyoo
if (property == null)
throw new ArgumentException($"No filterable parameter with the name {key}.");
MemberExpression propertyExpr = Expression.Property(param, property);
ConstantExpression valueExpr = Expression.Constant(Convert.ChangeType(value, property.PropertyType));
Type propertyType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
object val = string.IsNullOrEmpty(value) || value.Equals("null", StringComparison.OrdinalIgnoreCase)
? null
: Convert.ChangeType(value, propertyType);
ConstantExpression valueExpr = Expression.Constant(val);
Expression condition = operand switch
{
"eq" => Expression.Equal(propertyExpr, valueExpr),
"not" => Expression.NotEqual(propertyExpr, valueExpr),
"lt" => Expression.LessThan(propertyExpr, valueExpr),
"lte" => Expression.LessThanOrEqual(propertyExpr, valueExpr),
"gt" => Expression.GreaterThan(propertyExpr, valueExpr),
"gte" => Expression.GreaterThanOrEqual(propertyExpr, valueExpr),
"lt" => StringCompatibleExpression(Expression.LessThan, propertyExpr, valueExpr),
"lte" => StringCompatibleExpression(Expression.LessThanOrEqual, propertyExpr, valueExpr),
"gt" => StringCompatibleExpression(Expression.GreaterThan, propertyExpr, valueExpr),
"gte" => StringCompatibleExpression(Expression.GreaterThanOrEqual, propertyExpr, valueExpr),
// TODO Implement the Like expression
"like" => throw new NotImplementedException("Like not implemented yet"),
_ => throw new ArgumentException($"Invalid operand: {operand}")

View File

@ -88,7 +88,8 @@ namespace Kyoo.Controllers
Show after = await Get(page.AfterID);
object afterObj = sortKey.Compile()(after);
query = query.Where(Expression.Lambda<Func<Show, bool>>(
Expression.GreaterThan(sortKey, Expression.Constant(afterObj))
Utility.StringCompatibleExpression(Expression.GreaterThan, sortKey.Body, Expression.Constant(afterObj)),
(ParameterExpression)((MemberExpression)sortKey.Body).Expression
));
}
query = query.Take(page.Count <= 0 ? 20 : page.Count);

View File

@ -39,7 +39,7 @@ namespace Kyoo
{
configuration.RootPath = "wwwroot";
});
services.AddControllers().AddNewtonsoftJson();
services.AddHttpClient();

View File

@ -1,11 +1,8 @@
using System;
using Kyoo.Models;
using Kyoo.Models;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Castle.DynamicProxy.Generators.Emitters.SimpleAST;
using Kyoo.Controllers;
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
@ -43,6 +40,10 @@ namespace Kyoo.Api
[FromQuery] int afterID,
[FromQuery] Dictionary<string, string> where)
{
where.Remove("sortBy");
where.Remove("limit");
where.Remove("afterID");
return await _libraryManager.GetShows(Utility.ParseWhere<Show>(where),
new Sort<Show>(sortBy),
new Pagination(limit, afterID));