Skip to content

Commit

Permalink
Handle empty search tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
ejsmith committed Oct 22, 2024
1 parent fd1859c commit 7fae77c
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,13 @@ public static string ToDynamicLinqString(this TermNode node, ISqlQueryVisitorCon
}

context.SearchTokenizer.Invoke(searchTerm);
if (searchTerm.Tokens == null)
searchTerm.Tokens = [ searchTerm.Term ];
else
searchTerm.Tokens = searchTerm.Tokens.Select(t => !String.IsNullOrWhiteSpace(t) ? t : "@__NOMATCH__").ToList();
}

fieldTerms.ForEach((kvp, x) =>
fieldTerms.Where(f => f.Value.Tokens is { Count: > 0 }).ForEach((kvp, x) =>
{
if (x.IsFirst && node.IsNegated.HasValue && node.IsNegated.Value)
builder.Append("!");
Expand Down
37 changes: 35 additions & 2 deletions tests/Foundatio.Parsers.SqlQueries.Tests/SqlQueryParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ public async Task CanSearchWithTokenizer()
{
var sp = GetServiceProvider();
await using var db = await GetSampleContextWithDataAsync(sp);
var phoneNumberUtil = PhoneNumberUtil.GetInstance();
var parser = sp.GetRequiredService<SqlQueryParser>();
parser.Configuration.SetDefaultFields(["NationalPhoneNumber"]);
parser.Configuration.SetSearchTokenizer(s =>
Expand All @@ -96,7 +95,7 @@ public async Task CanSearchWithTokenizer()
if (s.FieldInfo.FullName != "NationalPhoneNumber")
return;

s.Tokens = [phoneNumberUtil.Parse(s.Term, "US").NationalNumber.ToString()];
s.Tokens = [TryGetNationalNumber(s.Term)];
s.Operator = SqlSearchOperator.StartsWith;
});

Expand Down Expand Up @@ -127,6 +126,27 @@ public async Task CanSearchWithTokenizer()
Assert.Single(results);
}

[Fact]
public async Task CanHandleEmptyTokens()
{
var sp = GetServiceProvider();
await using var db = await GetSampleContextWithDataAsync(sp);
var parser = sp.GetRequiredService<SqlQueryParser>();
parser.Configuration.SetDefaultFields(["NationalPhoneNumber"]);
parser.Configuration.SetSearchTokenizer(s =>
{
s.Tokens = ["", " "];
});

var context = parser.GetContext(db.Employees.EntityType);

string sql = await parser.ToDynamicLinqAsync("test", context);
_logger.LogInformation(sql);
string sqlActual = db.Employees.Where(sql).ToQueryString();
var results = await db.Employees.Where(sql).ToListAsync();
Assert.Empty(results);
}

[Fact]
public async Task CanUseDateFilter()
{
Expand Down Expand Up @@ -313,6 +333,19 @@ public async Task CanGenerateSql()
Assert.Equal("John Doe", employee.FullName);
}

public static string? TryGetNationalNumber(string phoneNumber, string regionCode = "US")

Check warning on line 336 in tests/Foundatio.Parsers.SqlQueries.Tests/SqlQueryParserTests.cs

View workflow job for this annotation

GitHub Actions / build / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

Check warning on line 336 in tests/Foundatio.Parsers.SqlQueries.Tests/SqlQueryParserTests.cs

View workflow job for this annotation

GitHub Actions / build / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
{
var phoneNumberUtil = PhoneNumberUtil.GetInstance();
try
{
return phoneNumberUtil.Parse(phoneNumber, regionCode).NationalNumber.ToString();
}
catch (NumberParseException)
{
return null;
}
}

public IServiceProvider GetServiceProvider()
{
var services = new ServiceCollection();
Expand Down

0 comments on commit 7fae77c

Please sign in to comment.