Skip to content

Commit 0b29cd4

Browse files
author
Niall Langley
committed
Changed dynamic linq filter implementation to pass a datetime object instead of a string
1 parent 5fa109c commit 0b29cd4

File tree

4 files changed

+90
-11
lines changed

4 files changed

+90
-11
lines changed

DataPipelineTools.Tests/Common/FilterTests/GetDynamicLinqValueTests.cs

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using NUnit.Framework;
1+
using System;
2+
using NUnit.Framework;
23
using SqlCollaborative.Azure.DataPipelineTools.Common;
34

45
namespace DataPipelineTools.Tests.Common.FilterTests
@@ -18,7 +19,9 @@ public void Given_Value_And_OpertatorIsNotLike_Should_Return_Value()
1819
var filter = new Filter<TestPoco>
1920
{
2021
Operator = "eq",
21-
Value = "Someone"
22+
Value = "Someone",
23+
PropertyType = typeof(string),
24+
IsValid = true
2225
};
2326

2427
var result = filter.GetDynamicLinqValue();
@@ -33,7 +36,9 @@ public void Given_ValueWithoutWildcards_And_OpertatorIsLike_Should_Return_Value(
3336
var filter = new Filter<TestPoco>
3437
{
3538
Operator = "like",
36-
Value = "Someone"
39+
Value = "Someone",
40+
PropertyType = typeof(string),
41+
IsValid = true
3742
};
3843

3944
var result = filter.GetDynamicLinqValue();
@@ -48,13 +53,72 @@ public void Given_ValueWithWildcards_And_OpertatorIsLike_Should_Return_ValueWith
4853
var filter = new Filter<TestPoco>
4954
{
5055
Operator = "like",
51-
Value = "Some*ne"
56+
Value = "Some*ne",
57+
PropertyType = typeof(string),
58+
IsValid = true
5259
};
5360

5461
var result = filter.GetDynamicLinqValue();
5562

5663

5764
Assert.That(result, Is.EqualTo("Some.*ne"));
5865
}
66+
67+
[Test]
68+
public void Given_DateTimeValue_Should_Return_ValueOfTypeDateTime()
69+
{
70+
var date = "2021-01-01T00:00:00";
71+
var filter = new Filter<TestPoco>
72+
{
73+
Operator = "like",
74+
Value = date,
75+
PropertyType = typeof(DateTime),
76+
IsValid = true
77+
};
78+
79+
var result = filter.GetDynamicLinqValue();
80+
81+
82+
Assert.That(result, Is.EqualTo(DateTime.Parse(date)));
83+
}
84+
85+
86+
87+
[Test]
88+
public void Given_DateTimeOffsetValue_Should_Return_ValueOfTypeDateTimeOffset()
89+
{
90+
var date = "2021-01-01T00:00:00+06:00";
91+
var filter = new Filter<TestPoco>
92+
{
93+
Operator = "like",
94+
Value = date,
95+
PropertyType = typeof(DateTimeOffset),
96+
IsValid = true
97+
};
98+
99+
var result = filter.GetDynamicLinqValue();
100+
101+
102+
Assert.That(result, Is.EqualTo(DateTimeOffset.Parse(date)));
103+
}
104+
105+
106+
107+
[Test]
108+
public void Given_InvalidFilter_Should_Return_Null()
109+
{
110+
var filter = new Filter<TestPoco>
111+
{
112+
Operator = "like",
113+
Value = "2021-01-01T00:00:00",
114+
PropertyType = typeof(DateTime),
115+
IsValid = false
116+
};
117+
118+
var result = filter.GetDynamicLinqValue();
119+
120+
Assert.That(result, Is.Null);
121+
}
122+
59123
}
60124
}

DataPipelineTools/Common/Filter.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ namespace SqlCollaborative.Azure.DataPipelineTools.Common
1212
public class Filter<T>
1313
{
1414
public string PropertyName { get; set; }
15+
public Type PropertyType { get; set; }
1516
public string Operator { get; set; }
1617
public string Value { get; set; }
1718
public bool IsValid { get; set; } = false;
@@ -29,14 +30,27 @@ public string GetDynamicLinqString()
2930
}
3031
}
3132

32-
public string GetDynamicLinqValue()
33+
public object GetDynamicLinqValue()
3334
{
34-
return Operator == "like" ? Value.Replace("*", ".*") : Value;
35+
// Avoid throwing trying to do an invalid cast
36+
if (!IsValid)
37+
return null;
38+
39+
switch (PropertyType.Name)
40+
{
41+
case nameof(DateTime):
42+
return DateTime.Parse(Value);
43+
case nameof(DateTimeOffset):
44+
return DateTimeOffset.Parse(Value);
45+
default:
46+
return Operator == "like" ? Value.Replace("*", ".*") : Value;
47+
}
3548
}
3649

3750

3851
#region Newtonsoft.Json serialization methods
3952
public bool ShouldSerializeIsValid() => false;
53+
public bool ShouldSerializePropertyType() => false;
4054
#endregion Newtonsoft.Json serialization methods
4155
}
4256
}

DataPipelineTools/Common/FilterFactory.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ public static Filter<T> Create(string columnName, string filter, ILogger log)
5454
var val = operatorMatches.FirstOrDefault().Groups[2].Value;
5555

5656
// If the operator is like, but it's not a string type it's not a valid filter
57-
var propertyType = targetProperty.PropertyType.Name;
58-
if (propertyType != nameof(String) && op == "like")
57+
var propertyType = targetProperty.PropertyType;
58+
if (propertyType.Name != nameof(String) && op == "like")
5959
{
6060
var error = $"The filter column '{columnName}' is not a string, and cannot be use with the 'like' operator.";
6161
log?.LogWarning(error);
@@ -68,7 +68,7 @@ public static Filter<T> Create(string columnName, string filter, ILogger log)
6868

6969
// Now we check the filter string can be parsed into the correct type
7070
var isValueParseable = false;
71-
switch (propertyType)
71+
switch (propertyType.Name)
7272
{
7373
case nameof(String):
7474
isValueParseable = true;
@@ -98,13 +98,14 @@ public static Filter<T> Create(string columnName, string filter, ILogger log)
9898
break;
9999
}
100100

101-
var parseError = isValueParseable ? null : $"The filter '{val}' cannot be applied to the property '{columnName}' as it cannot be cast to a '{propertyType}'";
101+
var parseError = isValueParseable ? null : $"The filter '{val}' cannot be applied to the property '{columnName}' as it cannot be cast to a '{propertyType.Name}'";
102102
if (!isValueParseable)
103103
log?.LogWarning(parseError);
104104

105105
return new Filter<T>
106106
{
107107
PropertyName = columnName,
108+
PropertyType = propertyType,
108109
Operator = op,
109110
Value = val,
110111
IsValid = isValueParseable,

DataPipelineTools/DataLake/DataLakeService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ await CheckPathAsync(getItemsConfig.Directory, true) :
129129
foreach (var filter in getItemsConfig.Filters.Where(f => f.IsValid))
130130
{
131131
var dynamicLinqQuery = filter.GetDynamicLinqString();
132-
string dynamicLinqQueryValue = filter.GetDynamicLinqValue();
132+
var dynamicLinqQueryValue = filter.GetDynamicLinqValue();
133133
_logger.LogInformation($"Applying filter: paths.AsQueryable().Where(\"{dynamicLinqQuery}\", \"{filter.Value}\").ToList()");
134134
paths = paths.AsQueryable().Where(dynamicLinqQuery, dynamicLinqQueryValue).ToList();
135135
}

0 commit comments

Comments
 (0)