From 07afbdaa4bd8ef7f8ca5c58d3b771ca12703b7be Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Fri, 24 Nov 2023 00:46:16 +0100 Subject: [PATCH] Add support for datetimes --- .../Kyoo.Abstractions/Models/Utils/Filter.cs | 24 +++++++++++++++---- .../Repositories/LocalRepository.cs | 4 ++-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/back/src/Kyoo.Abstractions/Models/Utils/Filter.cs b/back/src/Kyoo.Abstractions/Models/Utils/Filter.cs index 79ba0c41..03516ab0 100644 --- a/back/src/Kyoo.Abstractions/Models/Utils/Filter.cs +++ b/back/src/Kyoo.Abstractions/Models/Utils/Filter.cs @@ -17,11 +17,13 @@ // along with Kyoo. If not, see . using System; +using System.Collections; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Linq.Expressions; using System.Reflection; +using Kyoo.Abstractions.Models.Attributes; using Sprache; namespace Kyoo.Abstractions.Models.Utils; @@ -115,9 +117,12 @@ public abstract record Filter : Filter return property.Then(prop => { - PropertyInfo? propInfo = typeof(T).GetProperty(prop, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); + Type[] types = typeof(T).GetCustomAttribute()?.Types ?? new[] { typeof(T) }; + PropertyInfo? propInfo = types + .Select(x => x.GetProperty(prop, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance)) + .FirstOrDefault(); if (propInfo == null) - throw new ValidationException($"The given filter {property} is invalid."); + throw new ValidationException($"The given filter '{prop}' is invalid."); Parser value; @@ -149,14 +154,25 @@ public abstract record Filter : Filter throw new ValidationException($"Invalid enum value. Unexpected {x}"); }); } - // TODO: Support arrays + else if (propInfo.PropertyType == typeof(DateTime)) + { + value = + from year in Parse.Digit.Repeat(4).Text().Select(int.Parse) + from yd in Parse.Char('-') + from mouth in Parse.Digit.Repeat(2).Text().Select(int.Parse) + from md in Parse.Char('-') + from day in Parse.Digit.Repeat(2).Text().Select(int.Parse) + select new DateTime(year, mouth, day) as object; + } + else if (typeof(IEnumerable).IsAssignableFrom(propInfo.PropertyType)) + throw new ValidationException("Can't filter a list with a default comparator, use the 'in' filter."); else throw new ValidationException("Unfilterable field found"); return from eq in op from val in value - select apply(prop, val); + select apply(propInfo.Name, val); }); } diff --git a/back/src/Kyoo.Core/Controllers/Repositories/LocalRepository.cs b/back/src/Kyoo.Core/Controllers/Repositories/LocalRepository.cs index 840f9de4..07b886e5 100644 --- a/back/src/Kyoo.Core/Controllers/Repositories/LocalRepository.cs +++ b/back/src/Kyoo.Core/Controllers/Repositories/LocalRepository.cs @@ -113,7 +113,7 @@ namespace Kyoo.Core.Controllers return _Sort(query, sortBy, false).ThenBy(x => x.Id); } - protected static Expression> ParseFilter(Filter? filter) + protected Expression> ParseFilter(Filter? filter) { if (filter == null) return x => true; @@ -259,7 +259,7 @@ namespace Kyoo.Core.Controllers } else GetRandomSortKeys(seed, out xkey, out rkey); - BinaryExpression lastCompare = ApiHelper.StringCompatibleExpression(comparer, xkey, rkey); + BinaryExpression lastCompare = null;//ApiHelper.StringCompatibleExpression(comparer, xkey, rkey); // Comparing a value with null always return false for nulls so we must add nulls to the results manually. // Postgres sorts them after values so we will do the same