Implemented the oe filtering (#328)

* Implemented the oe filtering
This commit is contained in:
Leila Lali
2017-04-26 14:48:17 -07:00
committed by GitHub
parent 1a16101381
commit 51916c2221
17 changed files with 3108 additions and 1030 deletions

View File

@@ -29,6 +29,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
/// <returns></returns> /// <returns></returns>
public abstract IEnumerable<TreeNode> Expand(TreeNode parent); public abstract IEnumerable<TreeNode> Expand(TreeNode parent);
/// <summary>
/// The list of filters that should be applied on the smo object list
/// </summary>
public abstract IEnumerable<NodeFilter> Filters { get; }
public abstract bool CanCreateChild(TreeNode parent, object context); public abstract bool CanCreateChild(TreeNode parent, object context);
public abstract TreeNode CreateChild(TreeNode parent, object context); public abstract TreeNode CreateChild(TreeNode parent, object context);

View File

@@ -0,0 +1,84 @@
//
// 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;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
{
/// <summary>
/// Has information for filtering a SMO object by properties
/// </summary>
public class NodeFilter
{
/// <summary>
/// Property name
/// </summary>
public string Property { get; set; }
/// <summary>
/// Filter values
/// </summary>
public List<object> Values { get; set; }
/// <summary>
/// Type of the filter values
/// </summary>
public Type Type { get; set; }
/// <summary>
/// Indicates which platforms a filter is valid for
/// </summary>
public ValidForFlag ValidFor { get; set; }
/// <summary>
/// The type of the Querier the filter can be applied to
/// </summary>
public Type TypeToReverse { get; set; }
/// <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>
public bool CanApplyFilter(Type type, ValidForFlag validForFlag)
{
bool canApplyFilter = false;
canApplyFilter = TypeToReverse == null || TypeToReverse == type;
canApplyFilter = canApplyFilter && (ValidFor == 0 || ValidFor.HasFlag(validForFlag));
return canApplyFilter;
}
/// <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>
public string ToPropertyFilterString()
{
string filter = "";
List<object> values = Values;
if (values != null)
{
for (int i = 0; i < values.Count; i++)
{
var value = values[i];
object proeprtyValue = value;
if (Type == typeof(Enum))
{
proeprtyValue = (int)Convert.ChangeType(value, Type);
}
string orPrefix = i == 0 ? "" : "or";
filter = $"{filter} {orPrefix} @{Property} = {proeprtyValue}";
}
}
filter = $"[{filter}]";
return filter;
}
}
}

View File

@@ -24,6 +24,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
View, View,
Table, Table,
HistoryTable, HistoryTable,
Folder,
Databases, Databases,
ExternalResources, ExternalResources,
ServerLevelSecurity, ServerLevelSecurity,

View File

@@ -0,0 +1,91 @@
//
// 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 Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
{
/// <summary>
/// Server Types
/// </summary>
public enum SqlServerType
{
Unknown,
Sql2005,
Sql2008,
Sql2012,
Sql2014,
Sql2016,
Azure,
AzureV12
}
/// <summary>
/// Includes helper functions for server version and type
/// </summary>
public class ServerVersionHelper
{
/// <summary>
/// Converts a server type to ValidForFlag
/// </summary>
public static ValidForFlag GetValidForFlag(SqlServerType serverType)
{
ValidForFlag validforFlag = ValidForFlag.All;
if (Enum.TryParse<ValidForFlag>(serverType.ToString(), out validforFlag))
{
return validforFlag;
}
return ValidForFlag.All;
}
/// <summary>
/// Creates a server type from the server version
/// </summary>
public static SqlServerType CalculateServerType(ServerInfo serverInfo)
{
SqlServerType serverType = SqlServerType.Unknown;
string serverVersion = serverInfo.ServerVersion;
if (serverInfo.IsCloud)
{
if (serverVersion.StartsWith("11", StringComparison.Ordinal))
{
serverType = SqlServerType.Azure;
}
else
{
serverType = SqlServerType.AzureV12;
}
}
else if (!string.IsNullOrWhiteSpace(serverVersion))
{
if (serverVersion.StartsWith("9", StringComparison.Ordinal) ||
serverVersion.StartsWith("09", StringComparison.Ordinal))
{
serverType = SqlServerType.Sql2005;
}
else if (serverVersion.StartsWith("10", StringComparison.Ordinal))
{
serverType = SqlServerType.Sql2008; // and 2008R2
}
else if (serverVersion.StartsWith("11", StringComparison.Ordinal))
{
serverType = SqlServerType.Sql2012;
}
else if (serverVersion.StartsWith("12", StringComparison.Ordinal))
{
serverType = SqlServerType.Sql2014;
}
else if (serverVersion.StartsWith("13", StringComparison.Ordinal))
{
serverType = SqlServerType.Sql2016;
}
}
return serverType;
}
}
}

View File

@@ -31,6 +31,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
private Lazy<SmoQueryContext> context; private Lazy<SmoQueryContext> context;
private ConnectionService connectionService; private ConnectionService connectionService;
private SmoServerCreator serverCreator; private SmoServerCreator serverCreator;
private SqlServerType sqlServerType;
public ServerNode(ConnectionCompleteParams connInfo, IMultiServiceProvider serviceProvider) public ServerNode(ConnectionCompleteParams connInfo, IMultiServiceProvider serviceProvider)
: base() : base()
@@ -42,6 +43,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
this.connectionSummary = connInfo.ConnectionSummary; this.connectionSummary = connInfo.ConnectionSummary;
this.serverInfo = connInfo.ServerInfo; this.serverInfo = connInfo.ServerInfo;
this.connectionUri = connInfo.OwnerUri; this.connectionUri = connInfo.OwnerUri;
this.sqlServerType = ServerVersionHelper.CalculateServerType(this.serverInfo);
this.connectionService = serviceProvider.GetService<ConnectionService>(); this.connectionService = serviceProvider.GetService<ConnectionService>();
@@ -123,6 +125,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
return label; return label;
} }
private SmoQueryContext CreateContext(IMultiServiceProvider serviceProvider) private SmoQueryContext CreateContext(IMultiServiceProvider serviceProvider)
{ {
string exceptionMessage; string exceptionMessage;
@@ -160,7 +164,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
Server server = ServerCreator.Create(connection); Server server = ServerCreator.Create(connection);
return new SmoQueryContext(server, serviceProvider) return new SmoQueryContext(server, serviceProvider)
{ {
Parent = server Parent = server,
SqlServerType = this.sqlServerType
}; };
} }
catch (ConnectionFailureException cfe) catch (ConnectionFailureException cfe)

View File

@@ -1,133 +1,169 @@
// //
// Copyright (c) Microsoft. All rights reserved. // Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
// //
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.ServiceLayer.Utility;
using Microsoft.SqlTools.Utility; using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
public class SmoChildFactoryBase : ChildFactory public class SmoChildFactoryBase : ChildFactory
{ {
public override IEnumerable<string> ApplicableParents() public override IEnumerable<string> ApplicableParents()
{ {
return null; return null;
} }
public override IEnumerable<TreeNode> Expand(TreeNode parent) public override IEnumerable<TreeNode> Expand(TreeNode parent)
{ {
//parent.BeginChildrenInit(); //parent.BeginChildrenInit();
try try
{ {
List<TreeNode> allChildren = new List<TreeNode>(); List<TreeNode> allChildren = new List<TreeNode>();
OnExpandPopulateFolders(allChildren, parent); OnExpandPopulateFolders(allChildren, parent);
RemoveFoldersFromInvalidSqlServerVersions(allChildren, parent); RemoveFoldersFromInvalidSqlServerVersions(allChildren, parent);
OnExpandPopulateNonFolders(allChildren, parent); OnExpandPopulateNonFolders(allChildren, parent);
OnBeginAsyncOperations(parent); OnBeginAsyncOperations(parent);
return allChildren; return allChildren;
} }
finally finally
{ {
//parent.EndChildrenInit(); //parent.EndChildrenInit();
} }
} }
/// <summary> /// <summary>
/// Populates any folders for a given parent node /// Populates any folders for a given parent node
/// </summary> /// </summary>
/// <param name="allChildren">List to which nodes should be added</param> /// <param name="allChildren">List to which nodes should be added</param>
/// <param name="parent">Parent the nodes are being added to</param> /// <param name="parent">Parent the nodes are being added to</param>
protected virtual void OnExpandPopulateFolders(IList<TreeNode> allChildren, TreeNode parent) protected virtual void OnExpandPopulateFolders(IList<TreeNode> allChildren, TreeNode parent)
{ {
} }
/// <summary> /// <summary>
/// Populates any non-folder nodes such as specific items in the tree. /// Populates any non-folder nodes such as specific items in the tree.
/// </summary> /// </summary>
/// <param name="allChildren">List to which nodes should be added</param> /// <param name="allChildren">List to which nodes should be added</param>
/// <param name="parent">Parent the nodes are being added to</param> /// <param name="parent">Parent the nodes are being added to</param>
protected virtual void OnExpandPopulateNonFolders(IList<TreeNode> allChildren, TreeNode parent) protected virtual void OnExpandPopulateNonFolders(IList<TreeNode> allChildren, TreeNode parent)
{ {
if (ChildQuerierTypes == null) if (ChildQuerierTypes == null)
{ {
// This node does not support non-folder children // This node does not support non-folder children
return; return;
} }
SmoQueryContext context = parent.GetContextAs<SmoQueryContext>(); SmoQueryContext context = parent.GetContextAs<SmoQueryContext>();
Validate.IsNotNull(nameof(context), context); Validate.IsNotNull(nameof(context), context);
IEnumerable<SmoQuerier> queriers = context.ServiceProvider.GetServices<SmoQuerier>(q => IsCompatibleQuerier(q)); IEnumerable<SmoQuerier> queriers = context.ServiceProvider.GetServices<SmoQuerier>(q => IsCompatibleQuerier(q));
foreach (var querier in queriers) var filters = this.Filters;
{ var validForFlag = ServerVersionHelper.GetValidForFlag(context.SqlServerType);
foreach(var smoObject in querier.Query(context))
{ foreach (var querier in queriers)
{
string propertyFilter = GetProperyFilter(filters, querier.GetType(), validForFlag);
foreach (var smoObject in querier.Query(context, propertyFilter))
{
if (smoObject == null) if (smoObject == null)
{ {
Console.WriteLine("smoObject should not be null"); Console.WriteLine("smoObject should not be null");
} }
TreeNode childNode = CreateChild(parent, smoObject); TreeNode childNode = CreateChild(parent, smoObject);
if (childNode != null) if (childNode != null && !ShouldFilterNode(childNode, validForFlag))
{ {
allChildren.Add(childNode); allChildren.Add(childNode);
} }
} }
} }
} }
private bool IsCompatibleQuerier(SmoQuerier querier) private bool ShouldFilterNode(TreeNode childNode, ValidForFlag validForFlag)
{ {
if (ChildQuerierTypes == null) bool filterTheNode = false;
{ SmoTreeNode smoTreeNode = childNode as SmoTreeNode;
return false; if (smoTreeNode != null && smoTreeNode.ValidFor != 0)
} {
if (!(smoTreeNode.ValidFor.HasFlag(validForFlag)))
Type actualType = querier.GetType(); {
foreach (Type childType in ChildQuerierTypes) filterTheNode = true;
{ }
// We will accept any querier that is compatible with the listed querier type }
if (childType.IsAssignableFrom(actualType))
{ return filterTheNode;
return true; }
}
} private string GetProperyFilter(IEnumerable<NodeFilter> filters, Type querierType, ValidForFlag validForFlag)
return false; {
string filter = "";
} if (filters != null)
{
/// <summary> var filterToApply = filters.FirstOrDefault(f => f.CanApplyFilter(querierType, validForFlag));
/// Filters out invalid folders if they cannot be displayed for the current server version filter = "";
/// </summary>
/// <param name="allChildren">List to which nodes should be added</param> if (filterToApply != null)
/// <param name="parent">Parent the nodes are being added to</param> {
protected virtual void RemoveFoldersFromInvalidSqlServerVersions(IList<TreeNode> allChildren, TreeNode parent) filter = filterToApply.ToPropertyFilterString();
{ }
} }
// TODO Assess whether async operations node is required return filter;
protected virtual void OnBeginAsyncOperations(TreeNode parent) }
{
} private bool IsCompatibleQuerier(SmoQuerier querier)
{
public override bool CanCreateChild(TreeNode parent, object context) if (ChildQuerierTypes == null)
{ {
return false; return false;
} }
public override TreeNode CreateChild(TreeNode parent, object context) Type actualType = querier.GetType();
{ foreach (Type childType in ChildQuerierTypes)
throw new NotImplementedException(); {
} // We will accept any querier that is compatible with the listed querier type
if (childType.IsAssignableFrom(actualType))
protected virtual void InitializeChild(TreeNode child, object context) {
{ return true;
NamedSmoObject smoObj = context as NamedSmoObject; }
}
return false;
}
/// <summary>
/// Filters out invalid folders if they cannot be displayed for the current server version
/// </summary>
/// <param name="allChildren">List to which nodes should be added</param>
/// <param name="parent">Parent the nodes are being added to</param>
protected virtual void RemoveFoldersFromInvalidSqlServerVersions(IList<TreeNode> allChildren, TreeNode parent)
{
}
// TODO Assess whether async operations node is required
protected virtual void OnBeginAsyncOperations(TreeNode parent)
{
}
public override bool CanCreateChild(TreeNode parent, object context)
{
return false;
}
public override TreeNode CreateChild(TreeNode parent, object context)
{
throw new NotImplementedException();
}
protected virtual void InitializeChild(TreeNode child, object context)
{
NamedSmoObject smoObj = context as NamedSmoObject;
if (smoObj == null) if (smoObj == null)
{ {
Debug.WriteLine("context is not a NamedSmoObject. type: " + context.GetType()); Debug.WriteLine("context is not a NamedSmoObject. type: " + context.GetType());
@@ -136,26 +172,34 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
SmoTreeNode childAsMeItem = (SmoTreeNode)child; SmoTreeNode childAsMeItem = (SmoTreeNode)child;
childAsMeItem.CacheInfoFromModel(smoObj); childAsMeItem.CacheInfoFromModel(smoObj);
} }
} }
internal virtual Type[] ChildQuerierTypes { internal virtual Type[] ChildQuerierTypes {
get get
{ {
return null; return null;
} }
} }
/// <summary> public override IEnumerable<NodeFilter> Filters
/// Returns true if any final validation of the object to be added passes, and false {
/// if validation fails. This provides a chance to filter specific items out of a list get
/// </summary> {
/// <param name="parent"></param> return Enumerable.Empty<NodeFilter>();
/// <param name="contextObject"></param> }
/// <returns>boolean</returns> }
public virtual bool PassesFinalFilters(TreeNode parent, object context)
{ /// <summary>
return true; /// Returns true if any final validation of the object to be added passes, and false
} /// if validation fails. This provides a chance to filter specific items out of a list
} /// </summary>
} /// <param name="parent"></param>
/// <param name="contextObject"></param>
/// <returns>boolean</returns>
public virtual bool PassesFinalFilters(TreeNode parent, object context)
{
return true;
}
}
}

View File

@@ -1,42 +1,91 @@
// //
// Copyright (c) Microsoft. All rights reserved. // Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
// //
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.SqlServer.Management.Smo; using System.Data;
using Microsoft.Data.Tools.DataSets;
using Microsoft.SqlServer.Management.Sdk.Sfc;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.Extensibility; using Microsoft.SqlTools.Extensibility;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
/// <summary> /// <summary>
/// A <see cref="SmoQuerier"/> handles SMO queries for one or more SMO object types. /// A <see cref="SmoQuerier"/> handles SMO queries for one or more SMO object types.
/// The <see cref="SupportedObjectTypes"/> property defines which types can be queried. /// The <see cref="SupportedObjectTypes"/> property defines which types can be queried.
/// ///
/// To query multiple /// To query multiple
/// </summary> /// </summary>
public abstract class SmoQuerier : IComposableService public abstract class SmoQuerier : IComposableService
{ {
public abstract Type[] SupportedObjectTypes { get; } public abstract Type[] SupportedObjectTypes { get; }
/// <summary> /// <summary>
/// Queries SMO for a collection of objects using the <see cref="SmoQueryContext"/> /// Queries SMO for a collection of objects using the <see cref="SmoQueryContext"/>
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
/// <returns></returns> /// <returns></returns>
public abstract IEnumerable<SqlSmoObject> Query(SmoQueryContext context); public abstract IEnumerable<SqlSmoObject> Query(SmoQueryContext context, string filter);
internal IMultiServiceProvider ServiceProvider internal IMultiServiceProvider ServiceProvider
{ {
get; get;
private set; private set;
} }
public void SetServiceProvider(IMultiServiceProvider provider) public void SetServiceProvider(IMultiServiceProvider provider)
{ {
ServiceProvider = provider; ServiceProvider = provider;
} }
}
/// <summary>
} /// Convert the data to data reader is possible
/// </summary>
protected IDataReader GetDataReader(object data)
{
IDataReader reader = null;
if (data is IDataReader)
{
reader = data as IDataReader;
}
else if(data is Data.Tools.DataSets.DataTable)
{
reader = ((Data.Tools.DataSets.DataTable)data).CreateDataReader();
}
else if (data is DataSet)
{
reader = ((DataSet)data).Tables[0].CreateDataReader();
}
return reader;
}
/// <summary>
/// Gets the urn from the enumResult
/// </summary>
protected HashSet<string> GetUrns(EnumResult enumResult)
{
HashSet<string> urns = null;
if (enumResult != null && enumResult.Data != null)
{
urns = new HashSet<string>();
IDataReader reader = GetDataReader(enumResult.Data);
if (reader != null)
{
while (reader.Read())
{
urns.Add(reader.GetString(0));
}
}
}
return urns;
}
}
}

View File

@@ -28,6 +28,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
} }
/// <summary>
/// The server type
/// </summary>
public SqlServerType SqlServerType { get; set; }
/// <summary> /// <summary>
/// The server SMO will query against /// The server SMO will query against
/// </summary> /// </summary>
@@ -94,7 +99,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
SmoQueryContext context = new SmoQueryContext(this.Server, this.ServiceProvider) SmoQueryContext context = new SmoQueryContext(this.Server, this.ServiceProvider)
{ {
Database = this.Database, Database = this.Database,
Parent = parent Parent = parent,
SqlServerType = this.SqlServerType
}; };
return context; return context;
} }

View File

@@ -15,6 +15,8 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Composition; using System.Composition;
using System.Linq; using System.Linq;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Sdk.Sfc;
using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Smo.Broker; using Microsoft.SqlServer.Management.Smo.Broker;
@@ -50,7 +52,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
WriteLine(""); WriteLine("");
// Query impl // Query impl
WriteLine("public override IEnumerable<SqlSmoObject> Query(SmoQueryContext context)"); WriteLine("public override IEnumerable<SqlSmoObject> Query(SmoQueryContext context, string filter)");
WriteLine("{"); WriteLine("{");
PushIndent(indent); PushIndent(indent);
@@ -65,17 +67,43 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
string navigationPath = GetNavigationPath(nodeElement, xmlFile, nodeName, parentType); string navigationPath = GetNavigationPath(nodeElement, xmlFile, nodeName, parentType);
WriteLine(string.Format("var retValue = {0}.{1};", parentVar, navigationPath)); WriteLine(string.Format("var retValue = {0}.{1};", parentVar, navigationPath));
WriteLine("if(retValue != null)"); WriteLine("bool hasFilter = !string.IsNullOrEmpty(filter);");
WriteLine("HashSet<string> urns = null;");
WriteLine("if (hasFilter)");
WriteLine("{");
PushIndent(indent);
WriteLine(string.Format("string urn = $\"{{{0}.Urn.ToString()}}/{1}\" + filter;", parentVar, nodeType));
WriteLine("Enumerator en = new Enumerator();");
WriteLine("Request request = new Request(new Urn(urn));");
WriteLine("ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject);");
WriteLine("EnumResult result = en.Process(serverConnection, request);");
WriteLine("urns = GetUrns(result);");
PopIndent();
WriteLine("}");
WriteLine("if (retValue != null)");
WriteLine("{"); WriteLine("{");
PushIndent(indent); PushIndent(indent);
if (IsCollection(nodeElement)) if (IsCollection(nodeElement))
{ {
WriteLine("if (hasFilter && urns != null)");
WriteLine("{");
PushIndent(indent);
WriteLine(string.Format("return new SmoCollectionWrapper<{0}>(retValue).Where(c => urns.Contains(c.Urn));", nodeType));
PopIndent();
WriteLine("}");
WriteLine("else");
WriteLine("{");
PushIndent(indent);
WriteLine(string.Format("return new SmoCollectionWrapper<{0}>(retValue);", nodeType)); WriteLine(string.Format("return new SmoCollectionWrapper<{0}>(retValue);", nodeType));
PopIndent();
WriteLine("}");
} }
else else
{ {
WriteLine("return new SqlSmoObject[] { retValue };"); WriteLine("return new SqlSmoObject[] { retValue };");
} }
PopIndent(); PopIndent();
WriteLine("}"); WriteLine("}");
PopIndent(); PopIndent();

View File

@@ -20,7 +20,7 @@
<Child Name="ServerLevelEventSessions"/> <Child Name="ServerLevelEventSessions"/>
--> -->
</Node> </Node>
<Node Name="ServerLevelServerObjects" LocLabel="SR.SchemaHierarchy_ServerObjects" BaseClass="ModelBased" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|NotContainedUser"> <Node Name="ServerLevelServerObjects" LocLabel="SR.SchemaHierarchy_ServerObjects" BaseClass="ModelBased" NodeType="ServerLevelServerObject" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|NotContainedUser">
<Child Name="ServerLevelEndpoints"/> <Child Name="ServerLevelEndpoints"/>
<Child Name="ServerLevelLinkedServers"/> <Child Name="ServerLevelLinkedServers"/>
<Child Name="ServerLevelServerTriggers"/> <Child Name="ServerLevelServerTriggers"/>
@@ -30,26 +30,26 @@
--> -->
</Node> </Node>
<Node Name="SystemDatabases" LocLabel="SR.SchemaHierarchy_SystemDatabases" BaseClass="Databases" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV11|AzureV12|NotContainedUser|CanConnectToMaster"/> <Node Name="SystemDatabases" LocLabel="SR.SchemaHierarchy_SystemDatabases" BaseClass="Databases" NodeType="SystemDatabase" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV11|AzureV12|NotContainedUser|CanConnectToMaster"/>
<!-- TODO Support XEvents in .Net Core SMO <!-- TODO Support XEvents in .Net Core SMO
<Node Name="ServerLevelEventSessions" LocLabel="SR.SchemaHierarchy_EventSessions" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlEventSession" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/> <Node Name="ServerLevelEventSessions" LocLabel="SR.SchemaHierarchy_EventSessions" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlEventSession" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
<Node Name="ServerLevelEventNotifications" LocLabel="SR.SchemaHierarchy_ServerEventNotifications" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlServerEventNotification"/> <Node Name="ServerLevelEventNotifications" LocLabel="SR.SchemaHierarchy_ServerEventNotifications" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlServerEventNotification"/>
--> -->
<Node Name="ServerLevelLinkedServerLogins" LocLabel="SR.SchemaHierarchy_LinkedServerLogins" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlLinkedServerLogin" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/> <Node Name="ServerLevelLinkedServerLogins" LocLabel="SR.SchemaHierarchy_LinkedServerLogins" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="ServerLevelLinkedServerLogin" ChildQuerierTypes="SqlLinkedServerLogin" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
<Node Name="ServerLevelLogins" LocLabel="SR.SchemaHierarchy_Logins" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlLogin"/> <Node Name="ServerLevelLogins" LocLabel="SR.SchemaHierarchy_Logins" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="ServerLevelLogin" ChildQuerierTypes="SqlLogin"/>
<Node Name="ServerLevelServerRoles" LocLabel="SR.SchemaHierarchy_ServerRoles" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlServerRole" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/> <Node Name="ServerLevelServerRoles" LocLabel="SR.SchemaHierarchy_ServerRoles" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="ServerLevelServerRole" ChildQuerierTypes="SqlServerRole" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
<Node Name="ServerLevelCredentials" LocLabel="SR.SchemaHierarchy_Credentials" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlCredential" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/> <Node Name="ServerLevelCredentials" LocLabel="SR.SchemaHierarchy_Credentials" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="ServerLevelCredential" ChildQuerierTypes="SqlCredential" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
<Node Name="ServerLevelCryptographicProviders" LocLabel="SR.SchemaHierarchy_CryptographicProviders" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlCryptographicProvider" ValidFor="Sql2008|Sql2012|Sql2014|NotDebugInstance|Sql2016|SqlvNext"/> <Node Name="ServerLevelCryptographicProviders" LocLabel="SR.SchemaHierarchy_CryptographicProviders" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="ServerLevelCryptographicProvider" ChildQuerierTypes="SqlCryptographicProvider" ValidFor="Sql2008|Sql2012|Sql2014|NotDebugInstance|Sql2016|SqlvNext"/>
<Node Name="ServerLevelServerAudits" LocLabel="SR.SchemaHierarchy_ServerAudits" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlServerAudit" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/> <Node Name="ServerLevelServerAudits" LocLabel="SR.SchemaHierarchy_ServerAudits" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="ServerLevelServerAudit" ChildQuerierTypes="SqlServerAudit" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
<Node Name="ServerLevelServerAuditSpecifications" LocLabel="SR.SchemaHierarchy_ServerAuditSpecifications" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlServerAuditSpecification" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/> <Node Name="ServerLevelServerAuditSpecifications" LocLabel="SR.SchemaHierarchy_ServerAuditSpecifications" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="ServerLevelServerAuditSpecification" ChildQuerierTypes="SqlServerAuditSpecification" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
<Node Name="ServerLevelEndpoints" LocLabel="SR.SchemaHierarchy_Endpoints" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlEndpoint" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/> <Node Name="ServerLevelEndpoints" LocLabel="SR.SchemaHierarchy_Endpoints" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="ServerLevelEndpoint" ChildQuerierTypes="SqlEndpoint" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
<Node Name="ServerLevelLinkedServers" LocLabel="SR.SchemaHierarchy_LinkedServers" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlLinkedServer"/> <Node Name="ServerLevelLinkedServers" LocLabel="SR.SchemaHierarchy_LinkedServers" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="ServerLevelLinkedServer" ChildQuerierTypes="SqlLinkedServer"/>
<Node Name="ServerLevelServerTriggers" LocLabel="SR.SchemaHierarchy_ServerTriggers" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlServerDdlTrigger"/> <Node Name="ServerLevelServerTriggers" LocLabel="SR.SchemaHierarchy_ServerTriggers" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="ServerLevelServerTrigger" ChildQuerierTypes="SqlServerDdlTrigger"/>
<Node Name="ServerLevelErrorMessages" LocLabel="SR.SchemaHierarchy_ErrorMessages" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlErrorMessage"/> <Node Name="ServerLevelErrorMessages" LocLabel="SR.SchemaHierarchy_ErrorMessages" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="ServerLevelErrorMessage" ChildQuerierTypes="SqlErrorMessage"/>
<Node Name="Database" LocLabel="string.Empty" Image="Database" BaseClass="ModelBased" IsAsyncLoad="" Strategy="CreateModel"> <Node Name="Database" LocLabel="string.Empty" Image="Database" BaseClass="ModelBased" NodeType="Database" IsAsyncLoad="" Strategy="CreateModel">
<Child Name="Tables"/> <Child Name="Tables"/>
<Child Name="Views"/> <Child Name="Views"/>
<Child Name="Synonyms"/> <Child Name="Synonyms"/>
@@ -61,12 +61,13 @@
</Node> </Node>
<Node Name="Tables" LocLabel="SR.SchemaHierarchy_Tables" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlTable" TreeNode="TableTreeNode"> <Node Name="Tables" LocLabel="SR.SchemaHierarchy_Tables" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlTable" TreeNode="TableTreeNode">
<Filters> <Filters >
<Filter Property="IsFileTable" Value="0" Type="bool" /> <Filter Property="IsFileTable" Value="0" Type="bool" />
<Filter Property="IsSystemObject" Value="0" Type="bool" />
<Filter Property="IsExternal" Value="0" Type="bool" ValidFor="Sql2016|SqlvNext|AzureV12"/> <Filter Property="IsExternal" Value="0" Type="bool" ValidFor="Sql2016|SqlvNext|AzureV12"/>
<Filter Property="TemporalType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12"> <Filter Property="TemporalType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12">
<Value>TemporalTableType.None</Value> <Value>TableTemporalType.None</Value>
<Value>TemporalTableType.SystemVersioned</Value> <Value>TableTemporalType.SystemVersioned</Value>
</Filter> </Filter>
</Filters> </Filters>
<Child Name="SystemTables"/> <Child Name="SystemTables"/>
@@ -75,10 +76,13 @@
</Node> </Node>
<Node Name="Views" LocLabel="SR.SchemaHierarchy_Views" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlView" TreeNode="ViewTreeNode"> <Node Name="Views" LocLabel="SR.SchemaHierarchy_Views" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlView" TreeNode="ViewTreeNode">
<Filters>
<Filter Property="IsSystemObject" Value="0" Type="bool" />
</Filters>
<Child Name="SystemViews"/> <Child Name="SystemViews"/>
</Node> </Node>
<Node Name="Synonyms" LocLabel="SR.SchemaHierarchy_Synonyms" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSynonym"/> <Node Name="Synonyms" LocLabel="SR.SchemaHierarchy_Synonyms" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="Synonym" ChildQuerierTypes="SqlSynonym"/>
<Node Name="Programmability" LocLabel="SR.SchemaHierarchy_Programmability" BaseClass="ModelBased"> <Node Name="Programmability" LocLabel="SR.SchemaHierarchy_Programmability" BaseClass="ModelBased">
<Child Name="StoredProcedures"/> <Child Name="StoredProcedures"/>
<Child Name="Functions"/> <Child Name="Functions"/>
@@ -130,23 +134,27 @@
</Node> </Node>
<!-- Childs of Tables --> <!-- Childs of Tables -->
<Node Name="SystemTables" LocLabel="SR.SchemaHierarchy_SystemTables" BaseClass="ModelBased" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlTable" TreeNode="TableTreeNode"/> <Node Name="SystemTables" LocLabel="SR.SchemaHierarchy_SystemTables" BaseClass="ModelBased" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlTable" TreeNode="TableTreeNode">
<Filters >
<Filter Property="IsSystemObject" Value="1" Type="bool" />
</Filters>
</Node>
<Node Name="FileTables" LocLabel="SR.SchemaHierarchy_FileTables" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlTable" TreeNode="TableTreeNode" ValidFor="Sql2012|Sql2014|Sql2016|SqlvNext|NotDebug"> <Node Name="FileTables" LocLabel="SR.SchemaHierarchy_FileTables" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlTable" TreeNode="TableTreeNode" ValidFor="Sql2012|Sql2014|Sql2016|SqlvNext|NotDebug">
<Filters> <Filters >
<Filter Property="IsFileTable" Value="1" Type="boolean" /> <Filter Property="IsFileTable" Value="1" Type="bool" />
</Filters> </Filters>
</Node> </Node>
<Node Name="ExternalTables" LocLabel="SR.SchemaHierarchy_ExternalTables" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlTable" TreeNode="ExternalTableTreeNode" ValidFor="Sql2016|SqlvNext|AzureV12"> <Node Name="ExternalTables" LocLabel="SR.SchemaHierarchy_ExternalTables" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlTable" TreeNode="ExternalTableTreeNode" ValidFor="Sql2016|SqlvNext|AzureV12">
<Filters> <Filters >
<Filter Property="IsExternalTable" Value="1" Type="boolean" /> <Filter Property="IsExternal" Value="1" Type="bool" />
</Filters> </Filters>
</Node> </Node>
<Node Name="Table" LocLabel="string.Empty" BaseClass="ModelBased" IsAsyncLoad="" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlTable" TreeNode="HistoryTableTreeNode"> <Node Name="Table" LocLabel="string.Empty" BaseClass="ModelBased" IsAsyncLoad="" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlTable" TreeNode="HistoryTableTreeNode">
<!-- TODO Add special history table handling to only return related history table instead of all! Under Table, we directly show any related history tables.--> <!-- TODO Add special history table handling to only return related history table instead of all! Under Table, we directly show any related history tables.-->
<Filters> <Filters>
<Filter Property="TemporalType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12"> <Filter Property="TemporalType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12">
<Value>TemporalTableType.History</Value> <Value>TableTemporalType.HistoryTable</Value>
</Filter> </Filter>
</Filters> </Filters>
<Child Name="Columns"/> <Child Name="Columns"/>
@@ -158,20 +166,20 @@
</Node> </Node>
<!-- TODO This should use display item not ChildQuerierTypes --> <!-- TODO This should use display item not ChildQuerierTypes -->
<Node Name="HistoryTable" LocLabel="string.Empty" BaseClass="ModelBased" IsAsyncLoad="" Strategy="PopulateDetails" ChildQuerierTypes="SqlTable" ValidFor="Sql2016|SqlvNext|AzureV12"> <Node Name="HistoryTable" LocLabel="string.Empty" BaseClass="ModelBased" IsAsyncLoad="" Strategy="PopulateDetails" NodeType="Table" ChildQuerierTypes="SqlTable" ValidFor="Sql2016|SqlvNext|AzureV12">
<Child Name="Columns"/> <Child Name="Columns"/>
<Child Name="Indexes"/> <Child Name="Indexes"/>
<Child Name="Statistics"/> <Child Name="Statistics"/>
</Node> </Node>
<!-- TODO This should use display item not ChildQuerierTypes --> <!-- TODO This should use display item not ChildQuerierTypes -->
<Node Name="ExternalTable" LocLabel="string.Empty" BaseClass="ModelBased" IsAsyncLoad="" Strategy="PopulateDetails" ChildQuerierTypes="SqlTable" ValidFor="Sql2016|SqlvNext|AzureV12"> <Node Name="ExternalTable" LocLabel="string.Empty" BaseClass="ModelBased" IsAsyncLoad="" Strategy="PopulateDetails" NodeType="Table" ChildQuerierTypes="SqlTable" ValidFor="Sql2016|SqlvNext|AzureV12">
<Child Name="Columns"/> <Child Name="Columns"/>
<Child Name="Statistics"/> <Child Name="Statistics"/>
</Node> </Node>
<Node Name="Columns" LocLabel="SR.SchemaHierarchy_Columns" BaseClass="ModelBased" Strategy="PopulateParentDetails" ChildQuerierTypes="SqlColumn" DisableSort=""/> <Node Name="Columns" LocLabel="SR.SchemaHierarchy_Columns" BaseClass="ModelBased" Strategy="PopulateParentDetails" NodeType="Column" ChildQuerierTypes="SqlColumn" DisableSort=""/>
<Node Name="Keys" LocLabel="SR.SchemaHierarchy_Keys" BaseClass="ModelBased" Strategy="ElementsInRelationship" ChildQuerierTypes="SqlIndex;SqlForeignKeyConstraint" > <Node Name="Keys" LocLabel="SR.SchemaHierarchy_Keys" BaseClass="ModelBased" Strategy="ElementsInRelationship" NodeType="Key" ChildQuerierTypes="SqlIndex;SqlForeignKeyConstraint" >
<Filters> <Filters>
<Filter TypeToReverse="SqlIndex" Property="IndexKeyType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12"> <Filter TypeToReverse="SqlIndex" Property="IndexKeyType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12">
<Value>IndexKeyType.DriPrimaryKey</Value> <Value>IndexKeyType.DriPrimaryKey</Value>
@@ -179,20 +187,24 @@
</Filter> </Filter>
</Filters> </Filters>
</Node> </Node>
<Node Name="Constraints" LocLabel="SR.SchemaHierarchy_Constraints" BaseClass="ModelBased" Strategy="ElementsInRelationship" ChildQuerierTypes="SqlDefaultConstraint;SqlCheck"/> <Node Name="Constraints" LocLabel="SR.SchemaHierarchy_Constraints" BaseClass="ModelBased" NodeType="Constraint" Strategy="ElementsInRelationship" ChildQuerierTypes="SqlDefaultConstraint;SqlCheck"/>
<Node Name="Triggers" LocLabel="SR.SchemaHierarchy_Triggers" BaseClass="ModelBased" Strategy="ElementsInRelationship" ChildQuerierTypes="SqlDmlTrigger"/> <Node Name="Triggers" LocLabel="SR.SchemaHierarchy_Triggers" BaseClass="ModelBased" Strategy="ElementsInRelationship" NodeType="Trigger" ChildQuerierTypes="SqlDmlTrigger"/>
<Node Name="Indexes" LocLabel="SR.SchemaHierarchy_Indexes" BaseClass="ModelBased" Strategy="ElementsInRelationship" ChildQuerierTypes="SqlIndex;SqlFullTextIndex"> <Node Name="Indexes" LocLabel="SR.SchemaHierarchy_Indexes" BaseClass="ModelBased" Strategy="ElementsInRelationship" NodeType="Index" ChildQuerierTypes="SqlIndex;SqlFullTextIndex">
<Filters> <Filters>
<Filter TypeToReverse="SqlIndex" Property="IndexKeyType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12"> <Filter TypeToReverse="SqlIndex" Property="IndexKeyType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12">
<Value>IndexKeyType.None</Value> <Value>IndexKeyType.None</Value>
</Filter> </Filter>
</Filters> </Filters>
</Node> </Node>
<Node Name="Statistics" LocLabel="SR.SchemaHierarchy_Statistics" BaseClass="ModelBased" Strategy="ElementsInRelationship" ChildQuerierTypes="SqlStatistic"/> <Node Name="Statistics" LocLabel="SR.SchemaHierarchy_Statistics" BaseClass="ModelBased" Strategy="ElementsInRelationship" NodeType="Statistic" ChildQuerierTypes="SqlStatistic"/>
<Node Name="SystemViews" LocLabel="SR.SchemaHierarchy_SystemViews" BaseClass="ModelBased" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlView" TreeNode="ViewTreeNode"/> <Node Name="SystemViews" LocLabel="SR.SchemaHierarchy_SystemViews" BaseClass="ModelBased" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlView" TreeNode="ViewTreeNode">
<Filters>
<Filter Property="IsSystemObject" Value="1" Type="bool" />
</Filters>
</Node>
<Node Name="View" LocLabel="string.Empty" BaseClass="ModelBased" IsAsyncLoad="" Strategy="PopulateDetails"> <Node Name="View" LocLabel="string.Empty" BaseClass="ModelBased" IsAsyncLoad="" NodeType="View" Strategy="PopulateDetails">
<Child Name="Columns"/> <Child Name="Columns"/>
<Child Name="Triggers"/> <Child Name="Triggers"/>
<Child Name="Indexes"/> <Child Name="Indexes"/>
@@ -204,8 +216,8 @@
<Child Name="ScalarValuedFunctions"/> <Child Name="ScalarValuedFunctions"/>
<Child Name="AggregateFunctions"/> <Child Name="AggregateFunctions"/>
</Node> </Node>
<Node Name="DatabaseTriggers" LocLabel="SR.SchemaHierarchy_DatabaseTriggers" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlDatabaseDdlTrigger"/> <Node Name="DatabaseTriggers" LocLabel="SR.SchemaHierarchy_DatabaseTriggers" BaseClass="ModelBased" NodeType="DatabaseTrigger" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlDatabaseDdlTrigger"/>
<Node Name="Assemblies" LocLabel="SR.SchemaHierarchy_Assemblies" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlAssembly" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/> <Node Name="Assemblies" LocLabel="SR.SchemaHierarchy_Assemblies" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="Assembly" ChildQuerierTypes="SqlAssembly" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
<Node Name="Types" LocLabel="SR.SchemaHierarchy_Types" BaseClass="ModelBased" > <Node Name="Types" LocLabel="SR.SchemaHierarchy_Types" BaseClass="ModelBased" >
<Child Name="SystemDataTypes"/> <Child Name="SystemDataTypes"/>
<Child Name="UserDefinedDataTypes"/> <Child Name="UserDefinedDataTypes"/>
@@ -213,9 +225,9 @@
<Child Name="UserDefinedTypes"/> <Child Name="UserDefinedTypes"/>
<Child Name="XmlSchemaCollections"/> <Child Name="XmlSchemaCollections"/>
</Node> </Node>
<Node Name="Rules" LocLabel="SR.SchemaHierarchy_Rules" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlRule" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/> <Node Name="Rules" LocLabel="SR.SchemaHierarchy_Rules" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="Rule" ChildQuerierTypes="SqlRule" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
<Node Name="Defaults" LocLabel="SR.SchemaHierarchy_Defaults" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlDefault" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/> <Node Name="Defaults" LocLabel="SR.SchemaHierarchy_Defaults" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="Default" ChildQuerierTypes="SqlDefault" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
<Node Name="Sequences" LocLabel="SR.SchemaHierarchy_Sequences" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSequence" ValidFor="Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/> <Node Name="Sequences" LocLabel="SR.SchemaHierarchy_Sequences" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="Sequence" ChildQuerierTypes="SqlSequence" ValidFor="Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
<Node Name="SystemDataTypes" LocLabel="SR.SchemaHierarchy_SystemDataTypes" BaseClass="ModelBased" > <Node Name="SystemDataTypes" LocLabel="SR.SchemaHierarchy_SystemDataTypes" BaseClass="ModelBased" >
<Child Name="SystemExactNumerics"/> <Child Name="SystemExactNumerics"/>
@@ -228,18 +240,18 @@
<Child Name="SystemClrDataTypes"/> <Child Name="SystemClrDataTypes"/>
<Child Name="SystemSpatialDataTypes"/> <Child Name="SystemSpatialDataTypes"/>
</Node> </Node>
<Node Name="UserDefinedDataTypes" LocLabel="SR.SchemaHierarchy_UserDefinedDataTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedDataType"/> <Node Name="UserDefinedDataTypes" LocLabel="SR.SchemaHierarchy_UserDefinedDataTypes" BaseClass="ModelBased" NodeType="UserDefinedDataType" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedDataType"/>
<Node Name="UserDefinedTableTypes" LocLabel="SR.SchemaHierarchy_UserDefinedTableTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedTableType" TreeNode="UserDefinedTableTypeTreeNode" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV11|AzureV12"/> <Node Name="UserDefinedTableTypes" LocLabel="SR.SchemaHierarchy_UserDefinedTableTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedTableType" TreeNode="UserDefinedTableTypeTreeNode" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV11|AzureV12"/>
<Node Name="UserDefinedTypes" LocLabel="SR.SchemaHierarchy_UserDefinedTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedType" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/> <Node Name="UserDefinedTypes" LocLabel="SR.SchemaHierarchy_UserDefinedTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="UserDefinedType" ChildQuerierTypes="SqlUserDefinedType" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
<Node Name="XmlSchemaCollections" LocLabel="SR.SchemaHierarchy_XMLSchemaCollections" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlXmlSchemaCollection" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/> <Node Name="XmlSchemaCollections" LocLabel="SR.SchemaHierarchy_XMLSchemaCollections" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="XmlSchemaCollection" ChildQuerierTypes="SqlXmlSchemaCollection" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
<Node Name="UserDefinedTableType" LocLabel="string.Empty" BaseClass="ModelBased" ChildQuerierTypes="" IsAsyncLoad="" Strategy="PopulateDetails"> <Node Name="UserDefinedTableType" LocLabel="string.Empty" BaseClass="ModelBased" ChildQuerierTypes="" NodeType="UserDefinedTableType" IsAsyncLoad="" Strategy="PopulateDetails">
<Child Name="UserDefinedTableTypeColumns"/> <Child Name="UserDefinedTableTypeColumns"/>
<Child Name="UserDefinedTableTypeKeys"/> <Child Name="UserDefinedTableTypeKeys"/>
<Child Name="UserDefinedTableTypeConstraints"/> <Child Name="UserDefinedTableTypeConstraints"/>
</Node> </Node>
<Node Name="UserDefinedTableTypeColumns" LocLabel="SR.SchemaHierarchy_Columns" BaseClass="ModelBased" Strategy="PopulateParentDetails" ChildQuerierTypes="SqlColumn" DisableSort=""/> <Node Name="UserDefinedTableTypeColumns" LocLabel="SR.SchemaHierarchy_Columns" BaseClass="ModelBased" NodeType="UserDefinedTableTypeColumn" Strategy="PopulateParentDetails" ChildQuerierTypes="SqlColumn" DisableSort=""/>
<Node Name="UserDefinedTableTypeKeys" LocLabel="SR.SchemaHierarchy_Keys" BaseClass="ModelBased" Strategy="PopulateParentDetails" ChildQuerierTypes="SqlIndex"> <Node Name="UserDefinedTableTypeKeys" LocLabel="SR.SchemaHierarchy_Keys" BaseClass="ModelBased" NodeType="UserDefinedTableTypeKey" Strategy="PopulateParentDetails" ChildQuerierTypes="SqlIndex">
<Filters> <Filters>
<Filter TypeToReverse="SqlIndex" Property="IndexKeyType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12"> <Filter TypeToReverse="SqlIndex" Property="IndexKeyType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12">
<Value>IndexKeyType.DriPrimaryKey</Value> <Value>IndexKeyType.DriPrimaryKey</Value>
@@ -247,60 +259,71 @@
</Filter> </Filter>
</Filters> </Filters>
</Node> </Node>
<Node Name="UserDefinedTableTypeConstraints" LocLabel="SR.SchemaHierarchy_Constraints" BaseClass="ModelBased" Strategy="PopulateParentDetails" ChildQuerierTypes="SqlDefaultConstraint;SqlCheck"/>/> <Node Name="UserDefinedTableTypeConstraints" LocLabel="SR.SchemaHierarchy_Constraints" BaseClass="ModelBased" NodeType="UserDefinedTableTypeConstraint" Strategy="PopulateParentDetails" ChildQuerierTypes="SqlDefaultConstraint;SqlCheck"/>/>
<Node Name="SystemExactNumerics" LocLabel="SR.SchemaHierarchy_SystemExactNumerics" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/> <Node Name="SystemExactNumerics" LocLabel="SR.SchemaHierarchy_SystemExactNumerics" BaseClass="ModelBased" NodeType="SystemExactNumeric" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/>
<Node Name="SystemApproximateNumerics" LocLabel="SR.SchemaHierarchy_SystemApproximateNumerics" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/> <Node Name="SystemApproximateNumerics" LocLabel="SR.SchemaHierarchy_SystemApproximateNumerics" BaseClass="ModelBased" NodeType="SystemApproximateNumeric" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/>
<Node Name="SystemDateAndTimes" LocLabel="SR.SchemaHierarchy_SystemDateAndTime" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/> <Node Name="SystemDateAndTimes" LocLabel="SR.SchemaHierarchy_SystemDateAndTime" BaseClass="ModelBased" NodeType="SystemDateAndTime" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/>
<Node Name="SystemCharacterStrings" LocLabel="SR.SchemaHierarchy_SystemCharacterStrings" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/> <Node Name="SystemCharacterStrings" LocLabel="SR.SchemaHierarchy_SystemCharacterStrings" BaseClass="ModelBased" NodeType="SystemCharacterString" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/>
<Node Name="SystemUnicodeCharacterStrings" LocLabel="SR.SchemaHierarchy_SystemUnicodeCharacterStrings" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/> <Node Name="SystemUnicodeCharacterStrings" LocLabel="SR.SchemaHierarchy_SystemUnicodeCharacterStrings" BaseClass="ModelBased" NodeType="SystemUnicodeCharacterString" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/>
<Node Name="SystemBinaryStrings" LocLabel="SR.SchemaHierarchy_SystemBinaryStrings" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/> <Node Name="SystemBinaryStrings" LocLabel="SR.SchemaHierarchy_SystemBinaryStrings" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="SystemBinaryString" ChildQuerierTypes="SqlBuiltInType"/>
<Node Name="SystemOtherDataTypes" LocLabel="SR.SchemaHierarchy_SystemOtherDataTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/> <Node Name="SystemOtherDataTypes" LocLabel="SR.SchemaHierarchy_SystemOtherDataTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="SystemOtherDataType" ChildQuerierTypes="SqlBuiltInType"/>
<Node Name="SystemClrDataTypes" LocLabel="SR.SchemaHierarchy_SystemCLRDataTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedType" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV11|AzureV12"/> <Node Name="SystemClrDataTypes" LocLabel="SR.SchemaHierarchy_SystemCLRDataTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="SystemClrDataType" ChildQuerierTypes="SqlUserDefinedType" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV11|AzureV12"/>
<Node Name="SystemSpatialDataTypes" LocLabel="SR.SchemaHierarchy_SystemSpatialDataTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedType" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV11|AzureV12"/> <Node Name="SystemSpatialDataTypes" LocLabel="SR.SchemaHierarchy_SystemSpatialDataTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="SystemSpatialDataType" ChildQuerierTypes="SqlUserDefinedType" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV11|AzureV12"/>
<!-- Childs of ExternalResources --> <!-- Childs of ExternalResources -->
<Node Name="ExternalDataSources" LocLabel="SR.SchemaHierarchy_ExternalDataSources" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlExternalDataSource" ValidFor="Sql2016|SqlvNext|AzureV12"/> <Node Name="ExternalDataSources" LocLabel="SR.SchemaHierarchy_ExternalDataSources" BaseClass="ModelBased" NodeType="ExternalDataSource" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlExternalDataSource" ValidFor="Sql2016|SqlvNext|AzureV12"/>
<Node Name="ExternalFileFormats" LocLabel="SR.SchemaHierarchy_ExternalFileFormats" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlExternalFileFormat" ValidFor="Sql2016|SqlvNext"/> <Node Name="ExternalFileFormats" LocLabel="SR.SchemaHierarchy_ExternalFileFormats" BaseClass="ModelBased" NodeType="ExternalFileFormat" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlExternalFileFormat" ValidFor="Sql2016|SqlvNext"/>
<Node Name="StoredProcedures" LocLabel="SR.SchemaHierarchy_StoredProcedures" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlProcedure" TreeNode="StoredProcedureTreeNode"> <Node Name="StoredProcedures" LocLabel="SR.SchemaHierarchy_StoredProcedures" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlProcedure" TreeNode="StoredProcedureTreeNode">
<Filters >
<Filter Property="IsSystemObject" Value="0" Type="bool" />
</Filters>
<Child Name="SystemStoredProcedures"/> <Child Name="SystemStoredProcedures"/>
</Node> </Node>
<Node Name="SystemStoredProcedures" LocLabel="SR.SchemaHierarchy_SystemStoredProcedures" BaseClass="ModelBased" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlProcedure" TreeNode="StoredProcedureTreeNode"/> <Node Name="SystemStoredProcedures" LocLabel="SR.SchemaHierarchy_SystemStoredProcedures" BaseClass="ModelBased" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlProcedure" TreeNode="StoredProcedureTreeNode">
<Node Name="StoredProcedure" LocLabel="string.Empty" BaseClass="ModelBased" ChildQuerierTypes="" IsAsyncLoad="" Strategy="PopulateDetails"> <Filters >
<Child Name="StoredProcedureParameters"/> <Filter Property="IsSystemObject" Value="1" Type="bool" />
</Node>
<Node Name="StoredProcedureParameters" LocLabel="SR.SchemaHierarchy_Parameters" BaseClass="ModelBased" Strategy="StoredProcedureParameters" ChildQuerierTypes="SqlSubroutineParameter" DisableSort=""/>
<Node Name="TableValuedFunctions" LocLabel="SR.SchemaHierarchy_TableValuedFunctions" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedFunction" TreeNode="TableValuedFunctionTreeNode">
<Filters>
<Filter Property="UserDefinedFunctionType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12">
<Value>UserDefinedFunctionType.Table</Value>
</Filter>
</Filters> </Filters>
</Node> </Node>
<Node Name="TableValuedFunction" LocLabel="string.Empty" BaseClass="ModelBased" ChildQuerierTypes="" IsAsyncLoad="" Strategy="PopulateDetails"> <Node Name="StoredProcedure" LocLabel="string.Empty" BaseClass="ModelBased" ChildQuerierTypes="" NodeType="StoredProcedure" IsAsyncLoad="" Strategy="PopulateDetails">
<Child Name="StoredProcedureParameters"/>
</Node>
<Node Name="StoredProcedureParameters" LocLabel="SR.SchemaHierarchy_Parameters" BaseClass="ModelBased" NodeType="StoredProcedureParameter" Strategy="StoredProcedureParameters" ChildQuerierTypes="SqlSubroutineParameter" DisableSort=""/>
<Node Name="TableValuedFunctions" LocLabel="SR.SchemaHierarchy_TableValuedFunctions" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedFunction" TreeNode="TableValuedFunctionTreeNode">
<Filters >
<Filter Property="FunctionType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12">
<Value>UserDefinedFunctionType.Table</Value>
</Filter>
<Filter Property="IsSystemObject" Value="0" Type="bool" />
</Filters>
</Node>
<Node Name="TableValuedFunction" LocLabel="string.Empty" BaseClass="ModelBased" ChildQuerierTypes="" NodeType="TableValuedFunction" IsAsyncLoad="" Strategy="PopulateDetails">
<Child Name="TableValuedFunctionParameters"/> <Child Name="TableValuedFunctionParameters"/>
</Node> </Node>
<Node Name="TableValuedFunctionParameters" LocLabel="SR.SchemaHierarchy_Parameters" BaseClass="ModelBased" Strategy="FunctionParameters" ChildQuerierTypes="SqlSubroutineParameter" DisableSort=""/> <Node Name="TableValuedFunctionParameters" LocLabel="SR.SchemaHierarchy_Parameters" BaseClass="ModelBased" NodeType="TableValuedFunctionParameter" Strategy="FunctionParameters" ChildQuerierTypes="SqlSubroutineParameter" DisableSort="">
</Node>
<Node Name="ScalarValuedFunctions" LocLabel="SR.SchemaHierarchy_ScalarValuedFunctions" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedFunction" TreeNode="ScalarValuedFunctionTreeNode" > <Node Name="ScalarValuedFunctions" LocLabel="SR.SchemaHierarchy_ScalarValuedFunctions" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedFunction" TreeNode="ScalarValuedFunctionTreeNode" >
<Filters> <Filters>
<Filter Property="UserDefinedFunctionType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12"> <Filter Property="FunctionType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12">
<Value>UserDefinedFunctionType.Table</Value> <Value>UserDefinedFunctionType.Scalar</Value>
</Filter> </Filter>
<Filter Property="IsSystemObject" Value="0" Type="bool" />
</Filters> </Filters>
</Node> </Node>
<Node Name="ScalarValuedFunction" LocLabel="string.Empty" BaseClass="ModelBased" ChildQuerierTypes="" IsAsyncLoad="" Strategy="PopulateDetails"> <Node Name="ScalarValuedFunction" LocLabel="string.Empty" BaseClass="ModelBased" NodeType="ScalarValuedFunction" ChildQuerierTypes="" IsAsyncLoad="" Strategy="PopulateDetails">
<Child Name="ScalarValuedFunctionParameters"/> <Child Name="ScalarValuedFunctionParameters"/>
</Node> </Node>
<Node Name="ScalarValuedFunctionParameters" LocLabel="SR.SchemaHierarchy_Parameters" BaseClass="ModelBased" Strategy="FunctionParameters" ChildQuerierTypes="SqlSubroutineParameter" DisableSort=""/> <Node Name="ScalarValuedFunctionParameters" LocLabel="SR.SchemaHierarchy_Parameters" NodeType="ScalarValuedFunctionParameter" BaseClass="ModelBased" Strategy="FunctionParameters" ChildQuerierTypes="SqlSubroutineParameter" DisableSort=""/>
<Node Name="AggregateFunctions" LocLabel="SR.SchemaHierarchy_AggregateFunctions" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedAggregate" TreeNode="AggregateFunctionTreeNode" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/> <Node Name="AggregateFunctions" LocLabel="SR.SchemaHierarchy_AggregateFunctions" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedAggregate" TreeNode="AggregateFunctionTreeNode" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12">
<Node Name="AggregateFunction" LocLabel="string.Empty" BaseClass="ModelBased" ChildQuerierTypes="" IsAsyncLoad="" Strategy="PopulateDetails"> </Node>
<Node Name="AggregateFunction" LocLabel="string.Empty" BaseClass="ModelBased" ChildQuerierTypes="" NodeType="AggregateFunction" IsAsyncLoad="" Strategy="PopulateDetails">
<Child Name="AggregateFunctionParameters"/> <Child Name="AggregateFunctionParameters"/>
</Node> </Node>
<Node Name="AggregateFunctionParameters" LocLabel="SR.SchemaHierarchy_Parameters" BaseClass="ModelBased" Strategy="PopulateParentDetails" ChildQuerierTypes="SqlSubroutineParameter" DisableSort=""/> <Node Name="AggregateFunctionParameters" LocLabel="SR.SchemaHierarchy_Parameters" BaseClass="ModelBased" NodeType="AggregateFunctionParameter" Strategy="PopulateParentDetails" ChildQuerierTypes="SqlSubroutineParameter" DisableSort=""/>
<!-- TODO Support Route in SMO <!-- TODO Support Route in SMO
<Node Name="Routes" LocLabel="SR.SchemaHierarchy_Routes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlRoute"/> <Node Name="Routes" LocLabel="SR.SchemaHierarchy_Routes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlRoute"/>
@@ -308,71 +331,71 @@
<!-- TODO support events <!-- TODO support events
<Node Name="DatabaseAndQueueEventNotifications" LocLabel="SR.SchemaHierarchy_EventNotifications" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlEventNotification"/> <Node Name="DatabaseAndQueueEventNotifications" LocLabel="SR.SchemaHierarchy_EventNotifications" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlEventNotification"/>
--> -->
<Node Name="RemoteServiceBindings" LocLabel="SR.SchemaHierarchy_RemoteServiceBindings" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlRemoteServiceBinding"/> <Node Name="RemoteServiceBindings" LocLabel="SR.SchemaHierarchy_RemoteServiceBindings" BaseClass="ModelBased" NodeType="RemoteServiceBinding" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlRemoteServiceBinding"/>
<Node Name="BrokerPriorities" LocLabel="SR.SchemaHierarchy_BrokerPriorities" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBrokerPriority" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/> <Node Name="BrokerPriorities" LocLabel="SR.SchemaHierarchy_BrokerPriorities" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="BrokerPriority" ChildQuerierTypes="SqlBrokerPriority" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
<Node Name="FileGroups" LocLabel="SR.SchemaHierarchy_FileGroups" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlFileGroup" TreeNode="FileGroupTreeNode"/> <Node Name="FileGroups" LocLabel="SR.SchemaHierarchy_FileGroups" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlFileGroup" TreeNode="FileGroupTreeNode"/>
<Node Name="FullTextCatalogs" LocLabel="SR.SchemaHierarchy_FullTextCatalogs" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlFullTextCatalog"/> <Node Name="FullTextCatalogs" LocLabel="SR.SchemaHierarchy_FullTextCatalogs" BaseClass="ModelBased" NodeType="FullTextCatalog" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlFullTextCatalog"/>
<Node Name="FullTextStopLists" LocLabel="SR.SchemaHierarchy_FullTextStopLists" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlFullTextStopList" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/> <Node Name="FullTextStopLists" LocLabel="SR.SchemaHierarchy_FullTextStopLists" BaseClass="ModelBased" NodeType="FullTextStopList" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlFullTextStopList" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
<Node Name="SqlLogFiles" LocLabel="SR.SchemaHierarchy_LogFiles" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlFile"/> <Node Name="SqlLogFiles" LocLabel="SR.SchemaHierarchy_LogFiles" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="SqlLogFile" ChildQuerierTypes="SqlFile"/>
<Node Name="PartitionFunctions" LocLabel="SR.SchemaHierarchy_PartitionFunctions" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlPartitionFunction"/> <Node Name="PartitionFunctions" LocLabel="SR.SchemaHierarchy_PartitionFunctions" BaseClass="ModelBased" NodeType="PartitionFunction" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlPartitionFunction"/>
<Node Name="PartitionSchemes" LocLabel="SR.SchemaHierarchy_PartitionSchemes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlPartitionScheme"/> <Node Name="PartitionSchemes" LocLabel="SR.SchemaHierarchy_PartitionSchemes" BaseClass="ModelBased" NodeType="PartitionScheme" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlPartitionScheme"/>
<Node Name="SearchPropertyLists" LocLabel="SR.SchemaHierarchy_SearchPropertyLists" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSearchPropertyList" ValidFor="Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/> <Node Name="SearchPropertyLists" LocLabel="SR.SchemaHierarchy_SearchPropertyLists" BaseClass="ModelBased" NodeType="SearchPropertyList" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSearchPropertyList" ValidFor="Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
<Node Name="FileGroup" LocLabel="string.Empty" BaseClass="ModelBased" ChildQuerierTypes=""> <Node Name="FileGroup" LocLabel="string.Empty" BaseClass="ModelBased" ChildQuerierTypes="">
<Child Name="FileGroupFiles"/> <Child Name="FileGroupFiles"/>
</Node> </Node>
<Node Name="FileGroupFiles" LocLabel="SR.SchemaHierarchy_FilegroupFiles" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlFile" > <Node Name="FileGroupFiles" LocLabel="SR.SchemaHierarchy_FilegroupFiles" BaseClass="ModelBased" NodeType="FileGroupFile" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlFile" >
</Node> </Node>
<Node Name="Users" LocLabel="SR.SchemaHierarchy_Users" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUser"/> <Node Name="Users" LocLabel="SR.SchemaHierarchy_Users" BaseClass="ModelBased" NodeType="User" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUser"/>
<Node Name="Roles" LocLabel="SR.SchemaHierarchy_Roles" BaseClass="ModelBased" > <Node Name="Roles" LocLabel="SR.SchemaHierarchy_Roles" NodeType="Role" BaseClass="ModelBased" >
<Child Name="DatabaseRoles"/> <Child Name="DatabaseRoles"/>
<Child Name="ApplicationRoles"/> <Child Name="ApplicationRoles"/>
</Node> </Node>
<Node Name="Schemas" LocLabel="SR.SchemaHierarchy_Schemas" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSchema"/> <Node Name="Schemas" LocLabel="SR.SchemaHierarchy_Schemas" BaseClass="ModelBased" NodeType="Schema" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSchema"/>
<Node Name="AsymmetricKeys" LocLabel="SR.SchemaHierarchy_AsymmetricKeys" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlAsymmetricKey" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/> <Node Name="AsymmetricKeys" LocLabel="SR.SchemaHierarchy_AsymmetricKeys" BaseClass="ModelBased" NodeType="AsymmetricKey" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlAsymmetricKey" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
<Node Name="Certificates" LocLabel="SR.SchemaHierarchy_Certificates" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlCertificate" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/> <Node Name="Certificates" LocLabel="SR.SchemaHierarchy_Certificates" BaseClass="ModelBased" NodeType="Certificate" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlCertificate" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
<Node Name="SymmetricKeys" LocLabel="SR.SchemaHierarchy_SymmetricKeys" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSymmetricKey" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/> <Node Name="SymmetricKeys" LocLabel="SR.SchemaHierarchy_SymmetricKeys" BaseClass="ModelBased" NodeType="SymmetricKey" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSymmetricKey" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
<Node Name="DatabaseEncryptionKeys" LocLabel="SR.SchemaHierarchy_DatabaseEncryptionKeys" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlDatabaseEncryptionKey" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/> <Node Name="DatabaseEncryptionKeys" LocLabel="SR.SchemaHierarchy_DatabaseEncryptionKeys" BaseClass="ModelBased" NodeType="DatabaseEncryptionKey" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlDatabaseEncryptionKey" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
<Node Name="MasterKeys" LocLabel="SR.SchemaHierarchy_MasterKeys" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlMasterKey" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/> <Node Name="MasterKeys" LocLabel="SR.SchemaHierarchy_MasterKeys" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="MasterKey" ChildQuerierTypes="SqlMasterKey" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
<!-- TODO Support signatures <!-- TODO Support signatures
<Node Name="Signatures" LocLabel="SR.SchemaHierarchy_Signatures" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSignature" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/> <Node Name="Signatures" LocLabel="SR.SchemaHierarchy_Signatures" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSignature" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
--> -->
<Node Name="DatabaseAuditSpecifications" LocLabel="SR.SchemaHierarchy_DatabaseAuditSpecifications" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlDatabaseAuditSpecification" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/> <Node Name="DatabaseAuditSpecifications" LocLabel="SR.SchemaHierarchy_DatabaseAuditSpecifications" BaseClass="ModelBased" NodeType="DatabaseAuditSpecification" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlDatabaseAuditSpecification" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
<Node Name="SecurityPolicies" LocLabel="SR.SchemaHierarchy_SecurityPolicies" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSecurityPolicy" ValidFor="Sql2016|SqlvNext|AzureV12"/> <Node Name="SecurityPolicies" LocLabel="SR.SchemaHierarchy_SecurityPolicies" BaseClass="ModelBased" Strategy="MultipleElementsOfType" NodeType="SecurityPolicie" ChildQuerierTypes="SqlSecurityPolicy" ValidFor="Sql2016|SqlvNext|AzureV12"/>
<Node Name="DatabaseScopedCredentials" LocLabel="SR.SchemaHierarchy_DatabaseScopedCredentials" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlDatabaseCredential" ValidFor="Sql2016|SqlvNext|AzureV12"/> <Node Name="DatabaseScopedCredentials" LocLabel="SR.SchemaHierarchy_DatabaseScopedCredentials" BaseClass="ModelBased" NodeType="DatabaseScopedCredential" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlDatabaseCredential" ValidFor="Sql2016|SqlvNext|AzureV12"/>
<Node Name="AlwaysEncryptedKeys" LocLabel="SR.SchemaHierarchy_AlwaysEncryptedKeys" BaseClass="ModelBased" ValidFor="Sql2016|SqlvNext|AzureV12"> <Node Name="AlwaysEncryptedKeys" LocLabel="SR.SchemaHierarchy_AlwaysEncryptedKeys" BaseClass="ModelBased" ValidFor="Sql2016|SqlvNext|AzureV12">
<Child Name="ColumnMasterKeys"/> <Child Name="ColumnMasterKeys"/>
<Child Name="ColumnEncryptionKeys"/> <Child Name="ColumnEncryptionKeys"/>
</Node> </Node>
<Node Name="DatabaseRoles" LocLabel="SR.SchemaHierarchy_DatabaseRoles" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlRole"/> <Node Name="DatabaseRoles" LocLabel="SR.SchemaHierarchy_DatabaseRoles" BaseClass="ModelBased" NodeType="DatabaseRole" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlRole"/>
<Node Name="ApplicationRoles" LocLabel="SR.SchemaHierarchy_ApplicationRoles" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlApplicationRole" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/> <Node Name="ApplicationRoles" LocLabel="SR.SchemaHierarchy_ApplicationRoles" BaseClass="ModelBased" NodeType="ApplicationRole" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlApplicationRole" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
<Node Name="ColumnMasterKeys" LocLabel="SR.SchemaHierarchy_ColumnMasterKeys" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlColumnMasterKey" ValidFor="Sql2016|SqlvNext|AzureV12"/> <Node Name="ColumnMasterKeys" LocLabel="SR.SchemaHierarchy_ColumnMasterKeys" BaseClass="ModelBased" NodeType="ColumnMasterKey" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlColumnMasterKey" ValidFor="Sql2016|SqlvNext|AzureV12"/>
<Node Name="ColumnEncryptionKeys" LocLabel="SR.SchemaHierarchy_ColumnEncryptionKeys" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlColumnEncryptionKey" ValidFor="Sql2016|SqlvNext|AzureV12"/> <Node Name="ColumnEncryptionKeys" LocLabel="SR.SchemaHierarchy_ColumnEncryptionKeys" BaseClass="ModelBased" NodeType="ColumnEncryptionKey" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlColumnEncryptionKey" ValidFor="Sql2016|SqlvNext|AzureV12"/>
<Node Name="MessageTypes" LocLabel="SR.SchemaHierarchy_MessageTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlMessageType"> <Node Name="MessageTypes" LocLabel="SR.SchemaHierarchy_MessageTypes" BaseClass="ModelBased" NodeType="MessageType" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlMessageType">
<Child Name="SystemMessageTypes"/> <Child Name="SystemMessageTypes"/>
</Node> </Node>
<Node Name="SystemMessageTypes" LocLabel="SR.SchemaHierarchy_SystemMessageTypes" BaseClass="ModelBased" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlMessageType"/> <Node Name="SystemMessageTypes" LocLabel="SR.SchemaHierarchy_SystemMessageTypes" BaseClass="ModelBased" NodeType="SystemMessageType" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlMessageType"/>
<Node Name="Contracts" LocLabel="SR.SchemaHierarchy_Contracts" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlContract"> <Node Name="Contracts" LocLabel="SR.SchemaHierarchy_Contracts" BaseClass="ModelBased" NodeType="Contract" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlContract">
<Child Name="SystemContracts"/> <Child Name="SystemContracts"/>
</Node> </Node>
<Node Name="SystemContracts" LocLabel="SR.SchemaHierarchy_SystemContracts" BaseClass="ModelBased" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlContract"/> <Node Name="SystemContracts" LocLabel="SR.SchemaHierarchy_SystemContracts" BaseClass="ModelBased" NodeType="SystemContract" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlContract"/>
<Node Name="Queues" LocLabel="SR.SchemaHierarchy_Queues" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlQueue"> <Node Name="Queues" LocLabel="SR.SchemaHierarchy_Queues" BaseClass="ModelBased" NodeType="Queue" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlQueue">
<Child Name="SystemQueues"/> <Child Name="SystemQueues"/>
</Node> </Node>
<Node Name="SystemQueues" LocLabel="SR.SchemaHierarchy_SystemQueues" BaseClass="ModelBased" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlQueue"/> <Node Name="SystemQueues" LocLabel="SR.SchemaHierarchy_SystemQueues" BaseClass="ModelBased" NodeType="SystemQueue" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlQueue"/>
<Node Name="Services" LocLabel="SR.SchemaHierarchy_Services" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlService"> <Node Name="Services" LocLabel="SR.SchemaHierarchy_Services" BaseClass="ModelBased" NodeType="Service" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlService">
<Child Name="SystemServices"/> <Child Name="SystemServices"/>
</Node> </Node>
<Node Name="SystemServices" LocLabel="SR.SchemaHierarchy_SystemServices" BaseClass="ModelBased" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlService"/> <Node Name="SystemServices" LocLabel="SR.SchemaHierarchy_SystemServices" BaseClass="ModelBased" NodeType="SystemService" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlService"/>
<CodeGenOptions> <CodeGenOptions>
<UniqueTreeNode Name="DatabaseTreeNode"/> <UniqueTreeNode Name="DatabaseTreeNode"/>

View File

@@ -1,12 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Composition; using System.Composition;
using Microsoft.SqlTools.ServiceLayer; using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; using Microsoft.SqlTools.ServiceLayer;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{
internal sealed partial class DatabaseTreeNode : SmoTreeNode internal sealed partial class DatabaseTreeNode : SmoTreeNode
{ {
public DatabaseTreeNode() : base() public DatabaseTreeNode() : base()
@@ -657,6 +658,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
var child = new SmoTreeNode(); var child = new SmoTreeNode();
child.IsAlwaysLeaf = true; child.IsAlwaysLeaf = true;
child.NodeType = "Database";
InitializeChild(child, context); InitializeChild(child, context);
return child; return child;
} }
@@ -668,6 +670,45 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
public override IEnumerable<string> ApplicableParents() { return new[] { "Tables" }; } public override IEnumerable<string> ApplicableParents() { return new[] { "Tables" }; }
public override IEnumerable<NodeFilter> Filters
{
get
{
var filters = new List<NodeFilter>();
filters.Add(new NodeFilter
{
Property = "IsFileTable",
Type = typeof(bool),
Values = new List<object> { 0 },
});
filters.Add(new NodeFilter
{
Property = "IsSystemObject",
Type = typeof(bool),
Values = new List<object> { 0 },
});
filters.Add(new NodeFilter
{
Property = "IsExternal",
Type = typeof(bool),
ValidFor = ValidForFlag.Sql2016|ValidForFlag.AzureV12,
Values = new List<object> { 0 },
});
filters.Add(new NodeFilter
{
Property = "TemporalType",
Type = typeof(Enum),
ValidFor = ValidForFlag.Sql2016|ValidForFlag.AzureV12,
Values = new List<object>
{
{ TableTemporalType.None },
{ TableTemporalType.SystemVersioned }
}
});
return filters;
}
}
protected override void OnExpandPopulateFolders(IList<TreeNode> currentChildren, TreeNode parent) protected override void OnExpandPopulateFolders(IList<TreeNode> currentChildren, TreeNode parent)
{ {
currentChildren.Add(new FolderNode { currentChildren.Add(new FolderNode {
@@ -715,6 +756,21 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
public override IEnumerable<string> ApplicableParents() { return new[] { "Views" }; } public override IEnumerable<string> ApplicableParents() { return new[] { "Views" }; }
public override IEnumerable<NodeFilter> Filters
{
get
{
var filters = new List<NodeFilter>();
filters.Add(new NodeFilter
{
Property = "IsSystemObject",
Type = typeof(bool),
Values = new List<object> { 0 },
});
return filters;
}
}
protected override void OnExpandPopulateFolders(IList<TreeNode> currentChildren, TreeNode parent) protected override void OnExpandPopulateFolders(IList<TreeNode> currentChildren, TreeNode parent)
{ {
currentChildren.Add(new FolderNode { currentChildren.Add(new FolderNode {
@@ -1095,6 +1151,21 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
public override IEnumerable<string> ApplicableParents() { return new[] { "SystemTables" }; } public override IEnumerable<string> ApplicableParents() { return new[] { "SystemTables" }; }
public override IEnumerable<NodeFilter> Filters
{
get
{
var filters = new List<NodeFilter>();
filters.Add(new NodeFilter
{
Property = "IsSystemObject",
Type = typeof(bool),
Values = new List<object> { 1 },
});
return filters;
}
}
internal override Type[] ChildQuerierTypes internal override Type[] ChildQuerierTypes
{ {
get get
@@ -1117,6 +1188,21 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
public override IEnumerable<string> ApplicableParents() { return new[] { "FileTables" }; } public override IEnumerable<string> ApplicableParents() { return new[] { "FileTables" }; }
public override IEnumerable<NodeFilter> Filters
{
get
{
var filters = new List<NodeFilter>();
filters.Add(new NodeFilter
{
Property = "IsFileTable",
Type = typeof(bool),
Values = new List<object> { 1 },
});
return filters;
}
}
internal override Type[] ChildQuerierTypes internal override Type[] ChildQuerierTypes
{ {
get get
@@ -1139,6 +1225,21 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
public override IEnumerable<string> ApplicableParents() { return new[] { "ExternalTables" }; } public override IEnumerable<string> ApplicableParents() { return new[] { "ExternalTables" }; }
public override IEnumerable<NodeFilter> Filters
{
get
{
var filters = new List<NodeFilter>();
filters.Add(new NodeFilter
{
Property = "IsExternal",
Type = typeof(bool),
Values = new List<object> { 1 },
});
return filters;
}
}
internal override Type[] ChildQuerierTypes internal override Type[] ChildQuerierTypes
{ {
get get
@@ -1161,6 +1262,25 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
public override IEnumerable<string> ApplicableParents() { return new[] { "Table" }; } public override IEnumerable<string> ApplicableParents() { return new[] { "Table" }; }
public override IEnumerable<NodeFilter> Filters
{
get
{
var filters = new List<NodeFilter>();
filters.Add(new NodeFilter
{
Property = "TemporalType",
Type = typeof(Enum),
ValidFor = ValidForFlag.Sql2016|ValidForFlag.AzureV12,
Values = new List<object>
{
{ TableTemporalType.HistoryTable }
}
});
return filters;
}
}
protected override void OnExpandPopulateFolders(IList<TreeNode> currentChildren, TreeNode parent) protected override void OnExpandPopulateFolders(IList<TreeNode> currentChildren, TreeNode parent)
{ {
currentChildren.Add(new FolderNode { currentChildren.Add(new FolderNode {
@@ -1257,6 +1377,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
var child = new SmoTreeNode(); var child = new SmoTreeNode();
child.IsAlwaysLeaf = true; child.IsAlwaysLeaf = true;
child.NodeType = "Table";
InitializeChild(child, context); InitializeChild(child, context);
return child; return child;
} }
@@ -1296,6 +1417,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
var child = new SmoTreeNode(); var child = new SmoTreeNode();
child.IsAlwaysLeaf = true; child.IsAlwaysLeaf = true;
child.NodeType = "Table";
InitializeChild(child, context); InitializeChild(child, context);
return child; return child;
} }
@@ -1332,6 +1454,27 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
public override IEnumerable<string> ApplicableParents() { return new[] { "Keys" }; } public override IEnumerable<string> ApplicableParents() { return new[] { "Keys" }; }
public override IEnumerable<NodeFilter> Filters
{
get
{
var filters = new List<NodeFilter>();
filters.Add(new NodeFilter
{
Property = "IndexKeyType",
Type = typeof(Enum),
TypeToReverse = typeof(SqlIndexQuerier),
ValidFor = ValidForFlag.Sql2016|ValidForFlag.AzureV12,
Values = new List<object>
{
{ IndexKeyType.DriPrimaryKey },
{ IndexKeyType.DriUniqueKey }
}
});
return filters;
}
}
internal override Type[] ChildQuerierTypes internal override Type[] ChildQuerierTypes
{ {
get get
@@ -1404,6 +1547,26 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
public override IEnumerable<string> ApplicableParents() { return new[] { "Indexes" }; } public override IEnumerable<string> ApplicableParents() { return new[] { "Indexes" }; }
public override IEnumerable<NodeFilter> Filters
{
get
{
var filters = new List<NodeFilter>();
filters.Add(new NodeFilter
{
Property = "IndexKeyType",
Type = typeof(Enum),
TypeToReverse = typeof(SqlIndexQuerier),
ValidFor = ValidForFlag.Sql2016|ValidForFlag.AzureV12,
Values = new List<object>
{
{ IndexKeyType.None }
}
});
return filters;
}
}
internal override Type[] ChildQuerierTypes internal override Type[] ChildQuerierTypes
{ {
get get
@@ -1416,7 +1579,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
var child = new SmoTreeNode(); var child = new SmoTreeNode();
child.IsAlwaysLeaf = true; child.IsAlwaysLeaf = true;
child.NodeType = "Indexe"; child.NodeType = "Index";
InitializeChild(child, context); InitializeChild(child, context);
return child; return child;
} }
@@ -1452,6 +1615,21 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
public override IEnumerable<string> ApplicableParents() { return new[] { "SystemViews" }; } public override IEnumerable<string> ApplicableParents() { return new[] { "SystemViews" }; }
public override IEnumerable<NodeFilter> Filters
{
get
{
var filters = new List<NodeFilter>();
filters.Add(new NodeFilter
{
Property = "IsSystemObject",
Type = typeof(bool),
Values = new List<object> { 1 },
});
return filters;
}
}
internal override Type[] ChildQuerierTypes internal override Type[] ChildQuerierTypes
{ {
get get
@@ -1513,6 +1691,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
var child = new SmoTreeNode(); var child = new SmoTreeNode();
child.IsAlwaysLeaf = true; child.IsAlwaysLeaf = true;
child.NodeType = "View";
InitializeChild(child, context); InitializeChild(child, context);
return child; return child;
} }
@@ -1598,7 +1777,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
var child = new SmoTreeNode(); var child = new SmoTreeNode();
child.IsAlwaysLeaf = true; child.IsAlwaysLeaf = true;
child.NodeType = "Assemblie"; child.NodeType = "Assembly";
InitializeChild(child, context); InitializeChild(child, context);
return child; return child;
} }
@@ -1936,6 +2115,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
var child = new SmoTreeNode(); var child = new SmoTreeNode();
child.IsAlwaysLeaf = true; child.IsAlwaysLeaf = true;
child.NodeType = "UserDefinedTableType";
InitializeChild(child, context); InitializeChild(child, context);
return child; return child;
} }
@@ -1972,6 +2152,27 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
public override IEnumerable<string> ApplicableParents() { return new[] { "UserDefinedTableTypeKeys" }; } public override IEnumerable<string> ApplicableParents() { return new[] { "UserDefinedTableTypeKeys" }; }
public override IEnumerable<NodeFilter> Filters
{
get
{
var filters = new List<NodeFilter>();
filters.Add(new NodeFilter
{
Property = "IndexKeyType",
Type = typeof(Enum),
TypeToReverse = typeof(SqlIndexQuerier),
ValidFor = ValidForFlag.Sql2016|ValidForFlag.AzureV12,
Values = new List<object>
{
{ IndexKeyType.DriPrimaryKey },
{ IndexKeyType.DriUniqueKey }
}
});
return filters;
}
}
internal override Type[] ChildQuerierTypes internal override Type[] ChildQuerierTypes
{ {
get get
@@ -2284,6 +2485,21 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
public override IEnumerable<string> ApplicableParents() { return new[] { "StoredProcedures" }; } public override IEnumerable<string> ApplicableParents() { return new[] { "StoredProcedures" }; }
public override IEnumerable<NodeFilter> Filters
{
get
{
var filters = new List<NodeFilter>();
filters.Add(new NodeFilter
{
Property = "IsSystemObject",
Type = typeof(bool),
Values = new List<object> { 0 },
});
return filters;
}
}
protected override void OnExpandPopulateFolders(IList<TreeNode> currentChildren, TreeNode parent) protected override void OnExpandPopulateFolders(IList<TreeNode> currentChildren, TreeNode parent)
{ {
currentChildren.Add(new FolderNode { currentChildren.Add(new FolderNode {
@@ -2317,6 +2533,21 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
public override IEnumerable<string> ApplicableParents() { return new[] { "SystemStoredProcedures" }; } public override IEnumerable<string> ApplicableParents() { return new[] { "SystemStoredProcedures" }; }
public override IEnumerable<NodeFilter> Filters
{
get
{
var filters = new List<NodeFilter>();
filters.Add(new NodeFilter
{
Property = "IsSystemObject",
Type = typeof(bool),
Values = new List<object> { 1 },
});
return filters;
}
}
internal override Type[] ChildQuerierTypes internal override Type[] ChildQuerierTypes
{ {
get get
@@ -2360,6 +2591,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
var child = new SmoTreeNode(); var child = new SmoTreeNode();
child.IsAlwaysLeaf = true; child.IsAlwaysLeaf = true;
child.NodeType = "StoredProcedure";
InitializeChild(child, context); InitializeChild(child, context);
return child; return child;
} }
@@ -2396,6 +2628,31 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
public override IEnumerable<string> ApplicableParents() { return new[] { "TableValuedFunctions" }; } public override IEnumerable<string> ApplicableParents() { return new[] { "TableValuedFunctions" }; }
public override IEnumerable<NodeFilter> Filters
{
get
{
var filters = new List<NodeFilter>();
filters.Add(new NodeFilter
{
Property = "FunctionType",
Type = typeof(Enum),
ValidFor = ValidForFlag.Sql2016|ValidForFlag.AzureV12,
Values = new List<object>
{
{ UserDefinedFunctionType.Table }
}
});
filters.Add(new NodeFilter
{
Property = "IsSystemObject",
Type = typeof(bool),
Values = new List<object> { 0 },
});
return filters;
}
}
internal override Type[] ChildQuerierTypes internal override Type[] ChildQuerierTypes
{ {
get get
@@ -2439,6 +2696,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
var child = new SmoTreeNode(); var child = new SmoTreeNode();
child.IsAlwaysLeaf = true; child.IsAlwaysLeaf = true;
child.NodeType = "TableValuedFunction";
InitializeChild(child, context); InitializeChild(child, context);
return child; return child;
} }
@@ -2475,6 +2733,31 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
public override IEnumerable<string> ApplicableParents() { return new[] { "ScalarValuedFunctions" }; } public override IEnumerable<string> ApplicableParents() { return new[] { "ScalarValuedFunctions" }; }
public override IEnumerable<NodeFilter> Filters
{
get
{
var filters = new List<NodeFilter>();
filters.Add(new NodeFilter
{
Property = "FunctionType",
Type = typeof(Enum),
ValidFor = ValidForFlag.Sql2016|ValidForFlag.AzureV12,
Values = new List<object>
{
{ UserDefinedFunctionType.Scalar }
}
});
filters.Add(new NodeFilter
{
Property = "IsSystemObject",
Type = typeof(bool),
Values = new List<object> { 0 },
});
return filters;
}
}
internal override Type[] ChildQuerierTypes internal override Type[] ChildQuerierTypes
{ {
get get
@@ -2518,6 +2801,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
var child = new SmoTreeNode(); var child = new SmoTreeNode();
child.IsAlwaysLeaf = true; child.IsAlwaysLeaf = true;
child.NodeType = "ScalarValuedFunction";
InitializeChild(child, context); InitializeChild(child, context);
return child; return child;
} }
@@ -2597,6 +2881,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
var child = new SmoTreeNode(); var child = new SmoTreeNode();
child.IsAlwaysLeaf = true; child.IsAlwaysLeaf = true;
child.NodeType = "AggregateFunction";
InitializeChild(child, context); InitializeChild(child, context);
return child; return child;
} }
@@ -2669,7 +2954,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
var child = new SmoTreeNode(); var child = new SmoTreeNode();
child.IsAlwaysLeaf = true; child.IsAlwaysLeaf = true;
child.NodeType = "BrokerPrioritie"; child.NodeType = "BrokerPriority";
InitializeChild(child, context); InitializeChild(child, context);
return child; return child;
} }
@@ -3527,5 +3812,5 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
} }
} }
} }

View File

@@ -10,6 +10,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Composition; using System.Composition;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer; using Microsoft.SqlTools.ServiceLayer;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
@@ -84,6 +85,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
var isAlwaysLeaf = nodeElement.GetAttributeNode("IsAlwaysLeaf"); var isAlwaysLeaf = nodeElement.GetAttributeNode("IsAlwaysLeaf");
var baseClass = nodeElement.GetAttribute("BaseClass"); var baseClass = nodeElement.GetAttribute("BaseClass");
var strategy = nodeElement.GetAttribute("Strategy"); var strategy = nodeElement.GetAttribute("Strategy");
var nodeType = nodeElement.GetAttribute("NodeType");
var ChildQuerierTypes = nodeElement.GetAttribute("ChildQuerierTypes"); var ChildQuerierTypes = nodeElement.GetAttribute("ChildQuerierTypes");
var TreeNode = nodeElement.GetAttribute("TreeNode"); var TreeNode = nodeElement.GetAttribute("TreeNode");
var isAsync = nodeElement.GetAttributeNode("IsAsyncLoad"); var isAsync = nodeElement.GetAttributeNode("IsAsyncLoad");
@@ -104,6 +106,81 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
WriteLine(string.Format(" public override IEnumerable<string> ApplicableParents() {{ return new[] {{ \"{0}\" }}; }}", type)); WriteLine(string.Format(" public override IEnumerable<string> ApplicableParents() {{ return new[] {{ \"{0}\" }}; }}", type));
List<XmlElement> children = GetChildren(xmlFile, type); List<XmlElement> children = GetChildren(xmlFile, type);
List<XmlElement> filters = GetNodeFilters(xmlFile, type);
if (filters.Count > 0)
{
WriteLine("");
WriteLine(" public override IEnumerable<NodeFilter> Filters");
WriteLine(" {");
WriteLine(" get");
WriteLine(" {");
WriteLine(" var filters = new List<NodeFilter>();");
foreach (var filter in filters)
{
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, type, propertyName);
WriteLine(" filters.Add(new NodeFilter");
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(string.Format(" Values = new List<object>"));
WriteLine(string.Format(" {{"));
for(int i = 0; i < filterValues.Count; i++)
{
string separator = "";
if (i != filterValues.Count - 1)
{
separator = ",";
}
var filterValue = filterValues[i];
WriteLine(string.Format(" {{ {0} }}{1}", filterValue.InnerText, separator ));
}
WriteLine(string.Format(" }}"));
}
WriteLine(" });");
}
WriteLine(" return filters;");
WriteLine(" }");
WriteLine(" }");
}
if (children.Count > 0) if (children.Count > 0)
{ {
WriteLine(""); WriteLine("");
@@ -179,10 +256,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ {
WriteLine(" var child = new SmoTreeNode();"); WriteLine(" var child = new SmoTreeNode();");
WriteLine(" child.IsAlwaysLeaf = true;"); WriteLine(" child.IsAlwaysLeaf = true;");
if (type.EndsWith("s"))
if (!string.IsNullOrEmpty(nodeType))
{ {
var typeName = type.Substring(0, type.Length - 1);
WriteLine(string.Format(" child.NodeType = \"{0}\";", typeName)); WriteLine(string.Format(" child.NodeType = \"{0}\";", nodeType));
} }
} }
@@ -200,6 +278,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
WriteLine(" child.SortPriority = SmoTreeNode.NextSortPriority;"); WriteLine(" child.SortPriority = SmoTreeNode.NextSortPriority;");
} }
WriteLine(" InitializeChild(child, context);"); WriteLine(" InitializeChild(child, context);");
WriteLine(" return child;"); WriteLine(" return child;");
WriteLine(" }"); WriteLine(" }");
} }
@@ -390,4 +470,42 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
} }
return retElements; return retElements;
} }
public static List<XmlElement> GetNodeFilters(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));
foreach (var item in nodeList)
{
XmlElement itemAsElement = item as XmlElement;
if (itemAsElement != null)
{
retElements.Add(itemAsElement);
}
}
return retElements;
}
public static List<XmlElement> GetNodeFilterValues(string xmlFile, string parentName, string filterProperty)
{
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));
foreach (var item in nodeList)
{
XmlElement itemAsElement = item as XmlElement;
if (itemAsElement != null)
{
retElements.Add(itemAsElement);
}
}
return retElements;
}
#> #>

View File

@@ -1,14 +1,15 @@
// //
// Copyright (c) Microsoft. All rights reserved. // Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
// //
using System;
using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts; using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
@@ -22,78 +23,95 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
{ {
private ObjectExplorerService _service = TestServiceProvider.Instance.ObjectExplorerService; private ObjectExplorerService _service = TestServiceProvider.Instance.ObjectExplorerService;
[Fact] [Fact]
public async void CreateSessionAndExpandOnTheServerShouldReturnServerAsTheRoot() public async void CreateSessionAndExpandOnTheServerShouldReturnServerAsTheRoot()
{ {
var query = ""; var query = "";
string uri = "CreateSessionAndExpandServer"; string uri = "CreateSessionAndExpandServer";
string databaseName = null; string databaseName = null;
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri)) using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
{ {
var session = await CreateSession(null, uri); var session = await CreateSession(null, uri);
await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session); await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session);
CancelConnection(uri);
} }
CancelConnection(uri);
} }
[Fact] [Fact]
public async void CreateSessionWithTempdbAndExpandOnTheServerShouldReturnServerAsTheRoot() public async void CreateSessionWithTempdbAndExpandOnTheServerShouldReturnServerAsTheRoot()
{ {
var query = ""; var query = "";
string uri = "CreateSessionAndExpandServer"; string uri = "CreateSessionAndExpandServer";
string databaseName = null; string databaseName = null;
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri)) using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
{ {
var session = await CreateSession("tempdb", uri); var session = await CreateSession("tempdb", uri);
await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session); await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session);
CancelConnection(uri);
} }
CancelConnection(uri);
} }
[Fact] [Fact]
public async void CreateSessionAndExpandOnTheDatabaseShouldReturnDatabaseAsTheRoot() public async void CreateSessionAndExpandOnTheDatabaseShouldReturnDatabaseAsTheRoot()
{ {
var query = ""; var query = "";
string uri = "CreateSessionAndExpandDatabase"; string uri = "CreateSessionAndExpandDatabase";
string databaseName = null; string databaseName = null;
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri)) using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
{ {
var session = await CreateSession(testDb.DatabaseName, uri); var session = await CreateSession(testDb.DatabaseName, uri);
ExpandAndVerifyDatabaseNode(testDb.DatabaseName, session); ExpandAndVerifyDatabaseNode(testDb.DatabaseName, session);
CancelConnection(uri);
} }
CancelConnection(uri);
} }
private async Task<ObjectExplorerSession> CreateSession(string databaseName, string uri) private async Task<ObjectExplorerSession> CreateSession(string databaseName, string uri)
{ {
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, databaseName); ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, databaseName);
connectParams.Connection.Pooling = false;
ConnectionDetails details = connectParams.Connection; ConnectionDetails details = connectParams.Connection;
return await _service.DoCreateSession(details, uri); var session = await _service.DoCreateSession(details, uri);
Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "OE session created for database: {0}", databaseName));
return session;
} }
private async Task<NodeInfo> ExpandServerNodeAndVerifyDatabaseHierachy(string databaseName, ObjectExplorerSession session) private async Task<NodeInfo> ExpandServerNodeAndVerifyDatabaseHierachy(string databaseName, ObjectExplorerSession session, bool serverNode = true)
{ {
Assert.NotNull(session); Assert.NotNull(session);
Assert.NotNull(session.Root); Assert.NotNull(session.Root);
NodeInfo nodeInfo = session.Root.ToNodeInfo(); NodeInfo nodeInfo = session.Root.ToNodeInfo();
Assert.Equal(nodeInfo.IsLeaf, false); Assert.Equal(nodeInfo.IsLeaf, false);
Assert.Equal(nodeInfo.NodeType, NodeTypes.Server.ToString());
var children = session.Root.Expand(); NodeInfo databaseNode = null;
//All server children should be folder nodes if (serverNode)
foreach (var item in children)
{ {
Assert.Equal(item.NodeType, "Folder"); Assert.Equal(nodeInfo.NodeType, NodeTypes.Server.ToString());
var children = session.Root.Expand();
//All server children should be folder nodes
foreach (var item in children)
{
Assert.Equal(item.NodeType, "Folder");
}
var databasesRoot = children.FirstOrDefault(x => x.NodeTypeId == NodeTypes.Databases);
var databasesChildren = await _service.ExpandNode(session, databasesRoot.GetNodePath());
var databases = databasesChildren.Where(x => x.NodeType == NodeTypes.Database.ToString());
//Verify the test databases is in the list
Assert.NotNull(databases);
databaseNode = databases.FirstOrDefault(d => d.Label == databaseName);
}
else
{
Assert.Equal(nodeInfo.NodeType, NodeTypes.Database.ToString());
databaseNode = session.Root.ToNodeInfo();
Assert.True(databaseNode.Label.Contains(databaseName));
} }
var databasesRoot = children.FirstOrDefault(x => x.NodeTypeId == NodeTypes.Databases);
var databasesChildren = await _service.ExpandNode(session, databasesRoot.GetNodePath());
var databases = databasesChildren.Where(x => x.NodeType == NodeTypes.Database.ToString());
//Verify the test databases is in the list
Assert.NotNull(databases);
var databaseNode = databases.FirstOrDefault(d => d.Label == databaseName);
Assert.NotNull(databaseNode); Assert.NotNull(databaseNode);
return databaseNode; return databaseNode;
} }
@@ -120,154 +138,212 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
private void CancelConnection(string uri) private void CancelConnection(string uri)
{ {
//ConnectionService.Instance.CancelConnect(new CancelConnectParams ConnectionService.Instance.CancelConnect(new CancelConnectParams
//{ {
// OwnerUri = uri, OwnerUri = uri,
// Type = ConnectionType.Default Type = ConnectionType.Default
//}); });
} }
private async Task ExpandTree(NodeInfo node, ObjectExplorerSession session) private async Task ExpandTree(NodeInfo node, ObjectExplorerSession session)
{ {
if(node != null && !node.IsLeaf) if (node != null && !node.IsLeaf)
{ {
var children = await _service.ExpandNode(session, node.NodePath); var children = await _service.ExpandNode(session, node.NodePath);
Assert.NotNull(children);
if(!node.NodePath.Contains("System") &&
!node.NodePath.Contains("FileTables") && !node.NodePath.Contains("External Tables"))
{
var labaleToUpper = node.Label.ToUpper();
foreach (var child in children)
{
if (child.NodeType != "Folder")
{
Assert.NotNull(child.NodeType);
if (child.Metadata != null && !string.IsNullOrEmpty(child.Metadata.MetadataTypeName))
{
if (!string.IsNullOrEmpty(child.Metadata.Schema))
{
Assert.Equal($"{child.Metadata.Schema}.{child.Metadata.Name}", child.Label);
}
else
{
Assert.Equal(child.Metadata.Name, child.Label);
}
}
else
{
}
}
}
}
foreach (var child in children) foreach (var child in children)
{ {
//Console.WriteLine(child.Label); await _service.ExpandNode(session, child.NodePath);
await ExpandTree(child, session);
} }
} }
} }
/// <summary>
/// Returns the children of a node with the given label
/// </summary>
private async Task<NodeInfo[]> FindNodeByLabel(NodeInfo node, ObjectExplorerSession session, string nodeType, bool nodeFound = false)
{
if (node != null && !node.IsLeaf)
{
var children = await _service.ExpandNode(session, node.NodePath);
Assert.NotNull(children);
if (!nodeFound)
{
foreach (var child in children)
{
VerifyMetadata(child);
if (child.Label == nodeType)
{
return await FindNodeByLabel(child, session, nodeType, true);
}
var result = await FindNodeByLabel(child, session, nodeType);
if (result != null)
{
return result;
}
}
}
else
{
return children;
}
}
return null;
}
private void VerifyMetadata(NodeInfo node)
{
if (node.NodeType != "Folder")
{
Assert.NotNull(node.NodeType);
if (node.Metadata != null && !string.IsNullOrEmpty(node.Metadata.MetadataTypeName))
{
if (!string.IsNullOrEmpty(node.Metadata.Schema))
{
Assert.Equal($"{node.Metadata.Schema}.{node.Metadata.Name}", node.Label);
}
else
{
Assert.Equal(node.Metadata.Name, node.Label);
}
}
}
}
[Fact] [Fact]
public async void VerifyAdventureWorksDatabaseObjects() public async void VerifyAdventureWorksDatabaseObjects()
{ {
var query = Scripts.AdventureWorksScript; var query = Scripts.AdventureWorksScript;
string uri = "VerifyAdventureWorksDatabaseObjects"; string uri = "VerifyAdventureWorksDatabaseObjects";
string databaseName = null; string databaseName = null;
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri)) using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, true, databaseName, query, uri))
{ {
var session = await CreateSession(null, uri); var session = await CreateSession(testDb.DatabaseName, queryTempFile.FilePath);
var databaseNodeInfo = await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session); var databaseNodeInfo = await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session, false);
await ExpandTree(databaseNodeInfo, session); await ExpandTree(session.Root.ToNodeInfo(), session);
CancelConnection(uri); var tablesChildren = await FindNodeByLabel(databaseNodeInfo, session, SR.SchemaHierarchy_Tables);
var systemTables = await FindNodeByLabel(databaseNodeInfo, session, SR.SchemaHierarchy_SystemTables);
Assert.True(!systemTables.Any());
var externalTables = await FindNodeByLabel(databaseNodeInfo, session, SR.SchemaHierarchy_ExternalTables);
Assert.True(!externalTables.Any());
var fileTables = await FindNodeByLabel(databaseNodeInfo, session, SR.SchemaHierarchy_FileTables);
Assert.True(!fileTables.Any());
var allTables = tablesChildren.Where(x => x.NodeType != NodeTypes.Folder.ToString());
Assert.True(allTables.Any());
var storedProcedures = await FindNodeByLabel(databaseNodeInfo, session, SR.SchemaHierarchy_StoredProcedures);
Assert.True(storedProcedures.Any());
var views = await FindNodeByLabel(databaseNodeInfo, session, SR.SchemaHierarchy_Views);
Assert.True(views.Any());
var userDefinedDataTypes = await FindNodeByLabel(databaseNodeInfo, session, SR.SchemaHierarchy_UserDefinedDataTypes);
Assert.True(userDefinedDataTypes.Any());
var scalarValuedFunctions = await FindNodeByLabel(databaseNodeInfo, session, SR.SchemaHierarchy_ScalarValuedFunctions);
Assert.True(scalarValuedFunctions.Any());
} }
CancelConnection(uri);
} }
// [Fact] // [Fact]
public async void VerifySql2016Objects() public async void VerifySql2016Objects()
{ {
var query = LoadScript("Sql_2016_Additions.sql"); var query = LoadScript("Sql_2016_Additions.sql");
string uri = "VerifySql2016Objects"; string uri = "VerifySql2016Objects";
string databaseName = null; string databaseName = null;
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri)) using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
{ {
var session = await CreateSession(testDb.DatabaseName, uri); var session = await CreateSession(testDb.DatabaseName, uri);
var databaseNodeInfo = await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session); var databaseNodeInfo = await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session);
await ExpandTree(databaseNodeInfo, session); await FindNodeByLabel(databaseNodeInfo, session, SR.SchemaHierarchy_Tables);
CancelConnection(uri);
} }
CancelConnection(uri);
} }
// [Fact] // [Fact]
public async void VerifySqlObjects() public async void VerifySqlObjects()
{ {
var query = LoadScript("Sql_Additions.sql"); var query = LoadScript("Sql_Additions.sql");
string uri = "VerifySqlObjects"; string uri = "VerifySqlObjects";
string databaseName = null; string databaseName = null;
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri)) using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
{ {
var session = await CreateSession(testDb.DatabaseName, uri); var session = await CreateSession(testDb.DatabaseName, uri);
var databaseNodeInfo = await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session); var databaseNodeInfo = await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session);
await ExpandTree(databaseNodeInfo, session); await FindNodeByLabel(databaseNodeInfo, session, SR.SchemaHierarchy_Tables);
CancelConnection(uri);
} }
CancelConnection(uri);
} }
// [Fact] // [Fact]
public async void VerifyFileTableTest() public async void VerifyFileTableTest()
{ {
var query = LoadScript("FileTableTest.sql"); var query = LoadScript("FileTableTest.sql");
string uri = "VerifyFileTableTest"; string uri = "VerifyFileTableTest";
string databaseName = null; string databaseName = null;
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri)) using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
{ {
var session = await CreateSession(testDb.DatabaseName, uri); var session = await CreateSession(testDb.DatabaseName, uri);
var databaseNodeInfo = await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session); var databaseNodeInfo = await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session);
await ExpandTree(databaseNodeInfo, session); await FindNodeByLabel(databaseNodeInfo, session, SR.SchemaHierarchy_Tables);
CancelConnection(uri);
} }
CancelConnection(uri);
} }
//[Fact] //[Fact]
public async void VerifyColumnstoreindexSql16() public async void VerifyColumnstoreindexSql16()
{ {
var query = LoadScript("ColumnstoreindexSql16.sql"); var query = LoadScript("ColumnstoreindexSql16.sql");
string uri = "VerifyColumnstoreindexSql16"; string uri = "VerifyColumnstoreindexSql16";
string databaseName = null; string databaseName = null;
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri)) using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
{ {
var session = await CreateSession(testDb.DatabaseName, uri); var session = await CreateSession(testDb.DatabaseName, uri);
var databaseNodeInfo = await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session); var databaseNodeInfo = await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session);
await ExpandTree(databaseNodeInfo, session); await FindNodeByLabel(databaseNodeInfo, session, SR.SchemaHierarchy_Tables);
CancelConnection(uri); }
CancelConnection(uri);
}
private static string TestLocationDirectory
{
get
{
return Path.Combine(RunEnvironmentInfo.GetTestDataLocation(), "ObjectExplorer");
} }
} }
private static string TestLocationDirectory public DirectoryInfo InputFileDirectory
{ {
get get
{ {
return Path.Combine(RunEnvironmentInfo.GetTestDataLocation(), "ObjectExplorer"); string d = Path.Combine(TestLocationDirectory, "TestScripts");
} return new DirectoryInfo(d);
}
} }
public DirectoryInfo InputFileDirectory public FileInfo GetInputFile(string fileName)
{ {
get return new FileInfo(Path.Combine(InputFileDirectory.FullName, fileName));
{
string d = Path.Combine(TestLocationDirectory, "TestScripts");
return new DirectoryInfo(d);
}
}
public FileInfo GetInputFile(string fileName)
{
return new FileInfo(Path.Combine(InputFileDirectory.FullName, fileName));
} }
private string LoadScript(string fileName) private string LoadScript(string fileName)

View File

@@ -113,12 +113,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
{ {
if (!DoNotCleanupDb) if (!DoNotCleanupDb)
{ {
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) string dropDatabaseQuery = string.Format(CultureInfo.InvariantCulture,
{
string dropDatabaseQuery = string.Format(CultureInfo.InvariantCulture,
(ServerType == TestServerType.Azure ? Scripts.DropDatabaseIfExistAzure : Scripts.DropDatabaseIfExist), DatabaseName); (ServerType == TestServerType.Azure ? Scripts.DropDatabaseIfExistAzure : Scripts.DropDatabaseIfExist), DatabaseName);
TestServiceProvider.Instance.RunQuery(ServerType, MasterDatabaseName, dropDatabaseQuery);
} Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Cleaning up database {0}", DatabaseName));
TestServiceProvider.Instance.RunQuery(ServerType, MasterDatabaseName, dropDatabaseQuery);
} }
} }

View File

@@ -184,6 +184,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
connectParams.Connection.DatabaseName = connectionProfile.Database; connectParams.Connection.DatabaseName = connectionProfile.Database;
connectParams.Connection.UserName = connectionProfile.User; connectParams.Connection.UserName = connectionProfile.User;
connectParams.Connection.Password = connectionProfile.Password; connectParams.Connection.Password = connectionProfile.Password;
connectParams.Connection.MaxPoolSize = 200;
connectParams.Connection.AuthenticationType = connectionProfile.AuthenticationType.ToString(); connectParams.Connection.AuthenticationType = connectionProfile.AuthenticationType.ToString();
if (!string.IsNullOrEmpty(databaseName)) if (!string.IsNullOrEmpty(databaseName))
{ {

View File

@@ -1,369 +1,369 @@
// //
// Copyright (c) Microsoft. All rights reserved. // Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
// //
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data.SqlClient; using System.Data.SqlClient;
using System.Globalization; using System.Globalization;
using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.Extensibility; using Microsoft.SqlTools.Extensibility;
using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts; using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel;
using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility; using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility;
using Moq; using Moq;
using Xunit; using Xunit;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer
{ {
/// <summary> /// <summary>
/// Tests covering basic operation of Node based classes /// Tests covering basic operation of Node based classes
/// </summary> /// </summary>
public class NodeTests : ObjectExplorerTestBase public class NodeTests : ObjectExplorerTestBase
{ {
private string defaultOwnerUri = "objectexplorer://myserver"; private string defaultOwnerUri = "objectexplorer://myserver";
private ServerInfo defaultServerInfo; private ServerInfo defaultServerInfo;
private ConnectionDetails defaultConnectionDetails; private ConnectionDetails defaultConnectionDetails;
private ConnectionCompleteParams defaultConnParams; private ConnectionCompleteParams defaultConnParams;
private string fakeConnectionString = "Data Source=server;Initial Catalog=database;Integrated Security=False;User Id=user"; private string fakeConnectionString = "Data Source=server;Initial Catalog=database;Integrated Security=False;User Id=user";
public NodeTests() public NodeTests()
{ {
defaultServerInfo = TestObjects.GetTestServerInfo(); defaultServerInfo = TestObjects.GetTestServerInfo();
defaultConnectionDetails = new ConnectionDetails() defaultConnectionDetails = new ConnectionDetails()
{ {
DatabaseName = "master", DatabaseName = "master",
ServerName = "localhost", ServerName = "localhost",
UserName = "serverAdmin", UserName = "serverAdmin",
Password = "..." Password = "..."
}; };
defaultConnParams = new ConnectionCompleteParams() defaultConnParams = new ConnectionCompleteParams()
{ {
ServerInfo = defaultServerInfo, ServerInfo = defaultServerInfo,
ConnectionSummary = defaultConnectionDetails, ConnectionSummary = defaultConnectionDetails,
OwnerUri = defaultOwnerUri OwnerUri = defaultOwnerUri
}; };
// TODO can all tests use the standard service provider? // TODO can all tests use the standard service provider?
ServiceProvider = ExtensionServiceProvider.CreateDefaultServiceProvider(); ServiceProvider = ExtensionServiceProvider.CreateDefaultServiceProvider();
} }
[Fact] [Fact]
public void ServerNodeConstructorValidatesFields() public void ServerNodeConstructorValidatesFields()
{ {
Assert.Throws<ArgumentNullException>(() => new ServerNode(null, ServiceProvider)); Assert.Throws<ArgumentNullException>(() => new ServerNode(null, ServiceProvider));
Assert.Throws<ArgumentNullException>(() => new ServerNode(defaultConnParams, null)); Assert.Throws<ArgumentNullException>(() => new ServerNode(defaultConnParams, null));
} }
[Fact] [Fact]
public void ServerNodeConstructorShouldSetValuesCorrectly() public void ServerNodeConstructorShouldSetValuesCorrectly()
{ {
// Given a server node with valid inputs // Given a server node with valid inputs
ServerNode node = new ServerNode(defaultConnParams, ServiceProvider); ServerNode node = new ServerNode(defaultConnParams, ServiceProvider);
// Then expect all fields set correctly // Then expect all fields set correctly
Assert.False(node.IsAlwaysLeaf, "Server node should never be a leaf"); Assert.False(node.IsAlwaysLeaf, "Server node should never be a leaf");
Assert.Equal(defaultConnectionDetails.ServerName, node.NodeValue); Assert.Equal(defaultConnectionDetails.ServerName, node.NodeValue);
string expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + " - " string expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + " - "
+ defaultConnectionDetails.UserName + ")"; + defaultConnectionDetails.UserName + ")";
Assert.Equal(expectedLabel, node.Label); Assert.Equal(expectedLabel, node.Label);
Assert.Equal(NodeTypes.Server.ToString(), node.NodeType); Assert.Equal(NodeTypes.Server.ToString(), node.NodeType);
string[] nodePath = node.GetNodePath().Split(TreeNode.PathPartSeperator); string[] nodePath = node.GetNodePath().Split(TreeNode.PathPartSeperator);
Assert.Equal(1, nodePath.Length); Assert.Equal(1, nodePath.Length);
Assert.Equal(defaultConnectionDetails.ServerName, nodePath[0]); Assert.Equal(defaultConnectionDetails.ServerName, nodePath[0]);
} }
[Fact] [Fact]
public void ServerNodeLabelShouldIgnoreUserNameIfEmptyOrNull() public void ServerNodeLabelShouldIgnoreUserNameIfEmptyOrNull()
{ {
// Given no username set // Given no username set
ConnectionSummary integratedAuthSummary = new ConnectionSummary() ConnectionSummary integratedAuthSummary = new ConnectionSummary()
{ {
DatabaseName = defaultConnectionDetails.DatabaseName, DatabaseName = defaultConnectionDetails.DatabaseName,
ServerName = defaultConnectionDetails.ServerName, ServerName = defaultConnectionDetails.ServerName,
UserName = null UserName = null
}; };
ConnectionCompleteParams connParams = new ConnectionCompleteParams() ConnectionCompleteParams connParams = new ConnectionCompleteParams()
{ {
ConnectionSummary = integratedAuthSummary, ConnectionSummary = integratedAuthSummary,
ServerInfo = defaultServerInfo, ServerInfo = defaultServerInfo,
OwnerUri = defaultOwnerUri OwnerUri = defaultOwnerUri
}; };
// When querying label // When querying label
string label = new ServerNode(connParams, ServiceProvider).Label; string label = new ServerNode(connParams, ServiceProvider).Label;
// Then only server name and version shown // Then only server name and version shown
string expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + ")"; string expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + ")";
Assert.Equal(expectedLabel, label); Assert.Equal(expectedLabel, label);
} }
[Fact] [Fact]
public void ServerNodeConstructorShouldShowDbNameForCloud() public void ServerNodeConstructorShouldShowDbNameForCloud()
{ {
defaultServerInfo.IsCloud = true; defaultServerInfo.IsCloud = true;
// Given a server node for a cloud DB, with master name // Given a server node for a cloud DB, with master name
ServerNode node = new ServerNode(defaultConnParams, ServiceProvider); ServerNode node = new ServerNode(defaultConnParams, ServiceProvider);
// Then expect label to not include db name // Then expect label to not include db name
string expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + " - " string expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + " - "
+ defaultConnectionDetails.UserName + ")"; + defaultConnectionDetails.UserName + ")";
Assert.Equal(expectedLabel, node.Label); Assert.Equal(expectedLabel, node.Label);
// But given a server node for a cloud DB that's not master // But given a server node for a cloud DB that's not master
defaultConnectionDetails.DatabaseName = "NotMaster"; defaultConnectionDetails.DatabaseName = "NotMaster";
node = new ServerNode(defaultConnParams, ServiceProvider); node = new ServerNode(defaultConnParams, ServiceProvider);
// Then expect label to include db name // Then expect label to include db name
expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + " - " expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + " - "
+ defaultConnectionDetails.UserName + ", " + defaultConnectionDetails.DatabaseName + ")"; + defaultConnectionDetails.UserName + ", " + defaultConnectionDetails.DatabaseName + ")";
Assert.Equal(expectedLabel, node.Label); Assert.Equal(expectedLabel, node.Label);
} }
[Fact] [Fact]
public void ToNodeInfoIncludeAllFields() public void ToNodeInfoIncludeAllFields()
{ {
// Given a server connection // Given a server connection
ServerNode node = new ServerNode(defaultConnParams, ServiceProvider); ServerNode node = new ServerNode(defaultConnParams, ServiceProvider);
// When converting to NodeInfo // When converting to NodeInfo
NodeInfo info = node.ToNodeInfo(); NodeInfo info = node.ToNodeInfo();
// Then all fields should match // Then all fields should match
Assert.Equal(node.IsAlwaysLeaf, info.IsLeaf); Assert.Equal(node.IsAlwaysLeaf, info.IsLeaf);
Assert.Equal(node.Label, info.Label); Assert.Equal(node.Label, info.Label);
Assert.Equal(node.NodeType, info.NodeType); Assert.Equal(node.NodeType, info.NodeType);
string[] nodePath = node.GetNodePath().Split(TreeNode.PathPartSeperator); string[] nodePath = node.GetNodePath().Split(TreeNode.PathPartSeperator);
string[] nodeInfoPathParts = info.NodePath.Split(TreeNode.PathPartSeperator); string[] nodeInfoPathParts = info.NodePath.Split(TreeNode.PathPartSeperator);
Assert.Equal(nodePath.Length, nodeInfoPathParts.Length); Assert.Equal(nodePath.Length, nodeInfoPathParts.Length);
for (int i = 0; i < nodePath.Length; i++) for (int i = 0; i < nodePath.Length; i++)
{ {
Assert.Equal(nodePath[i], nodeInfoPathParts[i]); Assert.Equal(nodePath[i], nodeInfoPathParts[i]);
} }
} }
[Fact] [Fact]
public void AddChildShouldSetParent() public void AddChildShouldSetParent()
{ {
TreeNode parent = new TreeNode("parent"); TreeNode parent = new TreeNode("parent");
TreeNode child = new TreeNode("child"); TreeNode child = new TreeNode("child");
Assert.Null(child.Parent); Assert.Null(child.Parent);
parent.AddChild(child); parent.AddChild(child);
Assert.Equal(parent, child.Parent); Assert.Equal(parent, child.Parent);
} }
[Fact] [Fact]
public void GetChildrenShouldReturnReadonlyList() public void GetChildrenShouldReturnReadonlyList()
{ {
TreeNode node = new TreeNode("parent"); TreeNode node = new TreeNode("parent");
IList<TreeNode> children = node.GetChildren(); IList<TreeNode> children = node.GetChildren();
Assert.Throws<NotSupportedException>(() => children.Add(new TreeNode("child"))); Assert.Throws<NotSupportedException>(() => children.Add(new TreeNode("child")));
} }
[Fact] [Fact]
public void GetChildrenShouldReturnAddedNodesInOrder() public void GetChildrenShouldReturnAddedNodesInOrder()
{ {
TreeNode parent = new TreeNode("parent"); TreeNode parent = new TreeNode("parent");
TreeNode[] expectedKids = new TreeNode[] { new TreeNode("1"), new TreeNode("2") }; TreeNode[] expectedKids = new TreeNode[] { new TreeNode("1"), new TreeNode("2") };
foreach (TreeNode child in expectedKids) foreach (TreeNode child in expectedKids)
{ {
parent.AddChild(child); parent.AddChild(child);
} }
IList<TreeNode> children = parent.GetChildren(); IList<TreeNode> children = parent.GetChildren();
Assert.Equal(expectedKids.Length, children.Count); Assert.Equal(expectedKids.Length, children.Count);
for (int i = 0; i < expectedKids.Length; i++) for (int i = 0; i < expectedKids.Length; i++)
{ {
Assert.Equal(expectedKids[i], children[i]); Assert.Equal(expectedKids[i], children[i]);
} }
} }
public void MultiLevelTreeShouldFormatPath() public void MultiLevelTreeShouldFormatPath()
{ {
TreeNode root = new TreeNode("root"); TreeNode root = new TreeNode("root");
Assert.Equal("/root" , root.GetNodePath()); Assert.Equal("/root" , root.GetNodePath());
TreeNode level1Child1 = new TreeNode("L1C1"); TreeNode level1Child1 = new TreeNode("L1C1");
TreeNode level1Child2 = new TreeNode("L1C2"); TreeNode level1Child2 = new TreeNode("L1C2");
root.AddChild(level1Child1); root.AddChild(level1Child1);
root.AddChild(level1Child2); root.AddChild(level1Child2);
Assert.Equal("/root/L1C1" , level1Child1.GetNodePath()); Assert.Equal("/root/L1C1" , level1Child1.GetNodePath());
Assert.Equal("/root/L1C2", level1Child2.GetNodePath()); Assert.Equal("/root/L1C2", level1Child2.GetNodePath());
TreeNode level2Child1 = new TreeNode("L2C2"); TreeNode level2Child1 = new TreeNode("L2C2");
level1Child1.AddChild(level2Child1); level1Child1.AddChild(level2Child1);
Assert.Equal("/root/L1C1/L2C2", level2Child1.GetNodePath()); Assert.Equal("/root/L1C1/L2C2", level2Child1.GetNodePath());
} }
[Fact] [Fact]
public void ServerNodeContextShouldIncludeServer() public void ServerNodeContextShouldIncludeServer()
{ {
// given a successful Server creation // given a successful Server creation
SetupAndRegisterTestConnectionService(); SetupAndRegisterTestConnectionService();
Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString))); Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString)));
ServerNode node = SetupServerNodeWithServer(smoServer); ServerNode node = SetupServerNodeWithServer(smoServer);
// When I get the context for a ServerNode // When I get the context for a ServerNode
var context = node.GetContextAs<SmoQueryContext>(); var context = node.GetContextAs<SmoQueryContext>();
// Then I expect it to contain the server I created // Then I expect it to contain the server I created
Assert.NotNull(context); Assert.NotNull(context);
Assert.Equal(smoServer, context.Server); Assert.Equal(smoServer, context.Server);
// And the server should be the parent // And the server should be the parent
Assert.Equal(smoServer, context.Parent); Assert.Equal(smoServer, context.Parent);
Assert.Null(context.Database); Assert.Null(context.Database);
} }
[Fact] [Fact]
public void ServerNodeContextShouldSetErrorMessageIfSqlConnectionIsNull() public void ServerNodeContextShouldSetErrorMessageIfSqlConnectionIsNull()
{ {
// given a connectionInfo with no SqlConnection to use for queries // given a connectionInfo with no SqlConnection to use for queries
ConnectionService connService = SetupAndRegisterTestConnectionService(); ConnectionService connService = SetupAndRegisterTestConnectionService();
connService.OwnerToConnectionMap.Remove(defaultOwnerUri); connService.OwnerToConnectionMap.Remove(defaultOwnerUri);
Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString))); Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString)));
ServerNode node = SetupServerNodeWithServer(smoServer); ServerNode node = SetupServerNodeWithServer(smoServer);
// When I get the context for a ServerNode // When I get the context for a ServerNode
var context = node.GetContextAs<SmoQueryContext>(); var context = node.GetContextAs<SmoQueryContext>();
// Then I expect it to be in an error state // Then I expect it to be in an error state
Assert.Null(context); Assert.Null(context);
Assert.Equal( Assert.Equal(
string.Format(CultureInfo.CurrentCulture, SR.ServerNodeConnectionError, defaultConnectionDetails.ServerName), string.Format(CultureInfo.CurrentCulture, SR.ServerNodeConnectionError, defaultConnectionDetails.ServerName),
node.ErrorStateMessage); node.ErrorStateMessage);
} }
[Fact] [Fact]
public void ServerNodeContextShouldSetErrorMessageIfConnFailureExceptionThrown() public void ServerNodeContextShouldSetErrorMessageIfConnFailureExceptionThrown()
{ {
// given a connectionInfo with no SqlConnection to use for queries // given a connectionInfo with no SqlConnection to use for queries
SetupAndRegisterTestConnectionService(); SetupAndRegisterTestConnectionService();
Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString))); Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString)));
string expectedMsg = "ConnFailed!"; string expectedMsg = "ConnFailed!";
ServerNode node = SetupServerNodeWithExceptionCreator(new ConnectionFailureException(expectedMsg)); ServerNode node = SetupServerNodeWithExceptionCreator(new ConnectionFailureException(expectedMsg));
// When I get the context for a ServerNode // When I get the context for a ServerNode
var context = node.GetContextAs<SmoQueryContext>(); var context = node.GetContextAs<SmoQueryContext>();
// Then I expect it to be in an error state // Then I expect it to be in an error state
Assert.Null(context); Assert.Null(context);
Assert.Equal( Assert.Equal(
string.Format(CultureInfo.CurrentCulture, SR.TreeNodeError, expectedMsg), string.Format(CultureInfo.CurrentCulture, SR.TreeNodeError, expectedMsg),
node.ErrorStateMessage); node.ErrorStateMessage);
} }
[Fact] [Fact]
public void ServerNodeContextShouldSetErrorMessageIfExceptionThrown() public void ServerNodeContextShouldSetErrorMessageIfExceptionThrown()
{ {
// given a connectionInfo with no SqlConnection to use for queries // given a connectionInfo with no SqlConnection to use for queries
SetupAndRegisterTestConnectionService(); SetupAndRegisterTestConnectionService();
Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString))); Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString)));
string expectedMsg = "Failed!"; string expectedMsg = "Failed!";
ServerNode node = SetupServerNodeWithExceptionCreator(new Exception(expectedMsg)); ServerNode node = SetupServerNodeWithExceptionCreator(new Exception(expectedMsg));
// When I get the context for a ServerNode // When I get the context for a ServerNode
var context = node.GetContextAs<SmoQueryContext>(); var context = node.GetContextAs<SmoQueryContext>();
// Then I expect it to be in an error state // Then I expect it to be in an error state
Assert.Null(context); Assert.Null(context);
Assert.Equal( Assert.Equal(
string.Format(CultureInfo.CurrentCulture, SR.TreeNodeError, expectedMsg), string.Format(CultureInfo.CurrentCulture, SR.TreeNodeError, expectedMsg),
node.ErrorStateMessage); node.ErrorStateMessage);
} }
private ConnectionService SetupAndRegisterTestConnectionService() private ConnectionService SetupAndRegisterTestConnectionService()
{ {
ConnectionService connService = TestObjects.GetTestConnectionService(); ConnectionService connService = TestObjects.GetTestConnectionService();
ConnectionInfo connectionInfo = new ConnectionInfo(TestObjects.GetTestSqlConnectionFactory(), ConnectionInfo connectionInfo = new ConnectionInfo(TestObjects.GetTestSqlConnectionFactory(),
defaultOwnerUri, defaultConnectionDetails); defaultOwnerUri, defaultConnectionDetails);
connectionInfo.AddConnection("Default", new SqlConnection()); connectionInfo.AddConnection("Default", new SqlConnection());
connService.OwnerToConnectionMap.Add(defaultOwnerUri, connectionInfo); connService.OwnerToConnectionMap.Add(defaultOwnerUri, connectionInfo);
ServiceProvider.RegisterSingleService(connService); ServiceProvider.RegisterSingleService(connService);
return connService; return connService;
} }
private ServerNode SetupServerNodeWithServer(Server smoServer) private ServerNode SetupServerNodeWithServer(Server smoServer)
{ {
Mock<SmoServerCreator> creator = new Mock<SmoServerCreator>(); Mock<SmoServerCreator> creator = new Mock<SmoServerCreator>();
creator.Setup(c => c.Create(It.IsAny<SqlConnection>())) creator.Setup(c => c.Create(It.IsAny<SqlConnection>()))
.Returns(() => smoServer); .Returns(() => smoServer);
ServerNode node = SetupServerNodeWithCreator(creator.Object); ServerNode node = SetupServerNodeWithCreator(creator.Object);
return node; return node;
} }
private ServerNode SetupServerNodeWithExceptionCreator(Exception ex) private ServerNode SetupServerNodeWithExceptionCreator(Exception ex)
{ {
Mock<SmoServerCreator> creator = new Mock<SmoServerCreator>(); Mock<SmoServerCreator> creator = new Mock<SmoServerCreator>();
creator.Setup(c => c.Create(It.IsAny<SqlConnection>())) creator.Setup(c => c.Create(It.IsAny<SqlConnection>()))
.Throws(ex); .Throws(ex);
ServerNode node = SetupServerNodeWithCreator(creator.Object); ServerNode node = SetupServerNodeWithCreator(creator.Object);
return node; return node;
} }
private ServerNode SetupServerNodeWithCreator(SmoServerCreator creator) private ServerNode SetupServerNodeWithCreator(SmoServerCreator creator)
{ {
ServerNode node = new ServerNode(defaultConnParams, ServiceProvider); ServerNode node = new ServerNode(defaultConnParams, ServiceProvider);
node.ServerCreator = creator; node.ServerCreator = creator;
return node; return node;
} }
[Fact] [Fact]
public void ServerNodeChildrenShouldIncludeFoldersAndDatabases() public void ServerNodeChildrenShouldIncludeFoldersAndDatabases()
{ {
// Given a server with 1 database // Given a server with 1 database
SetupAndRegisterTestConnectionService(); SetupAndRegisterTestConnectionService();
ServiceProvider.RegisterSingleService(new ObjectExplorerService()); ServiceProvider.RegisterSingleService(new ObjectExplorerService());
string dbName = "DB1"; string dbName = "DB1";
Mock<NamedSmoObject> smoObjectMock = new Mock<NamedSmoObject>(); Mock<NamedSmoObject> smoObjectMock = new Mock<NamedSmoObject>();
smoObjectMock.SetupGet(s => s.Name).Returns(dbName); smoObjectMock.SetupGet(s => s.Name).Returns(dbName);
Mock<SqlDatabaseQuerier> querierMock = new Mock<SqlDatabaseQuerier>(); Mock<SqlDatabaseQuerier> querierMock = new Mock<SqlDatabaseQuerier>();
querierMock.Setup(q => q.Query(It.IsAny<SmoQueryContext>())) querierMock.Setup(q => q.Query(It.IsAny<SmoQueryContext>(), ""))
.Returns(smoObjectMock.Object.SingleItemAsEnumerable()); .Returns(smoObjectMock.Object.SingleItemAsEnumerable());
ServiceProvider.Register<SmoQuerier>(() => new[] { querierMock.Object }); ServiceProvider.Register<SmoQuerier>(() => new[] { querierMock.Object });
Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString))); Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString)));
ServerNode node = SetupServerNodeWithServer(smoServer); ServerNode node = SetupServerNodeWithServer(smoServer);
// When I populate its children // When I populate its children
IList<TreeNode> children = node.Expand(); IList<TreeNode> children = node.Expand();
// Then I expect it to contain server-level folders // Then I expect it to contain server-level folders
Assert.Equal(3, children.Count); Assert.Equal(3, children.Count);
VerifyTreeNode<FolderNode>(children[0], "Folder", SR.SchemaHierarchy_Databases); VerifyTreeNode<FolderNode>(children[0], "Folder", SR.SchemaHierarchy_Databases);
VerifyTreeNode<FolderNode>(children[1], "Folder", SR.SchemaHierarchy_Security); VerifyTreeNode<FolderNode>(children[1], "Folder", SR.SchemaHierarchy_Security);
VerifyTreeNode<FolderNode>(children[2], "Folder", SR.SchemaHierarchy_ServerObjects); VerifyTreeNode<FolderNode>(children[2], "Folder", SR.SchemaHierarchy_ServerObjects);
// And the database is contained under it // And the database is contained under it
TreeNode databases = children[0]; TreeNode databases = children[0];
IList<TreeNode> dbChildren = databases.Expand(); IList<TreeNode> dbChildren = databases.Expand();
Assert.Equal(2, dbChildren.Count); Assert.Equal(2, dbChildren.Count);
Assert.Equal(SR.SchemaHierarchy_SystemDatabases, dbChildren[0].NodeValue); Assert.Equal(SR.SchemaHierarchy_SystemDatabases, dbChildren[0].NodeValue);
TreeNode dbNode = dbChildren[1]; TreeNode dbNode = dbChildren[1];
Assert.Equal(dbName, dbNode.NodeValue); Assert.Equal(dbName, dbNode.NodeValue);
Assert.Equal(dbName, dbNode.Label); Assert.Equal(dbName, dbNode.Label);
Assert.False(dbNode.IsAlwaysLeaf); Assert.False(dbNode.IsAlwaysLeaf);
// Note: would like to verify Database in the context, but cannot since it's a Sealed class and isn't easily mockable // Note: would like to verify Database in the context, but cannot since it's a Sealed class and isn't easily mockable
} }
private void VerifyTreeNode<T>(TreeNode node, string nodeType, string folderValue) private void VerifyTreeNode<T>(TreeNode node, string nodeType, string folderValue)
where T : TreeNode where T : TreeNode
{ {
T nodeAsT = node as T; T nodeAsT = node as T;
Assert.NotNull(nodeAsT); Assert.NotNull(nodeAsT);
Assert.Equal(nodeType, nodeAsT.NodeType); Assert.Equal(nodeType, nodeAsT.NodeType);
Assert.Equal(folderValue, nodeAsT.NodeValue); Assert.Equal(folderValue, nodeAsT.NodeValue);
} }
} }
} }