Skip to content

Commit

Permalink
v2.3.2 (#35)
Browse files Browse the repository at this point in the history
* test search with spaces issue #33

* Update README.md

* typo fix (fields)

* add IgnoreNotMappedFiels Configuration #34

* use IgnoreNotMappedFields in orderings #34

* fix comment

* add some summary

* update to version 2.3.2
  • Loading branch information
alirezanet authored Nov 1, 2021
1 parent 25707ac commit b03a112
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/Gridify.EntityFramework/Gridify.EntityFramework.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PackageId>Gridify.EntityFramework</PackageId>
<Version>2.3.1</Version>
<Version>2.3.2</Version>
<Authors>Alireza Sabouri</Authors>
<Company>TuxTeam</Company>
<PackageDescription>Gridify (EntityFramework), Easy and optimized way to apply Filtering, Sorting, and Pagination using text-based data.</PackageDescription>
Expand Down
2 changes: 1 addition & 1 deletion src/Gridify/Gridify.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PackageId>Gridify</PackageId>
<Version>2.3.1</Version>
<Version>2.3.2</Version>
<Authors>Alireza Sabouri</Authors>
<Company>TuxTeam</Company>
<PackageDescription>Gridify, Easy and optimized way to apply Filtering, Sorting, and Pagination using text-based data.</PackageDescription>
Expand Down
31 changes: 28 additions & 3 deletions src/Gridify/GridifyExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
using Gridify.Syntax;

[assembly: InternalsVisibleTo("Gridify.EntityFramework")]

namespace Gridify
{
public static partial class GridifyExtensions
{
internal static bool EntityFrameworkCompatibilityLayer { get; set; }
public static int DefaultPageSize { get; set; } = 20;

#region "Private"

/// <summary>
Expand Down Expand Up @@ -132,13 +133,37 @@ public static IQueryable<T> ApplyOrdering<T>(this IQueryable<T> query, IGridifyO
: ProcessOrdering(query, gridifyOrdering.OrderBy!, startWithThenBy, mapper);
}

/// <summary>
/// adds Ordering to the query
/// </summary>
/// <param name="query">the original(target) queryable object</param>
/// <param name="orderBy">the ordering fields</param>
/// <param name="mapper">this is an optional parameter to apply ordering using a custom mapping configuration</param>
/// <param name="startWithThenBy">if you already have an ordering with start with ThenBy, new orderings will add on top of your orders</param>
/// <typeparam name="T">type of target entity</typeparam>
/// <returns>returns user query after applying Ordering </returns>
public static IQueryable<T> ApplyOrdering<T>(this IQueryable<T> query, string orderBy, IGridifyMapper<T>? mapper = null,
bool startWithThenBy = false)
{
mapper = mapper.FixMapper();
return string.IsNullOrWhiteSpace(orderBy)
? query
: ProcessOrdering(query, orderBy, startWithThenBy, mapper);
}

private static IQueryable<T> ProcessOrdering<T>(IQueryable<T> query, string orderings, bool startWithThenBy, IGridifyMapper<T> mapper)
{
var isFirst = !startWithThenBy;
foreach (var (member, isAscending) in ParseOrderings(orderings))
{
// skip if there is no mappings available
if (!mapper.HasMap(member)) continue;
if (!mapper.HasMap(member))
{
// skip if there is no mappings available
if (mapper.Configuration.IgnoreNotMappedFields)
continue;

throw new GridifyMapperException($"Mapping '{member}' not found");
}

if (isFirst)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Gridify/GridifyMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public IEnumerable<IGMap<T>> GetCurrentMaps()

/// <summary>
/// Converts current mappings to a comma seperated list of map names.
/// eg, filed1,field2,field3
/// eg, field1,field2,field3
/// </summary>
/// <returns>a comma seperated string</returns>
public override string ToString() => string.Join(",", _mappings.Select(q => q.From));
Expand Down
10 changes: 10 additions & 0 deletions src/Gridify/GridifyMapperConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@ namespace Gridify
public record GridifyMapperConfiguration
{
public bool CaseSensitive { get; set; }

/// <summary>
/// This option enables the 'null' keyword in filtering operations
/// </summary>
public bool AllowNullSearch { get; set; } = true;
/// <summary>
/// If true, in filtering and ordering operations,
/// gridify doesn't return any exceptions when a mapping
/// is not defined for the fields
/// </summary>
public bool IgnoreNotMappedFields { get; set; }
}
}
29 changes: 20 additions & 9 deletions src/Gridify/Syntax/SyntaxTreeToQueryConvertor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ public static class ExpressionToQueryConvertor
private static (Expression<Func<T, bool>> Expression, bool IsNested)? ConvertBinaryExpressionSyntaxToQuery<T>(
BinaryExpressionSyntax binarySyntax, IGridifyMapper<T> mapper)
{

var fieldExpression = binarySyntax.Left as FieldExpressionSyntax;

var left = fieldExpression?.FieldToken.Text.Trim();
var right = (binarySyntax.Right as ValueExpressionSyntax);
var op = binarySyntax.OperatorToken;
Expand All @@ -23,10 +22,10 @@ private static (Expression<Func<T, bool>> Expression, bool IsNested)? ConvertBin

var gMap = mapper.GetGMap(left);

if (gMap == null) return null;
if (gMap == null) throw new GridifyMapperException($"Mapping '{left}' not found");

if (fieldExpression!.IsCollection)
gMap.To = UpdateExpressionIndex(gMap.To,fieldExpression.Index);
gMap.To = UpdateExpressionIndex(gMap.To, fieldExpression.Index);

if (gMap.IsNestedCollection)
{
Expand All @@ -44,11 +43,11 @@ private static (Expression<Func<T, bool>> Expression, bool IsNested)? ConvertBin

private static LambdaExpression UpdateExpressionIndex(LambdaExpression exp, int index)
{
var parameter = exp.Parameters[0];
var parameter = exp.Parameters[0];
var unary = exp.Body as UnaryExpression;
var body = unary!.Operand as MemberExpression;
var newBody = new PredicateBuilder.ReplaceExpressionVisitor(exp.Parameters[1],Expression.Constant(index,typeof(int))).Visit(body!);
return Expression.Lambda(newBody,parameter);
var newBody = new PredicateBuilder.ReplaceExpressionVisitor(exp.Parameters[1], Expression.Constant(index, typeof(int))).Visit(body!);
return Expression.Lambda(newBody, parameter);
}

private static Expression<Func<T, bool>>? GenerateNestedExpression<T>(
Expand Down Expand Up @@ -382,7 +381,19 @@ internal static (Expression<Func<T, bool>> Expression, bool IsNested)
var bExp = expression as BinaryExpressionSyntax;

if (bExp!.Left is FieldExpressionSyntax && bExp.Right is ValueExpressionSyntax)
return ConvertBinaryExpressionSyntaxToQuery(bExp, mapper) ?? throw new GridifyFilteringException("Invalid expression");
{
try
{
return ConvertBinaryExpressionSyntaxToQuery(bExp, mapper) ?? throw new GridifyFilteringException("Invalid expression");
}
catch (GridifyMapperException e)
{
if (mapper.Configuration.IgnoreNotMappedFields)
return (_ => true, false);

throw;
}
}

(Expression<Func<T, bool>> exp, bool isNested) leftQuery;
(Expression<Func<T, bool>> exp, bool isNested) rightQuery;
Expand Down
71 changes: 68 additions & 3 deletions test/Gridify.Tests/GridifyExtensionsShould.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public void ApplyFiltering_DisableNullHandlingUsingMapper()
}

[Fact]
public void ApplyFiltering_DuplicateFiledName()
public void ApplyFiltering_DuplicatefieldName()
{
const string gq = "name=John|name=Sara";
var actual = _fakeRepository.AsQueryable()
Expand Down Expand Up @@ -457,6 +457,7 @@ public void ApplyFiltering_GreaterThanBetweenTwoStrings()
Assert.Equal(expected, actual);
Assert.True(actual.Any());
}


[Fact] // issue #27
public void ApplyFiltering_LessThanBetweenTwoStrings()
Expand Down Expand Up @@ -551,6 +552,43 @@ public void ApplyFiltering_NotEqual_ProcessingNullOrDefaultValueNonStringTypes()
Assert.Equal(expected, actual);
Assert.True(actual.Any());
}

[Fact] // issue #33
public void ApplyFiltering_WithSpaces()
{
var actual = _fakeRepository.AsQueryable().ApplyFiltering("name =ali reza").ToList();
var expected = _fakeRepository.Where(q => q.Name == "ali reza" ).ToList();

Assert.Equal(expected.Count, actual.Count);
Assert.Equal(expected, actual);
Assert.True(actual.Any());
}


[Fact] // issue #34
public void ApplyFiltering_UnmappedFields_ShouldThrowException()
{
var gm = new GridifyMapper<TestClass>()
.AddMap("Id", q => q.Id);

var exp = Assert.Throws<GridifyMapperException>(() => _fakeRepository.AsQueryable().ApplyFiltering("name=John,id>0", gm).ToList());
Assert.Equal("Mapping 'name' not found",exp.Message);
}

[Fact] // issue #34
public void ApplyFiltering_UnmappedFields_ShouldSkipWhenIgnored()
{
var gm = new GridifyMapper<TestClass>(configuration => configuration.IgnoreNotMappedFields = true)
.AddMap("Id", q => q.Id);

// name=*a filter should be ignored
var actual = _fakeRepository.AsQueryable().ApplyFiltering("name=*a, id>15", gm).ToList();
var expected = _fakeRepository.Where(q => q.Id > 15).ToList();

Assert.Equal(expected.Count, actual.Count);
Assert.Equal(expected, actual);
Assert.True(actual.Any());
}

#endregion

Expand Down Expand Up @@ -644,12 +682,38 @@ public void ApplyOrdering_EmptyOrderBy_ShouldSkip()
[Fact]
public void ApplyOrdering_NullGridifyQuery_ShouldSkip()
{
GridifyQuery gq = null;
var actual = _fakeRepository.AsQueryable()
.ApplyOrdering(null)
.ApplyOrdering(gq)
.ToList();
var expected = _fakeRepository.ToList();
Assert.Equal(expected, actual);
}

[Fact] // issue #34
public void ApplyOrdering_UnmappedFields_ShouldThrowException()
{
var gm = new GridifyMapper<TestClass>()
.AddMap("Id", q => q.Id);

var exp = Assert.Throws<GridifyMapperException>(() => _fakeRepository.AsQueryable().ApplyOrdering("name,id", gm).ToList());
Assert.Equal("Mapping 'name' not found",exp.Message);
}

[Fact] // issue #34
public void ApplyOrdering_UnmappedFields_ShouldSkipWhenIgnored()
{
var gm = new GridifyMapper<TestClass>(configuration => configuration.IgnoreNotMappedFields = true)
.AddMap("Id", q => q.Id);

// name orderBy should be ignored
var actual = _fakeRepository.AsQueryable().ApplyOrdering("name,id", gm).ToList();
var expected = _fakeRepository.OrderBy(q => q.Id ).ToList();

Assert.Equal(expected.Count, actual.Count);
Assert.Equal(expected, actual);
Assert.True(actual.Any());
}

#endregion

Expand Down Expand Up @@ -784,7 +848,8 @@ private static IEnumerable<TestClass> GetSampleData()
lst.Add(new TestClass(23, "LI | AM", null));
lst.Add(new TestClass(24, "(LI,AM)", null, tag: string.Empty));
lst.Add(new TestClass(25, "Case/i", null, tag: string.Empty));
lst.Add(new TestClass(26, "/iCase", null));
lst.Add(new TestClass(26, "/iCase", null));
lst.Add(new TestClass(27, "ali reza", null));

return lst;
}
Expand Down

0 comments on commit b03a112

Please sign in to comment.