mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-16 01:25:41 -05:00
Or Filtering on Object Explorer Nodes (#1608)
support for a more robust filtering system in the Object Explorer xml, allowing for or-ing filter properties together for use in URN querying for objects Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
This commit is contained in:
@@ -36,7 +36,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
|
||||
/// <summary>
|
||||
/// The list of filters that should be applied on the smo object list
|
||||
/// </summary>
|
||||
public abstract IEnumerable<NodeFilter> Filters { get; }
|
||||
public abstract IEnumerable<INodeFilter> Filters { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The list of properties to be loaded with the object
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
|
||||
{
|
||||
/// <summary>
|
||||
/// Has information for filtering a SMO object by properties
|
||||
/// </summary>
|
||||
public interface INodeFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns true if the filter can be apply to the given type and Server type
|
||||
/// </summary>
|
||||
/// <param name="type">Type of the querier</param>
|
||||
/// <param name="validForFlag">Server Type</param>
|
||||
/// <returns></returns>
|
||||
bool CanApplyFilter(Type type, ValidForFlag validForFlag);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a string from the filter property and values to be used in the Urn to query the SQL objects
|
||||
/// Example of the output:[@ IsSystemObject = 0]
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
string ToPropertyFilterString(Type type, ValidForFlag validForFlag);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a fully paramaterized property filter string for the URN query for SQL objects.
|
||||
/// Example of the output:[@ IsSystemObject = 0]
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetPropertyFilter(IEnumerable<INodeFilter> filters, Type type, ValidForFlag validForFlag)
|
||||
{
|
||||
StringBuilder filter = new StringBuilder();
|
||||
foreach (var value in filters)
|
||||
{
|
||||
string andPrefix = filter.Length == 0 ? string.Empty : " and ";
|
||||
var filterString = value.ToPropertyFilterString(type, validForFlag);
|
||||
if (filterString != string.Empty) {
|
||||
filter.Append($"{andPrefix}{filterString}");
|
||||
}
|
||||
}
|
||||
|
||||
if (filter.Length != 0)
|
||||
{
|
||||
return "[" + filter.ToString() + "]";
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
|
||||
{
|
||||
/// <summary>
|
||||
/// Has information for filtering a SMO object by properties
|
||||
/// </summary>
|
||||
public class NodeOrFilter : INodeFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Filter values
|
||||
/// </summary>
|
||||
public List<NodePropertyFilter> FilterList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if any of the filters within the FilterList apply to the type and server type.
|
||||
/// </summary>
|
||||
/// <param name="type">Type of the querier</param>
|
||||
/// <param name="validForFlag">Server Type</param>
|
||||
public bool CanApplyFilter(Type type, ValidForFlag validForFlag) {
|
||||
return this.FilterList.Exists(f => f.CanApplyFilter(type, validForFlag));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a string representation of a node "or" filter, which is combined in the INodeFilter interface to construct the filter used in the URN to query the SQL objects.
|
||||
/// Example of the output: ((@TableTemporalType = 1) or (@LedgerTableType = 1))
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string ToPropertyFilterString(Type type, ValidForFlag validForFlag)
|
||||
{
|
||||
StringBuilder filter = new StringBuilder();
|
||||
foreach (var nodeFilter in FilterList)
|
||||
{
|
||||
string orPrefix = filter.Length == 0 ? string.Empty : " or ";
|
||||
|
||||
// For "or" filter, have to check each node as it's processed for whether it's valid.
|
||||
var filterString = nodeFilter.ToPropertyFilterString(type, validForFlag);
|
||||
if (filterString != string.Empty)
|
||||
{
|
||||
filter.Append($"{orPrefix}{filterString}");
|
||||
}
|
||||
}
|
||||
|
||||
if (filter.Length != 0)
|
||||
{
|
||||
return "(" + filter.ToString() + ")";
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,14 +5,14 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
|
||||
{
|
||||
/// <summary>
|
||||
/// Has information for filtering a SMO object by properties
|
||||
/// </summary>
|
||||
public class NodeFilter
|
||||
public class NodePropertyFilter : INodeFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Property name
|
||||
@@ -55,52 +55,40 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a string from the filter property and values to be used in the Urn to query the SQL objects
|
||||
/// Example of the output:[@ IsSystemObject = 0]
|
||||
/// Creates a string representation of a given node filter, which is combined in the INodeFilter interface to construct the filter used in the URN to query the SQL objects.
|
||||
/// Example of the output: (@ IsSystemObject = 0)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string ToPropertyFilterString()
|
||||
public string ToPropertyFilterString(Type type, ValidForFlag validForFlag)
|
||||
{
|
||||
string filter = "";
|
||||
List<object> values = Values;
|
||||
if (values != null)
|
||||
// check first if the filter can be applied; if not just return empty string
|
||||
if (!CanApplyFilter(type, validForFlag))
|
||||
{
|
||||
for (int i = 0; i < values.Count; i++)
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
StringBuilder filter = new StringBuilder();
|
||||
foreach (var value in Values)
|
||||
{
|
||||
object propertyValue = value;
|
||||
if (Type == typeof(string))
|
||||
{
|
||||
var value = values[i];
|
||||
object propertyValue = value;
|
||||
if (Type == typeof(string))
|
||||
{
|
||||
propertyValue = $"'{propertyValue}'";
|
||||
}
|
||||
if (Type == typeof(Enum))
|
||||
{
|
||||
propertyValue = (int)Convert.ChangeType(value, Type);
|
||||
|
||||
}
|
||||
string orPrefix = i == 0 ? string.Empty : "or";
|
||||
filter = $"{filter} {orPrefix} @{Property} = {propertyValue}";
|
||||
propertyValue = $"'{propertyValue}'";
|
||||
}
|
||||
else if (Type == typeof(Enum))
|
||||
{
|
||||
propertyValue = (int)Convert.ChangeType(value, Type);
|
||||
}
|
||||
|
||||
string orPrefix = filter.Length == 0 ? string.Empty : " or ";
|
||||
filter.Append($"{orPrefix}@{Property} = {propertyValue}");
|
||||
}
|
||||
filter = $"({filter})";
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
public static string ConcatProperties(IEnumerable<NodeFilter> filters)
|
||||
{
|
||||
string filter = "";
|
||||
var list = filters.ToList();
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
if (filter.Length != 0)
|
||||
{
|
||||
var value = list[i];
|
||||
|
||||
string andPrefix = i == 0 ? string.Empty : "and";
|
||||
filter = $"{filter} {andPrefix} {value.ToPropertyFilterString()}";
|
||||
return "(" + filter.ToString() + ")";
|
||||
}
|
||||
filter = $"[{filter}]";
|
||||
|
||||
return filter;
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user