Skip to content

Commit

Permalink
fix contains logic + add UT (#12)
Browse files Browse the repository at this point in the history
Co-authored-by: Bar Nuri <[email protected]>
  • Loading branch information
vitusik and barnuri authored Dec 19, 2024
1 parent 254987a commit f17f533
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 10 deletions.
10 changes: 10 additions & 0 deletions LinqToKql.Test/Translator/WhereTranslatorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ public Task Translate_ShouldHandleWhereWitContainsAsync()
[_tableName, "where Name in ('name1', 'name2', 'name3')"]
);

[Fact]
public async Task Translate_ShouldHandleWhereWitContainsWithListAsync()
{
var test = new List<string> { "name1", "name2", "name3" };
await AssertQueryAsync(
_q.Where(x => test.Contains(x.Name)),
[_tableName, "where Name in ('name1', 'name2', 'name3')"]
);
}

[Fact]
public Task Translate_ShouldHandleWhereWithAndAsync()
=> AssertQueryAsync(
Expand Down
25 changes: 15 additions & 10 deletions LinqToKql/Translator/Builders/LinqToKQLTranslatorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,20 +163,26 @@ protected string BuildFilter(Expression expression)
private string BuildFilterCustomMethodCall(MethodCallExpression methodCall)
{
var methodName = methodCall.Method.Name;
var leftSide = methodCall.Arguments.Count > 1 ? methodCall.Arguments[1] : methodCall.Object!;
if (methodName == "KqlLike") { return HandleKqlLike(methodCall); }
var leftSideKql = BuildFilter(methodCall.Arguments.Count > 1 ? methodCall.Arguments[1] : methodCall.Object!);
if (methodName == "Like") { return HandleLike(methodCall, leftSideKql); }

var rightSideKql = BuildFilter(methodCall.Arguments[0]);
if (leftSideKql.StartsWith('(') && leftSideKql.EndsWith(')'))
{
(rightSideKql, leftSideKql) = (leftSideKql, rightSideKql);
}
return methodName switch
{
nameof(string.Contains) when methodCall.Method.DeclaringType == typeof(string) => $"{BuildFilter(leftSide)} has_cs {BuildFilter(methodCall.Arguments[0])}",
nameof(Enumerable.Contains) => $"{BuildFilter(leftSide)} in ({BuildFilter(methodCall.Arguments[0]).TrimStart('(').TrimEnd(')')})",
nameof(string.StartsWith) => $"{BuildFilter(leftSide)} startswith_cs {BuildFilter(methodCall.Arguments[0])}",
nameof(string.EndsWith) => $"{BuildFilter(leftSide)} endswith_cs {BuildFilter(methodCall.Arguments[0])}",
nameof(string.Equals) => $"{BuildFilter(leftSide)} == {BuildFilter(methodCall.Arguments[0])}",
"KqlLike" => HandleKqlLike(methodCall),
"Like" => HandleLike(methodCall, leftSide),
nameof(string.Contains) when methodCall.Method.DeclaringType == typeof(string) => $"{leftSideKql} has_cs {rightSideKql}",
nameof(Enumerable.Contains) => $"{leftSideKql} in ({rightSideKql.TrimStart('(').TrimEnd(')')})",
nameof(string.StartsWith) => $"{leftSideKql} startswith_cs {rightSideKql}",
nameof(string.EndsWith) => $"{leftSideKql} endswith_cs {rightSideKql}",
nameof(string.Equals) => $"{leftSideKql} == {rightSideKql}",
_ => throw new NotSupportedException($"{nameof(BuildFilterCustomMethodCall)} - Method {methodCall.Method.Name} is not supported."),
};

string HandleLike(MethodCallExpression methodCall, Expression leftSide)
string HandleLike(MethodCallExpression methodCall, string leftSideKql)
{
var likeValueConst = methodCall.Arguments
.Where(x => x.NodeType == ExpressionType.Constant)
Expand All @@ -187,7 +193,6 @@ string HandleLike(MethodCallExpression methodCall, Expression leftSide)
if (likeValueConst == null) { throw new NotSupportedException($"{nameof(HandleLike)} - likeValueConst is null."); }
var likeValue = likeValueConst.Value!.ToString()!;
var filter = likeValue.Trim('%').GetKQLValue();
var leftSideKql = BuildFilter(leftSide);
if (likeValue.StartsWith("%") && likeValue.EndsWith("%"))
{
return $"{leftSideKql} has_cs {filter}";
Expand Down

0 comments on commit f17f533

Please sign in to comment.