mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-16 09:35:36 -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
var smoProperties = this.SmoProperties.Where(p => ServerVersionHelper.IsValidFor(serverValidFor, p.ValidFor)).Select(x => x.Name);
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
{
|
||||
filters.Add(new NodeFilter
|
||||
filters.Add(new NodePropertyFilter
|
||||
{
|
||||
Property = "Name",
|
||||
Type = typeof(string),
|
||||
@@ -118,7 +118,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string propertyFilter = GetProperyFilter(filters, querier.GetType(), serverValidFor);
|
||||
string propertyFilter = INodeFilter.GetPropertyFilter(filters, querier.GetType(), serverValidFor);
|
||||
try
|
||||
{
|
||||
var smoObjectList = querier.Query(context, propertyFilter, refresh, smoProperties).ToList();
|
||||
@@ -162,22 +162,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
return filterTheNode;
|
||||
}
|
||||
|
||||
private string GetProperyFilter(IEnumerable<NodeFilter> filters, Type querierType, ValidForFlag validForFlag)
|
||||
{
|
||||
string filter = string.Empty;
|
||||
if (filters != null)
|
||||
{
|
||||
var filtersToApply = filters.Where(f => f.CanApplyFilter(querierType, validForFlag)).ToList();
|
||||
filter = string.Empty;
|
||||
if (filtersToApply.Any())
|
||||
{
|
||||
filter = NodeFilter.ConcatProperties(filtersToApply);
|
||||
}
|
||||
}
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
private bool IsCompatibleQuerier(SmoQuerier querier)
|
||||
{
|
||||
if (ChildQuerierTypes == null)
|
||||
@@ -257,11 +241,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<NodeFilter> Filters
|
||||
public override IEnumerable<INodeFilter> Filters
|
||||
{
|
||||
get
|
||||
{
|
||||
return Enumerable.Empty<NodeFilter>();
|
||||
return Enumerable.Empty<INodeFilter>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -73,13 +73,13 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
var name = TreeNode.GetAttribute("Name");
|
||||
WriteLine(string.Format(" internal sealed partial class {0} : SmoTreeNode", name));
|
||||
WriteLine(" {");
|
||||
WriteLine(string.Format(" public {0}() : base()", name));
|
||||
WriteLine(" {");
|
||||
WriteLine(" NodeValue = string.Empty;");
|
||||
WriteLine(string.Format(" this.NodeType = \"{0}\";", name.Replace("TreeNode", string.Empty)));
|
||||
WriteLine(string.Format(" this.NodeTypeId = NodeTypes.{0};", name.Replace("TreeNode", string.Empty)));
|
||||
WriteLine(" OnInitialize();");
|
||||
WriteLine(" }");
|
||||
WriteLine(string.Format(" public {0}() : base()", name));
|
||||
WriteLine(" {");
|
||||
WriteLine(" NodeValue = string.Empty;");
|
||||
WriteLine(string.Format(" this.NodeType = \"{0}\";", name.Replace("TreeNode", string.Empty)));
|
||||
WriteLine(string.Format(" this.NodeTypeId = NodeTypes.{0};", name.Replace("TreeNode", string.Empty)));
|
||||
WriteLine(" OnInitialize();");
|
||||
WriteLine(" }");
|
||||
WriteLine(" }");
|
||||
WriteLine("");
|
||||
}
|
||||
@@ -116,86 +116,101 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
WriteLine(string.Format(" public override IEnumerable<string> ApplicableParents() {{ return new[] {{ \"{0}\" }}; }}", type));
|
||||
|
||||
List<XmlElement> children = GetChildren(xmlFile, type);
|
||||
List<XmlElement> filters = GetNodeFilters(xmlFile, type);
|
||||
List<XmlElement> smoProperties = GetNodeSmoProperties(xmlFile, type);
|
||||
|
||||
if (filters.Count > 0)
|
||||
// Load and parse Filters node
|
||||
// A <Filters> node is comprised of <Or> and <Filter> nodes
|
||||
// - A <Filter> node defines the properties to construct a NodePropertyFilter object
|
||||
// - An <Or> node defines a list of <Filter> nodes that are or'ed in the resulting URN Query
|
||||
// <Filters> can have an arbitrary number of top-level <Or> and <Filter> nodes.
|
||||
// All filters defined at the top-level are and'ed in the resulting URN Query.
|
||||
// This is generated into the IEnumerable<INodeFilter> Filters object for a particular SMO object.
|
||||
// Currently there is not support for nested <Or> nodes
|
||||
XmlNode filtersNode = GetFiltersNode(xmlFile, type);
|
||||
if (filtersNode != null)
|
||||
{
|
||||
// Get the children nodes for the Filters
|
||||
XmlNodeList childNodes = filtersNode.ChildNodes;
|
||||
if (childNodes.Count > 0)
|
||||
{
|
||||
// Write initial declarator for the filters object
|
||||
WriteLine("");
|
||||
WriteLine(" public override IEnumerable<NodeFilter> Filters");
|
||||
WriteLine(" public override IEnumerable<INodeFilter> Filters");
|
||||
WriteLine(" {");
|
||||
WriteLine(" get");
|
||||
WriteLine(" {");
|
||||
WriteLine(" get");
|
||||
WriteLine(" {");
|
||||
WriteLine(" var filters = new List<INodeFilter>();");
|
||||
|
||||
WriteLine(" var filters = new List<NodeFilter>();");
|
||||
foreach (var filter in filters)
|
||||
// Parse each of the <Or> nodes in <Filters>
|
||||
foreach (var orNode in filtersNode.SelectNodes("Or"))
|
||||
{
|
||||
var propertyName = filter.GetAttribute("Property");
|
||||
var propertyType = filter.GetAttribute("Type");
|
||||
var propertyValue = filter.GetAttribute("Value");
|
||||
var validFor = filter.GetAttribute("ValidFor");
|
||||
var typeToReverse = filter.GetAttribute("TypeToReverse");
|
||||
XmlElement or = orNode as XmlElement;
|
||||
if (or == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
List<XmlElement> filterValues = GetNodeFilterValues(xmlFile, type, propertyName);
|
||||
|
||||
|
||||
WriteLine(" filters.Add(new NodeFilter");
|
||||
// Write initial declarator for the <Or> object, which is just a list of NodePropertyFilters
|
||||
WriteLine(" filters.Add(new NodeOrFilter");
|
||||
WriteLine(" {");
|
||||
WriteLine(string.Format(" Property = \"{0}\",", propertyName));
|
||||
WriteLine(string.Format(" Type = typeof({0}),", propertyType));
|
||||
if (!string.IsNullOrWhiteSpace(typeToReverse))
|
||||
{
|
||||
WriteLine(string.Format(" TypeToReverse = typeof({0}Querier),", typeToReverse));
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(validFor))
|
||||
{
|
||||
WriteLine(string.Format(" ValidFor = {0},", GetValidForFlags(validFor)));
|
||||
}
|
||||
if (propertyValue != null && (filterValues == null || filterValues.Count == 0))
|
||||
{
|
||||
WriteLine(string.Format(" Values = new List<object> {{ {0} }},", propertyValue));
|
||||
}
|
||||
if (filterValues != null && filterValues.Count > 0)
|
||||
{
|
||||
string filterValueType = "object";
|
||||
if (propertyType == "Enum")
|
||||
{
|
||||
WriteLine(" FilterList = new List<NodePropertyFilter> {");
|
||||
|
||||
}
|
||||
WriteLine(string.Format(" Values = new List<object>"));
|
||||
WriteLine(string.Format(" {{"));
|
||||
for(int i = 0; i < filterValues.Count; i++)
|
||||
foreach(var orFilterNode in or.GetElementsByTagName("Filter"))
|
||||
{
|
||||
XmlElement orFilter = orFilterNode as XmlElement;
|
||||
if (orFilter == null)
|
||||
{
|
||||
string separator = "";
|
||||
if (i != filterValues.Count - 1)
|
||||
{
|
||||
separator = ",";
|
||||
}
|
||||
var filterValue = filterValues[i];
|
||||
WriteLine(string.Format(" {{ {0} }}{1}", filterValue.InnerText, separator ));
|
||||
|
||||
continue;
|
||||
}
|
||||
WriteLine(string.Format(" }}"));
|
||||
|
||||
// Declaration of Filter node
|
||||
WriteLine(" new NodePropertyFilter");
|
||||
|
||||
// Parse the elements in the <Filter> node into a string, and write
|
||||
ParseAndWriteFilterNode(xmlFile, type, orFilter, true /*orFilter*/);
|
||||
|
||||
// Close out filter object definition
|
||||
WriteLine(" },");
|
||||
}
|
||||
|
||||
// Close out declaration of the NodeOrFilter
|
||||
WriteLine(" }");
|
||||
WriteLine(" });");
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Parse each of the top-level <Filter> nodes in <Filters>
|
||||
foreach (var filterNode in filtersNode.SelectNodes("Filter"))
|
||||
{
|
||||
XmlElement filter = filterNode as XmlElement;
|
||||
if (filter == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Start declaration of Filter node
|
||||
WriteLine(" filters.Add(new NodePropertyFilter");
|
||||
|
||||
// Parse the elements in the <Filter> node into a string, and write
|
||||
ParseAndWriteFilterNode(xmlFile, type, filter);
|
||||
|
||||
// Close out filter object definition
|
||||
WriteLine(" });");
|
||||
}
|
||||
|
||||
// Close out declaration of the Filters object
|
||||
WriteLine(" return filters;");
|
||||
WriteLine(" }");
|
||||
WriteLine(" }");
|
||||
WriteLine(" }");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (smoProperties.Count > 0)
|
||||
{
|
||||
WriteLine("");
|
||||
WriteLine(" public override IEnumerable<NodeSmoProperty> SmoProperties");
|
||||
WriteLine(" {");
|
||||
WriteLine(" get");
|
||||
WriteLine(" {");
|
||||
WriteLine(" get");
|
||||
WriteLine(" {");
|
||||
|
||||
WriteLine(" var properties = new List<NodeSmoProperty>();");
|
||||
foreach (var smoPropertiy in smoProperties)
|
||||
@@ -203,9 +218,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
var propertyName = smoPropertiy.GetAttribute("Name");
|
||||
var validFor = smoPropertiy.GetAttribute("ValidFor");
|
||||
|
||||
|
||||
|
||||
|
||||
WriteLine(" properties.Add(new NodeSmoProperty");
|
||||
WriteLine(" {");
|
||||
WriteLine(string.Format(" Name = \"{0}\",", propertyName));
|
||||
@@ -215,17 +227,13 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
WriteLine(string.Format(" ValidFor = {0}", GetValidForFlags(validFor)));
|
||||
}
|
||||
WriteLine(" });");
|
||||
|
||||
|
||||
}
|
||||
|
||||
WriteLine(" return properties;");
|
||||
WriteLine(" }");
|
||||
WriteLine(" }");
|
||||
WriteLine(" }");
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (children.Count > 0)
|
||||
{
|
||||
WriteLine("");
|
||||
@@ -276,11 +284,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
WriteLine("");
|
||||
WriteLine(" internal override Type[] ChildQuerierTypes");
|
||||
WriteLine(" {");
|
||||
WriteLine(" get");
|
||||
WriteLine(" {");
|
||||
WriteLine(" get");
|
||||
WriteLine(" {");
|
||||
if (!string.IsNullOrWhiteSpace(ChildQuerierTypes))
|
||||
{
|
||||
Write(" return new [] {");
|
||||
Write(" return new [] {");
|
||||
foreach (var typeToRe in allTypes)
|
||||
{
|
||||
Write(string.Format(" typeof({0}Querier),", typeToRe));
|
||||
@@ -289,9 +297,9 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
}
|
||||
else
|
||||
{
|
||||
Write(" return new Type[0];");
|
||||
WriteLine(" return new Type[0];");
|
||||
}
|
||||
WriteLine(" }");
|
||||
WriteLine(" }");
|
||||
WriteLine(" }");
|
||||
|
||||
WriteLine("");
|
||||
@@ -464,14 +472,14 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
return retElements;
|
||||
}
|
||||
|
||||
public static List<XmlElement> GetNodeFilters(string xmlFile, string parentName)
|
||||
public static List<XmlElement> GetNodeOrFilters(string xmlFile, string parentName)
|
||||
{
|
||||
XmlElement nodeElement = GetNodeElement(xmlFile, parentName);
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
|
||||
List<XmlElement> retElements = new List<XmlElement>();
|
||||
XmlNodeList nodeList = doc.SelectNodes(string.Format("/ServerExplorerTree/Node[@Name='{0}']/Filters/Filter", parentName));
|
||||
XmlNodeList nodeList = doc.SelectNodes(string.Format("/ServerExplorerTree/Node[@Name='{0}']/Filters/Or/Filter", parentName));
|
||||
foreach (var item in nodeList)
|
||||
{
|
||||
XmlElement itemAsElement = item as XmlElement;
|
||||
@@ -483,6 +491,14 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
return retElements;
|
||||
}
|
||||
|
||||
public static XmlNode GetFiltersNode(string xmlFile, string parentName)
|
||||
{
|
||||
XmlElement nodeElement = GetNodeElement(xmlFile, parentName);
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
|
||||
return doc.SelectSingleNode(string.Format("/ServerExplorerTree/Node[@Name='{0}']/Filters", parentName));
|
||||
}
|
||||
|
||||
public static List<XmlElement> GetNodeSmoProperties(string xmlFile, string parentName)
|
||||
{
|
||||
@@ -503,14 +519,20 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
return retElements;
|
||||
}
|
||||
|
||||
public static List<XmlElement> GetNodeFilterValues(string xmlFile, string parentName, string filterProperty)
|
||||
public static List<XmlElement> GetNodeFilterValues(string xmlFile, string parentName, string filterProperty, bool orFilter = false)
|
||||
{
|
||||
XmlElement nodeElement = GetNodeElement(xmlFile, parentName);
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
|
||||
List<XmlElement> retElements = new List<XmlElement>();
|
||||
XmlNodeList nodeList = doc.SelectNodes(string.Format("/ServerExplorerTree/Node[@Name='{0}']/Filters/Filter[@Property='{1}']/Value", parentName, filterProperty));
|
||||
|
||||
var xpath = string.Format(
|
||||
"/ServerExplorerTree/Node[@Name='{0}']/Filters/{1}Filter[@Property='{2}']/Value",
|
||||
parentName,
|
||||
orFilter ? "Or/" : string.Empty,
|
||||
filterProperty);
|
||||
XmlNodeList nodeList = doc.SelectNodes(xpath);
|
||||
foreach (var item in nodeList)
|
||||
{
|
||||
XmlElement itemAsElement = item as XmlElement;
|
||||
@@ -521,4 +543,56 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
}
|
||||
return retElements;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function to parse out and write the contents of a <Filter> node.
|
||||
/// </summary>
|
||||
/// <param name="xmlFile">Base xml doc</param>
|
||||
/// <param name="parentName">name of the parent object in the xml</param>
|
||||
/// <param name="filter">The filter to be parsed</param>
|
||||
/// <param name="orFilter">Whether this filter is a sub-node of an <Or> node</param>
|
||||
public void ParseAndWriteFilterNode(string xmlFile, string parentName, XmlElement filter, bool orFilter = false)
|
||||
{
|
||||
// <Or> Filters start at a larger base indentation than <Filter> nodes directly under <Filters>
|
||||
var indent = orFilter ? " " : " ";
|
||||
|
||||
var propertyName = filter.GetAttribute("Property");
|
||||
var propertyType = filter.GetAttribute("Type");
|
||||
var propertyValue = filter.GetAttribute("Value");
|
||||
var validFor = filter.GetAttribute("ValidFor");
|
||||
var typeToReverse = filter.GetAttribute("TypeToReverse");
|
||||
|
||||
List<XmlElement> filterValues = GetNodeFilterValues(xmlFile, parentName, propertyName, orFilter);
|
||||
|
||||
// Write out the "meat" of the object definition
|
||||
WriteLine(indent + "{");
|
||||
WriteLine(indent + " Property = \"{0}\",", propertyName);
|
||||
WriteLine(indent + " Type = typeof({0}),", propertyType);
|
||||
if (!string.IsNullOrWhiteSpace(typeToReverse))
|
||||
{
|
||||
WriteLine(indent + " TypeToReverse = typeof({0}Querier),", typeToReverse);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(validFor))
|
||||
{
|
||||
WriteLine(indent + " ValidFor = {0},", GetValidForFlags(validFor));
|
||||
}
|
||||
if (propertyValue != null && (filterValues == null || filterValues.Count == 0))
|
||||
{
|
||||
WriteLine(indent + " Values = new List<object> {{ {0} }},", propertyValue);
|
||||
}
|
||||
if (filterValues != null && filterValues.Count > 0)
|
||||
{
|
||||
WriteLine(indent + " Values = new List<object>");
|
||||
WriteLine(indent + " {");
|
||||
|
||||
for(int i = 0; i < filterValues.Count; i++)
|
||||
{
|
||||
string separator = (i != filterValues.Count - 1) ? "," : "";
|
||||
var filterValue = filterValues[i];
|
||||
WriteLine(indent + " {{ {0} }}{1}", filterValue.InnerText, separator);
|
||||
}
|
||||
|
||||
WriteLine(indent + " }");
|
||||
}
|
||||
}
|
||||
#>
|
||||
Reference in New Issue
Block a user