Adding like filter and removing contains to OE filtering (#2105)

* Adding startswith and like filter

* Adding ends with

* Adding tests

* Remove null and not null

* Fixing string

* Update test/Microsoft.SqlTools.ServiceLayer.UnitTests/ObjectExplorer/NodeFilterTests.cs

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Update test/Microsoft.SqlTools.ServiceLayer.UnitTests/ObjectExplorer/NodeFilterTests.cs

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Adding back contains, starts with and ends with

* Properly escaping chars for like based filters

* Adding some comments regarding escape characters

* Using generated regex

* removing additional class

* Adding extra auth type that was causing the tests to error out

* Fixing regex

* Adding integration tests

* Fixing unit tests

* Making fluent assertions

---------

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
This commit is contained in:
Aasim Khan
2023-06-28 16:17:20 -07:00
committed by GitHub
parent 2a30a648f7
commit 6b251bd24a
6 changed files with 535 additions and 46 deletions

View File

@@ -157,6 +157,10 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts
NotBetween = 7,
Contains = 8,
NotContains = 9,
StartsWith = 10,
NotStartsWith = 11,
EndsWith = 12,
NotEndsWith = 13
}
/// <summary>

View File

@@ -8,13 +8,16 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.SqlTools.ServiceLayer.Management;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
{
/// <summary>
/// Has information for filtering a SMO object by properties
/// </summary>
public class NodePropertyFilter : INodeFilter
public partial class NodePropertyFilter : INodeFilter
{
/// <summary>
/// Property name
@@ -182,7 +185,25 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
object propertyValue = value;
if (Type == typeof(string))
{
propertyValue = $"'{propertyValue}'";
//Replacing quotes with double quotes
var escapedString = CUtils.EscapeStringSQuote(propertyValue.ToString());
if (this.FilterType == FilterType.STARTSWITH || this.FilterType == FilterType.ENDSWITH)
{
escapedString = EscapeLikeURNRegex().Replace(escapedString, "[$0]");
if (this.FilterType == FilterType.STARTSWITH)
{
propertyValue = $"'{escapedString}%'";
}
else if (this.FilterType == FilterType.ENDSWITH)
{
propertyValue = $"'%{escapedString}'";
}
}
else
{
propertyValue = $"'{escapedString}'";
}
}
else if (Type == typeof(Enum))
{
@@ -211,15 +232,19 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
case FilterType.DATETIME:
filterText = $"@{Property} = datetime({propertyValue})";
break;
case FilterType.CONTAINS:
filterText = $"contains(@{Property}, {propertyValue})";
break;
case FilterType.FALSE:
filterText = $"@{Property} = false()";
break;
case FilterType.ISNULL:
filterText = $"isnull(@{Property})";
break;
case FilterType.CONTAINS:
filterText = $"contains(@{Property}, {propertyValue})";
break;
case FilterType.STARTSWITH:
case FilterType.ENDSWITH:
filterText = $"like(@{Property}, {propertyValue})";
break;
}
}
@@ -261,13 +286,17 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
return false;
}
}
// For filters that use the LIKE operator, we need to escape the following characters: %, _, [, ^
// we do this by wrapping them in square brackets eg: [%], [_], [[], [^]
[GeneratedRegexAttribute(@"%|_|\[|\^")]
public static partial Regex EscapeLikeURNRegex();
}
public enum FilterType
{
EQUALS,
DATETIME,
CONTAINS,
FALSE,
ISNULL,
NOTEQUALS,
@@ -276,6 +305,9 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
LESSTHANOREQUAL,
GREATERTHANOREQUAL,
BETWEEN,
NOTBETWEEN
NOTBETWEEN,
CONTAINS,
STARTSWITH,
ENDSWITH
}
}

View File

@@ -129,13 +129,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
case NodeFilterOperator.GreaterThanOrEquals:
filterType = FilterType.GREATERTHANOREQUAL;
break;
case NodeFilterOperator.Contains:
filterType = FilterType.CONTAINS;
break;
case NodeFilterOperator.NotContains:
filterType = FilterType.CONTAINS;
isNotFilter = true;
break;
case NodeFilterOperator.Between:
filterType = FilterType.BETWEEN;
break;
@@ -143,9 +136,29 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
filterType = FilterType.NOTBETWEEN;
isNotFilter = true;
break;
case NodeFilterOperator.Contains:
filterType = FilterType.CONTAINS;
break;
case NodeFilterOperator.NotContains:
filterType = FilterType.CONTAINS;
isNotFilter = true;
break;
case NodeFilterOperator.StartsWith:
filterType = FilterType.STARTSWITH;
break;
case NodeFilterOperator.NotStartsWith:
filterType = FilterType.STARTSWITH;
isNotFilter = true;
break;
case NodeFilterOperator.EndsWith:
filterType = FilterType.ENDSWITH;
break;
case NodeFilterOperator.NotEndsWith:
filterType = FilterType.ENDSWITH;
isNotFilter = true;
break;
}
if (filter.Operator == NodeFilterOperator.Between || filter.Operator == NodeFilterOperator.NotBetween)
{
if (filterProperty.Type == NodeFilterPropertyDataType.Number)