Skip to content

Commit

Permalink
fix merge
Browse files Browse the repository at this point in the history
  • Loading branch information
Mehdi Oueldi committed Feb 7, 2023
2 parents 820a637 + e74ba4e commit a0d5a8e
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace Azure.EntityServices.Queries
{
public static class DynamicQueryExtensions
{
/// <summary>
/// Build query filters by iterate on each given collection item
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="U">Generic collection</typeparam>
/// <param name="query"></param>
/// <param name="list"></param>
/// <param name="action"></param>
/// <returns></returns>
public static IFilterOperator<T> WithEach<T, U>(this IFilterOperator<T> query, IEnumerable<U> list, Func<U, IFilterOperator<T>, IFilterOperator<T>> action)
{
var dynamicQuery = query;
foreach (var item in list)
{
dynamicQuery = action(item, dynamicQuery);
}
return dynamicQuery;
}

/// <summary>
/// Build a filter to check if current field value was present in given list
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="P"></typeparam>
/// <param name="query"></param>
/// <param name="values"></param>
/// <returns></returns>
public static IFilterOperator<T> In<T, P>(this IQueryFilter<T, P> query, params P[] values)
{
IQuery<T> nextQuery = (IQuery<T>)query;
foreach (var item in values.SkipLast(1))
{
nextQuery = (IQuery<T>)(nextQuery as IQueryFilter<T>).Equal(item).Or(query.PropertyName);
}
(nextQuery as IQueryFilter<T>).Equal(values.Last());
return nextQuery as IFilterOperator<T>;
}

/// <summary>
/// Build a filter to check if current field value was not present in given list
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="P"></typeparam>
/// <param name="query"></param>
/// <param name="values"></param>
/// <returns></returns>
public static IFilterOperator<T> NotIn<T, P>(this IQueryFilter<T, P> query, params P[] values)
{
IQuery<T> nextQuery = (IQuery<T>)query;
foreach (var item in values.SkipLast(1))
{
nextQuery = (IQuery<T>)(nextQuery as IQueryFilter<T>).NotEqual(item).And(query.PropertyName);
}
(nextQuery as IQueryFilter<T>).NotEqual(values.Last());
return nextQuery as IFilterOperator<T>;
}
}
}
5 changes: 4 additions & 1 deletion src/Azure.EntityServices.Queries/IQueryFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ public interface IQueryFilter<T> : IQueryFilter<T, object>

public interface IQueryFilter<T, P>
{
string PropertyName { get; }

IFilterOperator<T> AddFilterCondition(string comparison, P value);

IFilterOperator<T> AddFilterCondition(string comparison, object value, Type type);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,5 +121,98 @@ public void Should_Build_TableStorage_Query_Expression_With_Grouped_Filter_Insid
.Should()
.Be("PartitionKey eq 'Tenant-1' and TenantId eq '10' and not (Created gt datetime'2012-04-21T18:25:43.0000000Z' or Created lt datetime'2012-04-21T18:25:43.0000000Z') or not (Enabled eq true)");
}

[TestMethod]
public void Should_BuildGroup_Dynamic_Query_Expression()
{
var builder = new MockedExpressionBuilder<PersonEntity>();

var dynamicQuery = builder.Query
.Where(p => p.TenantId).Equal("50");
for (var i = 0; i < 10; i++)
{
dynamicQuery = dynamicQuery.Or(p => p.FirstName).Equal($"do {i}");
}

var queryStr = builder.Build();

queryStr.Trim()
.Should()
.Be("TenantId Equal '50' Or FirstName Equal 'do 0' Or FirstName Equal 'do 1' Or FirstName Equal 'do 2' Or FirstName Equal 'do 3' Or FirstName Equal 'do 4' Or FirstName Equal 'do 5' Or FirstName Equal 'do 6' Or FirstName Equal 'do 7' Or FirstName Equal 'do 8' Or FirstName Equal 'do 9'");
}

[TestMethod]
public void Should_BuildGroup_Dynamic_Query_Expression_WithEach_Extension_Helper()
{
var builder = new MockedExpressionBuilder<PersonEntity>();

var dynamicQuery = builder.Query
.Where(p => p.TenantId).Equal("50");

dynamicQuery.WithEach(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, (item, q) =>
q.Or(p => p.FirstName).Equal($"do {item}"));

var queryStr = builder.Build();

queryStr.Trim()
.Should()
.Be("TenantId Equal '50' Or FirstName Equal 'do 0' Or FirstName Equal 'do 1' Or FirstName Equal 'do 2' Or FirstName Equal 'do 3' Or FirstName Equal 'do 4' Or FirstName Equal 'do 5' Or FirstName Equal 'do 6' Or FirstName Equal 'do 7' Or FirstName Equal 'do 8' Or FirstName Equal 'do 9'");
}

[TestMethod]
public void Should_BuildGroup_Dynamic_Query_Expression_In_Extension_Helper()
{
var builder = new MockedExpressionBuilder<PersonEntity>();

var dynamicQuery = builder.Query
.Where(p => p.TenantId).Equal("50")
.And(p => p.LastName)
.In("Doe");

var queryStr = builder.Build();

queryStr.Trim()
.Should()
.Be("TenantId Equal '50' And LastName Equal 'Doe'");

dynamicQuery = builder.Query
.Where(p => p.TenantId).Equal("50")
.And("LastName")
.In("Doe", "Kent");

queryStr = builder.Build();

queryStr.Trim()
.Should()
.Be("TenantId Equal '50' And LastName Equal 'Doe' Or LastName Equal 'Kent'");
}

[TestMethod]
public void Should_BuildGroup_Dynamic_Query_Expression_NotIn_Extension_Helper()
{
var builder = new MockedExpressionBuilder<PersonEntity>();

var dynamicQuery = builder.Query
.Where(p => p.TenantId).Equal("50")
.And(p => p.LastName)
.NotIn("Doe");

var queryStr = builder.Build();

queryStr.Trim()
.Should()
.Be("TenantId Equal '50' And LastName NotEqual 'Doe'");

dynamicQuery = builder.Query
.Where(p => p.TenantId).Equal("50")
.And("LastName")
.NotIn("Doe", "Kent");

queryStr = builder.Build();

queryStr.Trim()
.Should()
.Be("TenantId Equal '50' And LastName NotEqual 'Doe' And LastName NotEqual 'Kent'");
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Azure.EntityServices.Queries;
using Common.Samples.Models;
using Azure.EntityServices.Tables;
using Azure.EntityServices.Tables.Core;
using Common.Samples.Models;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
Expand Down Expand Up @@ -155,29 +155,49 @@ public void Should_Build_Table_Filter_Expression_With_Invariant_Floating_Point_V
.Be("PartitionKey eq 'tenantId' and Latitude eq 48.77309806265856 and Distance eq '148.45648566856' and BankAmount eq '1248.7731'");
}

[TestMethod]
public void Should_Use_Multi_PartitionKey_filter()
{
var builder = new TableStorageQueryBuilder<PersonEntity>(new TagFilterExpression<PersonEntity>("Created"));

(builder.Query as TagFilterExpression<PersonEntity>)
.WherePartitionKey()
.Equal("partition1")
.OrPartitionKey()
.Equal("partition2")
.OrPartitionKey()
.Equal("Partition3");

var queryStr = builder.Build();

queryStr.Trim()
.Should()
.Be("PartitionKey eq 'partition1' or PartitionKey eq 'partition2' or PartitionKey eq 'Partition3'");
}

[TestMethod]
public void Should_Use_WithTag_Extension_To_Get_All_Tag_Values_Without_Filter_Operator()
{
var builder = new TableStorageQueryBuilder<PersonEntity>(new TagFilterExpression<PersonEntity>());

(builder.Query as TagFilterExpression<PersonEntity>)
.WithTag("Created")
.And(p => p.TenantId).Equal("10");
.And(p => p.TenantId).Equal("10");
var queryStr = builder.Build();

queryStr.Trim()
.Should()
.Be("RowKey gt '~Created-' and RowKey lt '~Created-~' and TenantId eq '10'");
}
[TestMethod]
}

[TestMethod]
public void Should_Use_IncludeTags_To_Get_All_Entities_Included_All_Tags()
{
var builder = new TableStorageQueryBuilder<PersonEntity>(new TagFilterExpression<PersonEntity>());

(builder.Query as TagFilterExpression<PersonEntity>)
.IncludeTags()
.WherePartitionKey().Equal("tenant1");
.WherePartitionKey().Equal("tenant1");

var queryStr = builder.Build();

Expand Down

0 comments on commit a0d5a8e

Please sign in to comment.