diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/ChildFactory.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/ChildFactory.cs index cb412d79..95b3c4da 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/ChildFactory.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/ChildFactory.cs @@ -29,6 +29,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes /// public abstract IEnumerable Expand(TreeNode parent); + /// + /// The list of filters that should be applied on the smo object list + /// + public abstract IEnumerable Filters { get; } + public abstract bool CanCreateChild(TreeNode parent, object context); public abstract TreeNode CreateChild(TreeNode parent, object context); diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodeFilter.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodeFilter.cs new file mode 100644 index 00000000..0c101c04 --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodeFilter.cs @@ -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 +{ + /// + /// Has information for filtering a SMO object by properties + /// + public class NodeFilter + { + /// + /// Property name + /// + public string Property { get; set; } + + /// + /// Filter values + /// + public List Values { get; set; } + + /// + /// Type of the filter values + /// + public Type Type { get; set; } + + /// + /// Indicates which platforms a filter is valid for + /// + public ValidForFlag ValidFor { get; set; } + + /// + /// The type of the Querier the filter can be applied to + /// + public Type TypeToReverse { get; set; } + + /// + /// Returns true if the filter can be apply to the given type and Server type + /// + /// Type of the querier + /// Server Type + /// + public bool CanApplyFilter(Type type, ValidForFlag validForFlag) + { + bool canApplyFilter = false; + canApplyFilter = TypeToReverse == null || TypeToReverse == type; + canApplyFilter = canApplyFilter && (ValidFor == 0 || ValidFor.HasFlag(validForFlag)); + + return canApplyFilter; + } + + /// + /// 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] + /// + /// + public string ToPropertyFilterString() + { + string filter = ""; + List 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; + } + } +} diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodeTypes.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodeTypes.cs index 10812a95..2f089dd7 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodeTypes.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodeTypes.cs @@ -24,6 +24,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes View, Table, HistoryTable, + Folder, Databases, ExternalResources, ServerLevelSecurity, diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/SqlServerType.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/SqlServerType.cs new file mode 100644 index 00000000..7b7f7eaf --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/SqlServerType.cs @@ -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 +{ + /// + /// Server Types + /// + public enum SqlServerType + { + Unknown, + Sql2005, + Sql2008, + Sql2012, + Sql2014, + Sql2016, + Azure, + AzureV12 + } + + /// + /// Includes helper functions for server version and type + /// + public class ServerVersionHelper + { + /// + /// Converts a server type to ValidForFlag + /// + public static ValidForFlag GetValidForFlag(SqlServerType serverType) + { + ValidForFlag validforFlag = ValidForFlag.All; + if (Enum.TryParse(serverType.ToString(), out validforFlag)) + { + return validforFlag; + } + return ValidForFlag.All; + } + + /// + /// Creates a server type from the server version + /// + 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; + } + } +} diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/ServerNode.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/ServerNode.cs index 0cf839ad..208930ea 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/ServerNode.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/ServerNode.cs @@ -31,6 +31,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel private Lazy context; private ConnectionService connectionService; private SmoServerCreator serverCreator; + private SqlServerType sqlServerType; public ServerNode(ConnectionCompleteParams connInfo, IMultiServiceProvider serviceProvider) : base() @@ -42,6 +43,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel this.connectionSummary = connInfo.ConnectionSummary; this.serverInfo = connInfo.ServerInfo; this.connectionUri = connInfo.OwnerUri; + this.sqlServerType = ServerVersionHelper.CalculateServerType(this.serverInfo); this.connectionService = serviceProvider.GetService(); @@ -123,6 +125,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel return label; } + + private SmoQueryContext CreateContext(IMultiServiceProvider serviceProvider) { string exceptionMessage; @@ -160,7 +164,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Server server = ServerCreator.Create(connection); return new SmoQueryContext(server, serviceProvider) { - Parent = server + Parent = server, + SqlServerType = this.sqlServerType }; } catch (ConnectionFailureException cfe) diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoChildFactoryBase.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoChildFactoryBase.cs index 6aa7a072..89b9641d 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoChildFactoryBase.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoChildFactoryBase.cs @@ -1,133 +1,169 @@ -// -// 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; +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System; +using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Reflection; -using Microsoft.SqlServer.Management.Smo; -using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; -using Microsoft.SqlTools.ServiceLayer.Utility; +using System.Linq; +using System.Reflection; +using Microsoft.SqlServer.Management.Smo; +using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; using Microsoft.SqlTools.Utility; -namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel -{ - public class SmoChildFactoryBase : ChildFactory - { - public override IEnumerable ApplicableParents() - { - return null; - } - - public override IEnumerable Expand(TreeNode parent) - { - //parent.BeginChildrenInit(); - try - { - List allChildren = new List(); - OnExpandPopulateFolders(allChildren, parent); - RemoveFoldersFromInvalidSqlServerVersions(allChildren, parent); - OnExpandPopulateNonFolders(allChildren, parent); - OnBeginAsyncOperations(parent); - return allChildren; - } - finally - { - //parent.EndChildrenInit(); - } - } - - /// - /// Populates any folders for a given parent node - /// - /// List to which nodes should be added - /// Parent the nodes are being added to - protected virtual void OnExpandPopulateFolders(IList allChildren, TreeNode parent) - { - } - - /// - /// Populates any non-folder nodes such as specific items in the tree. - /// - /// List to which nodes should be added - /// Parent the nodes are being added to - protected virtual void OnExpandPopulateNonFolders(IList allChildren, TreeNode parent) - { - if (ChildQuerierTypes == null) - { - // This node does not support non-folder children - return; - } - SmoQueryContext context = parent.GetContextAs(); - Validate.IsNotNull(nameof(context), context); - IEnumerable queriers = context.ServiceProvider.GetServices(q => IsCompatibleQuerier(q)); - foreach (var querier in queriers) - { - foreach(var smoObject in querier.Query(context)) - { +namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel +{ + public class SmoChildFactoryBase : ChildFactory + { + public override IEnumerable ApplicableParents() + { + return null; + } + + public override IEnumerable Expand(TreeNode parent) + { + //parent.BeginChildrenInit(); + try + { + List allChildren = new List(); + OnExpandPopulateFolders(allChildren, parent); + RemoveFoldersFromInvalidSqlServerVersions(allChildren, parent); + OnExpandPopulateNonFolders(allChildren, parent); + OnBeginAsyncOperations(parent); + return allChildren; + } + finally + { + //parent.EndChildrenInit(); + } + } + + /// + /// Populates any folders for a given parent node + /// + /// List to which nodes should be added + /// Parent the nodes are being added to + protected virtual void OnExpandPopulateFolders(IList allChildren, TreeNode parent) + { + } + + /// + /// Populates any non-folder nodes such as specific items in the tree. + /// + /// List to which nodes should be added + /// Parent the nodes are being added to + protected virtual void OnExpandPopulateNonFolders(IList allChildren, TreeNode parent) + { + if (ChildQuerierTypes == null) + { + // This node does not support non-folder children + return; + } + SmoQueryContext context = parent.GetContextAs(); + Validate.IsNotNull(nameof(context), context); + IEnumerable queriers = context.ServiceProvider.GetServices(q => IsCompatibleQuerier(q)); + var filters = this.Filters; + var validForFlag = ServerVersionHelper.GetValidForFlag(context.SqlServerType); + + foreach (var querier in queriers) + { + string propertyFilter = GetProperyFilter(filters, querier.GetType(), validForFlag); + + foreach (var smoObject in querier.Query(context, propertyFilter)) + { if (smoObject == null) { Console.WriteLine("smoObject should not be null"); - } - TreeNode childNode = CreateChild(parent, smoObject); - if (childNode != null) - { - allChildren.Add(childNode); - } - } - } - } - - private bool IsCompatibleQuerier(SmoQuerier querier) - { - if (ChildQuerierTypes == null) - { - return false; - } - - Type actualType = querier.GetType(); - foreach (Type childType in ChildQuerierTypes) - { - // We will accept any querier that is compatible with the listed querier type - if (childType.IsAssignableFrom(actualType)) - { - return true; - } - } - return false; - - } - - /// - /// Filters out invalid folders if they cannot be displayed for the current server version - /// - /// List to which nodes should be added - /// Parent the nodes are being added to - protected virtual void RemoveFoldersFromInvalidSqlServerVersions(IList 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; + } + TreeNode childNode = CreateChild(parent, smoObject); + if (childNode != null && !ShouldFilterNode(childNode, validForFlag)) + { + allChildren.Add(childNode); + } + } + } + } + + private bool ShouldFilterNode(TreeNode childNode, ValidForFlag validForFlag) + { + bool filterTheNode = false; + SmoTreeNode smoTreeNode = childNode as SmoTreeNode; + if (smoTreeNode != null && smoTreeNode.ValidFor != 0) + { + if (!(smoTreeNode.ValidFor.HasFlag(validForFlag))) + { + filterTheNode = true; + } + } + + return filterTheNode; + } + + private string GetProperyFilter(IEnumerable filters, Type querierType, ValidForFlag validForFlag) + { + string filter = ""; + if (filters != null) + { + var filterToApply = filters.FirstOrDefault(f => f.CanApplyFilter(querierType, validForFlag)); + filter = ""; + + if (filterToApply != null) + { + filter = filterToApply.ToPropertyFilterString(); + } + } + + return filter; + } + + private bool IsCompatibleQuerier(SmoQuerier querier) + { + if (ChildQuerierTypes == null) + { + return false; + } + + Type actualType = querier.GetType(); + foreach (Type childType in ChildQuerierTypes) + { + // We will accept any querier that is compatible with the listed querier type + if (childType.IsAssignableFrom(actualType)) + { + return true; + } + } + return false; + + } + + /// + /// Filters out invalid folders if they cannot be displayed for the current server version + /// + /// List to which nodes should be added + /// Parent the nodes are being added to + protected virtual void RemoveFoldersFromInvalidSqlServerVersions(IList 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) { Debug.WriteLine("context is not a NamedSmoObject. type: " + context.GetType()); @@ -136,26 +172,34 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { SmoTreeNode childAsMeItem = (SmoTreeNode)child; childAsMeItem.CacheInfoFromModel(smoObj); - } - } - - internal virtual Type[] ChildQuerierTypes { - get - { - return null; - } - } - - /// - /// 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 - /// - /// - /// - /// boolean - public virtual bool PassesFinalFilters(TreeNode parent, object context) - { - return true; - } - } -} + } + } + + internal virtual Type[] ChildQuerierTypes { + get + { + return null; + } + } + + public override IEnumerable Filters + { + get + { + return Enumerable.Empty(); + } + } + + /// + /// 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 + /// + /// + /// + /// boolean + public virtual bool PassesFinalFilters(TreeNode parent, object context) + { + return true; + } + } +} diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQuerier.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQuerier.cs index 87373258..aececc7a 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQuerier.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQuerier.cs @@ -1,42 +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 System.Collections.Generic; -using Microsoft.SqlServer.Management.Smo; +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System; +using System.Collections.Generic; +using System.Data; +using Microsoft.Data.Tools.DataSets; +using Microsoft.SqlServer.Management.Sdk.Sfc; +using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlTools.Extensibility; -namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel -{ - /// - /// A handles SMO queries for one or more SMO object types. - /// The property defines which types can be queried. - /// - /// To query multiple - /// - public abstract class SmoQuerier : IComposableService - { - public abstract Type[] SupportedObjectTypes { get; } - - /// - /// Queries SMO for a collection of objects using the - /// - /// - /// - public abstract IEnumerable Query(SmoQueryContext context); - - internal IMultiServiceProvider ServiceProvider - { - get; - private set; - } - - public void SetServiceProvider(IMultiServiceProvider provider) - { - ServiceProvider = provider; - } - } - -} +namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel +{ + /// + /// A handles SMO queries for one or more SMO object types. + /// The property defines which types can be queried. + /// + /// To query multiple + /// + public abstract class SmoQuerier : IComposableService + { + public abstract Type[] SupportedObjectTypes { get; } + + /// + /// Queries SMO for a collection of objects using the + /// + /// + /// + public abstract IEnumerable Query(SmoQueryContext context, string filter); + + internal IMultiServiceProvider ServiceProvider + { + get; + private set; + } + + public void SetServiceProvider(IMultiServiceProvider provider) + { + ServiceProvider = provider; + } + + /// + /// Convert the data to data reader is possible + /// + 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; + } + + /// + /// Gets the urn from the enumResult + /// + protected HashSet GetUrns(EnumResult enumResult) + { + HashSet urns = null; + if (enumResult != null && enumResult.Data != null) + { + urns = new HashSet(); + IDataReader reader = GetDataReader(enumResult.Data); + if (reader != null) + { + while (reader.Read()) + { + urns.Add(reader.GetString(0)); + } + } + } + + return urns; + } + } + +} diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryContext.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryContext.cs index 73758a3c..d6ebdfec 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryContext.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryContext.cs @@ -28,6 +28,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel ServiceProvider = serviceProvider; } + /// + /// The server type + /// + public SqlServerType SqlServerType { get; set; } + /// /// The server SMO will query against /// @@ -94,7 +99,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel SmoQueryContext context = new SmoQueryContext(this.Server, this.ServiceProvider) { Database = this.Database, - Parent = parent + Parent = parent, + SqlServerType = this.SqlServerType }; return context; } diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModel.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModel.cs index f2407b6b..f8a05fc3 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModel.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModel.cs @@ -6,6 +6,8 @@ using System; using System.Collections.Generic; using System.Composition; using System.Linq; +using Microsoft.SqlServer.Management.Common; +using Microsoft.SqlServer.Management.Sdk.Sfc; using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Smo.Broker; @@ -19,15 +21,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Server parentServer = context.Parent as Server; if (parentServer != null) { var retValue = parentServer.Databases; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServer.Urn.ToString()}/Database" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -41,15 +61,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Server parentServer = context.Parent as Server; if (parentServer != null) { var retValue = parentServer.LinkedServers; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServer.Urn.ToString()}/LinkedServer" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -63,15 +101,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Server parentServer = context.Parent as Server; if (parentServer != null) { var retValue = parentServer.Logins; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServer.Urn.ToString()}/Login" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -85,15 +141,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Server parentServer = context.Parent as Server; if (parentServer != null) { var retValue = parentServer.Roles; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServer.Urn.ToString()}/ServerRole" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -107,15 +181,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Server parentServer = context.Parent as Server; if (parentServer != null) { var retValue = parentServer.Credentials; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServer.Urn.ToString()}/Credential" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -129,15 +221,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Server parentServer = context.Parent as Server; if (parentServer != null) { var retValue = parentServer.CryptographicProviders; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServer.Urn.ToString()}/CryptographicProvider" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -151,15 +261,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Server parentServer = context.Parent as Server; if (parentServer != null) { var retValue = parentServer.Audits; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServer.Urn.ToString()}/Audit" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -173,15 +301,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Server parentServer = context.Parent as Server; if (parentServer != null) { var retValue = parentServer.ServerAuditSpecifications; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServer.Urn.ToString()}/ServerAuditSpecification" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -195,15 +341,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Server parentServer = context.Parent as Server; if (parentServer != null) { var retValue = parentServer.Endpoints; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServer.Urn.ToString()}/Endpoint" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -217,15 +381,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Server parentServer = context.Parent as Server; if (parentServer != null) { var retValue = parentServer.LinkedServers; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServer.Urn.ToString()}/LinkedServer" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -239,15 +421,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Server parentServer = context.Parent as Server; if (parentServer != null) { var retValue = parentServer.Triggers; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServer.Urn.ToString()}/ServerDdlTrigger" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -261,15 +461,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Server parentServer = context.Parent as Server; if (parentServer != null) { var retValue = parentServer.UserDefinedMessages; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServer.Urn.ToString()}/UserDefinedMessage" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -283,15 +501,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.Tables; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/Table" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper
(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper
(retValue); + } } } return Enumerable.Empty(); @@ -305,15 +541,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.Views; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/View" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -327,15 +581,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.Synonyms; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/Synonym" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -349,15 +621,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { TableViewTableTypeBase parentTableViewTableTypeBase = context.Parent as TableViewTableTypeBase; if (parentTableViewTableTypeBase != null) { var retValue = parentTableViewTableTypeBase.Columns; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentTableViewTableTypeBase.Urn.ToString()}/Column" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -371,15 +661,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { TableViewTableTypeBase parentTableViewTableTypeBase = context.Parent as TableViewTableTypeBase; if (parentTableViewTableTypeBase != null) { var retValue = parentTableViewTableTypeBase.Indexes; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentTableViewTableTypeBase.Urn.ToString()}/Index" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -393,15 +701,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Table parentTable = context.Parent as Table; if (parentTable != null) { var retValue = parentTable.Checks; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentTable.Urn.ToString()}/Check" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -415,15 +741,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Table parentTable = context.Parent as Table; if (parentTable != null) { var retValue = parentTable.ForeignKeys; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentTable.Urn.ToString()}/ForeignKey" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -437,13 +781,24 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Column parentColumn = context.Parent as Column; if (parentColumn != null) { var retValue = parentColumn.DefaultConstraint; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) + { + string urn = $"{parentColumn.Urn.ToString()}/DefaultConstraint" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) { return new SqlSmoObject[] { retValue }; } @@ -459,15 +814,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Table parentTable = context.Parent as Table; if (parentTable != null) { var retValue = parentTable.Triggers; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentTable.Urn.ToString()}/Trigger" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -481,13 +854,24 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Table parentTable = context.Parent as Table; if (parentTable != null) { var retValue = parentTable.FullTextIndex; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) + { + string urn = $"{parentTable.Urn.ToString()}/FullTextIndex" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) { return new SqlSmoObject[] { retValue }; } @@ -503,15 +887,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { TableViewBase parentTableViewBase = context.Parent as TableViewBase; if (parentTableViewBase != null) { var retValue = parentTableViewBase.Statistics; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentTableViewBase.Urn.ToString()}/Statistic" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -525,15 +927,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.Triggers; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/Trigger" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -547,15 +967,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.Assemblies; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/SqlAssembly" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -569,15 +1007,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.Rules; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/Rule" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -591,15 +1047,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.Defaults; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/Default" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -613,15 +1087,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.Sequences; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/Sequence" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -635,15 +1127,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Server parentServer = context.Parent as Server; if (parentServer != null) { var retValue = parentServer.SystemDataTypes; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServer.Urn.ToString()}/SystemDataType" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -657,15 +1167,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.UserDefinedDataTypes; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/UserDefinedDataType" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -679,15 +1207,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.UserDefinedTableTypes; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/UserDefinedTableType" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -701,15 +1247,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.XmlSchemaCollections; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/XmlSchemaCollection" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -723,15 +1287,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.UserDefinedTypes; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/UserDefinedType" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -745,15 +1327,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.UserDefinedFunctions; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/UserDefinedFunction" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -767,15 +1367,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.UserDefinedAggregates; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/UserDefinedAggregate" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -789,15 +1407,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.FileGroups; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/FileGroup" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -811,15 +1447,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { FileGroup parentFileGroup = context.Parent as FileGroup; if (parentFileGroup != null) { var retValue = parentFileGroup.Files; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentFileGroup.Urn.ToString()}/DataFile" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -833,15 +1487,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.FullTextCatalogs; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/FullTextCatalog" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -855,15 +1527,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.FullTextStopLists; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/FullTextStopList" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -877,15 +1567,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.PartitionFunctions; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/PartitionFunction" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -899,15 +1607,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.PartitionSchemes; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/PartitionScheme" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -921,15 +1647,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.SearchPropertyLists; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/SearchPropertyList" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -943,15 +1687,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.Users; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/User" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -965,15 +1727,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.Schemas; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/Schema" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -987,15 +1767,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.AsymmetricKeys; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/AsymmetricKey" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1009,15 +1807,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.Certificates; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/Certificate" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1031,15 +1847,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.SymmetricKeys; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/SymmetricKey" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1053,13 +1887,24 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.DatabaseEncryptionKey; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) + { + string urn = $"{parentDatabase.Urn.ToString()}/DatabaseEncryptionKey" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) { return new SqlSmoObject[] { retValue }; } @@ -1075,13 +1920,24 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.MasterKey; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) + { + string urn = $"{parentDatabase.Urn.ToString()}/MasterKey" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) { return new SqlSmoObject[] { retValue }; } @@ -1097,15 +1953,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.DatabaseAuditSpecifications; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/DatabaseAuditSpecification" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1119,15 +1993,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.SecurityPolicies; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/SecurityPolicy" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1141,15 +2033,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.DatabaseScopedCredentials; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/DatabaseScopedCredential" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1163,15 +2073,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.Roles; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/DatabaseRole" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1185,15 +2113,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.ApplicationRoles; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/ApplicationRole" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1207,15 +2153,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.ColumnMasterKeys; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/ColumnMasterKey" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1229,15 +2193,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.ColumnEncryptionKeys; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/ColumnEncryptionKey" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1251,13 +2233,24 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.ServiceBroker; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) + { + string urn = $"{parentDatabase.Urn.ToString()}/ServiceBroker" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) { return new SqlSmoObject[] { retValue }; } @@ -1273,15 +2266,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { ServiceBroker parentServiceBroker = context.Parent as ServiceBroker; if (parentServiceBroker != null) { var retValue = parentServiceBroker.Services; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServiceBroker.Urn.ToString()}/BrokerService" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1295,15 +2306,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { ServiceBroker parentServiceBroker = context.Parent as ServiceBroker; if (parentServiceBroker != null) { var retValue = parentServiceBroker.ServiceContracts; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServiceBroker.Urn.ToString()}/ServiceContract" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1317,15 +2346,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { ServiceBroker parentServiceBroker = context.Parent as ServiceBroker; if (parentServiceBroker != null) { var retValue = parentServiceBroker.Queues; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServiceBroker.Urn.ToString()}/ServiceQueue" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1339,15 +2386,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { ServiceBroker parentServiceBroker = context.Parent as ServiceBroker; if (parentServiceBroker != null) { var retValue = parentServiceBroker.RemoteServiceBindings; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServiceBroker.Urn.ToString()}/RemoteServiceBinding" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1361,15 +2426,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { ServiceBroker parentServiceBroker = context.Parent as ServiceBroker; if (parentServiceBroker != null) { var retValue = parentServiceBroker.Priorities; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServiceBroker.Urn.ToString()}/BrokerPriority" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1383,15 +2466,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { ServiceBroker parentServiceBroker = context.Parent as ServiceBroker; if (parentServiceBroker != null) { var retValue = parentServiceBroker.MessageTypes; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServiceBroker.Urn.ToString()}/MessageType" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1405,15 +2506,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.ExternalDataSources; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/ExternalDataSource" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1427,15 +2546,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.ExternalFileFormats; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/ExternalFileFormat" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1449,15 +2586,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.StoredProcedures; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/StoredProcedure" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1471,15 +2626,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { var retValue = parentDatabase.ExtendedStoredProcedures; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentDatabase.Urn.ToString()}/ExtendedStoredProcedure" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1493,33 +2666,87 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { StoredProcedure parentStoredProcedure = context.Parent as StoredProcedure; if (parentStoredProcedure != null) { var retValue = parentStoredProcedure.Parameters; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentStoredProcedure.Urn.ToString()}/Parameter" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } UserDefinedAggregate parentUserDefinedAggregate = context.Parent as UserDefinedAggregate; if (parentUserDefinedAggregate != null) { var retValue = parentUserDefinedAggregate.Parameters; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentUserDefinedAggregate.Urn.ToString()}/Parameter" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } UserDefinedFunction parentUserDefinedFunction = context.Parent as UserDefinedFunction; if (parentUserDefinedFunction != null) { var retValue = parentUserDefinedFunction.Parameters; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentUserDefinedFunction.Urn.ToString()}/Parameter" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1533,15 +2760,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { PartitionFunction parentPartitionFunction = context.Parent as PartitionFunction; if (parentPartitionFunction != null) { var retValue = parentPartitionFunction.PartitionFunctionParameters; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentPartitionFunction.Urn.ToString()}/PartitionFunctionParameter" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); @@ -1555,15 +2800,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override Type[] SupportedObjectTypes { get { return supportedTypes; } } - public override IEnumerable Query(SmoQueryContext context) + public override IEnumerable Query(SmoQueryContext context, string filter) { Server parentServer = context.Parent as Server; if (parentServer != null) { var retValue = parentServer.SystemDataTypes; - if(retValue != null) + bool hasFilter = !string.IsNullOrEmpty(filter); + HashSet urns = null; + if (hasFilter) { - return new SmoCollectionWrapper(retValue); + string urn = $"{parentServer.Urn.ToString()}/SystemDataType" + filter; + Enumerator en = new Enumerator(); + Request request = new Request(new Urn(urn)); + ServerConnection serverConnection = new ServerConnection(context.Server.ConnectionContext.SqlConnectionObject); + EnumResult result = en.Process(serverConnection, request); + urns = GetUrns(result); + } + if (retValue != null) + { + if (hasFilter && urns != null) + { + return new SmoCollectionWrapper(retValue).Where(c => urns.Contains(c.Urn)); + } + else + { + return new SmoCollectionWrapper(retValue); + } } } return Enumerable.Empty(); diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModel.tt b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModel.tt index 0ed1ebe4..252cb104 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModel.tt +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModel.tt @@ -15,6 +15,8 @@ using System; using System.Collections.Generic; using System.Composition; using System.Linq; +using Microsoft.SqlServer.Management.Common; +using Microsoft.SqlServer.Management.Sdk.Sfc; using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Smo.Broker; @@ -50,7 +52,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel WriteLine(""); // Query impl - WriteLine("public override IEnumerable Query(SmoQueryContext context)"); + WriteLine("public override IEnumerable Query(SmoQueryContext context, string filter)"); WriteLine("{"); PushIndent(indent); @@ -65,17 +67,43 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel string navigationPath = GetNavigationPath(nodeElement, xmlFile, nodeName, parentType); WriteLine(string.Format("var retValue = {0}.{1};", parentVar, navigationPath)); - WriteLine("if(retValue != null)"); + WriteLine("bool hasFilter = !string.IsNullOrEmpty(filter);"); + WriteLine("HashSet 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("{"); PushIndent(indent); 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)); + PopIndent(); + WriteLine("}"); } else { WriteLine("return new SqlSmoObject[] { retValue };"); } + PopIndent(); WriteLine("}"); PopIndent(); diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/TreeNodeDefinition.xml b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/TreeNodeDefinition.xml index 3e14860f..b8e8b868 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/TreeNodeDefinition.xml +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/TreeNodeDefinition.xml @@ -20,7 +20,7 @@ --> - + @@ -30,26 +30,26 @@ --> - + - - - - - - - + + + + + + + - - - - + + + + - + @@ -61,12 +61,13 @@ - + + - TemporalTableType.None - TemporalTableType.SystemVersioned + TableTemporalType.None + TableTemporalType.SystemVersioned @@ -75,10 +76,13 @@ + + + - + @@ -130,23 +134,27 @@ - + + + + + - - + + - - + + - - TemporalTableType.History + + TableTemporalType.HistoryTable @@ -158,20 +166,20 @@ - + - + - - + + IndexKeyType.DriPrimaryKey @@ -179,20 +187,24 @@ - - - + + + IndexKeyType.None - + - + + + + + - + @@ -204,8 +216,8 @@ - - + + @@ -213,9 +225,9 @@ - - - + + + @@ -228,18 +240,18 @@ - + - - + + - + - - + + IndexKeyType.DriPrimaryKey @@ -247,60 +259,71 @@ - /> + /> - - - - - - - - - + + + + + + + + + - - + + + + + - - - - - - - - - - UserDefinedFunctionType.Table - + + + - + + + + + + + + + UserDefinedFunctionType.Table + + + + + - + + - - UserDefinedFunctionType.Table + + UserDefinedFunctionType.Scalar + - + - + - - + + + - + - - + + - - - - - - + + + + + + - + - - + + - - - - - - + + + + + + - - - + + + - - - - + + + + - + - + - + - + - + - + - + - + diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/TreeNodeGenerator.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/TreeNodeGenerator.cs index ac2fc282..984dd37d 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/TreeNodeGenerator.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/TreeNodeGenerator.cs @@ -1,12 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Composition; -using Microsoft.SqlTools.ServiceLayer; -using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; - -namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel -{ - +using System; +using System.Collections.Generic; +using System.Composition; +using Microsoft.SqlServer.Management.Smo; +using Microsoft.SqlTools.ServiceLayer; +using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; + +namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel +{ + internal sealed partial class DatabaseTreeNode : SmoTreeNode { public DatabaseTreeNode() : base() @@ -657,6 +658,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { var child = new SmoTreeNode(); child.IsAlwaysLeaf = true; + child.NodeType = "Database"; InitializeChild(child, context); return child; } @@ -668,6 +670,45 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { public override IEnumerable ApplicableParents() { return new[] { "Tables" }; } + public override IEnumerable Filters + { + get + { + var filters = new List(); + filters.Add(new NodeFilter + { + Property = "IsFileTable", + Type = typeof(bool), + Values = new List { 0 }, + }); + filters.Add(new NodeFilter + { + Property = "IsSystemObject", + Type = typeof(bool), + Values = new List { 0 }, + }); + filters.Add(new NodeFilter + { + Property = "IsExternal", + Type = typeof(bool), + ValidFor = ValidForFlag.Sql2016|ValidForFlag.AzureV12, + Values = new List { 0 }, + }); + filters.Add(new NodeFilter + { + Property = "TemporalType", + Type = typeof(Enum), + ValidFor = ValidForFlag.Sql2016|ValidForFlag.AzureV12, + Values = new List + { + { TableTemporalType.None }, + { TableTemporalType.SystemVersioned } + } + }); + return filters; + } + } + protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { @@ -715,6 +756,21 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { public override IEnumerable ApplicableParents() { return new[] { "Views" }; } + public override IEnumerable Filters + { + get + { + var filters = new List(); + filters.Add(new NodeFilter + { + Property = "IsSystemObject", + Type = typeof(bool), + Values = new List { 0 }, + }); + return filters; + } + } + protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { @@ -1095,6 +1151,21 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { public override IEnumerable ApplicableParents() { return new[] { "SystemTables" }; } + public override IEnumerable Filters + { + get + { + var filters = new List(); + filters.Add(new NodeFilter + { + Property = "IsSystemObject", + Type = typeof(bool), + Values = new List { 1 }, + }); + return filters; + } + } + internal override Type[] ChildQuerierTypes { get @@ -1117,6 +1188,21 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { public override IEnumerable ApplicableParents() { return new[] { "FileTables" }; } + public override IEnumerable Filters + { + get + { + var filters = new List(); + filters.Add(new NodeFilter + { + Property = "IsFileTable", + Type = typeof(bool), + Values = new List { 1 }, + }); + return filters; + } + } + internal override Type[] ChildQuerierTypes { get @@ -1139,6 +1225,21 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { public override IEnumerable ApplicableParents() { return new[] { "ExternalTables" }; } + public override IEnumerable Filters + { + get + { + var filters = new List(); + filters.Add(new NodeFilter + { + Property = "IsExternal", + Type = typeof(bool), + Values = new List { 1 }, + }); + return filters; + } + } + internal override Type[] ChildQuerierTypes { get @@ -1161,6 +1262,25 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { public override IEnumerable ApplicableParents() { return new[] { "Table" }; } + public override IEnumerable Filters + { + get + { + var filters = new List(); + filters.Add(new NodeFilter + { + Property = "TemporalType", + Type = typeof(Enum), + ValidFor = ValidForFlag.Sql2016|ValidForFlag.AzureV12, + Values = new List + { + { TableTemporalType.HistoryTable } + } + }); + return filters; + } + } + protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { @@ -1257,6 +1377,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { var child = new SmoTreeNode(); child.IsAlwaysLeaf = true; + child.NodeType = "Table"; InitializeChild(child, context); return child; } @@ -1296,6 +1417,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { var child = new SmoTreeNode(); child.IsAlwaysLeaf = true; + child.NodeType = "Table"; InitializeChild(child, context); return child; } @@ -1332,6 +1454,27 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { public override IEnumerable ApplicableParents() { return new[] { "Keys" }; } + public override IEnumerable Filters + { + get + { + var filters = new List(); + filters.Add(new NodeFilter + { + Property = "IndexKeyType", + Type = typeof(Enum), + TypeToReverse = typeof(SqlIndexQuerier), + ValidFor = ValidForFlag.Sql2016|ValidForFlag.AzureV12, + Values = new List + { + { IndexKeyType.DriPrimaryKey }, + { IndexKeyType.DriUniqueKey } + } + }); + return filters; + } + } + internal override Type[] ChildQuerierTypes { get @@ -1404,6 +1547,26 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { public override IEnumerable ApplicableParents() { return new[] { "Indexes" }; } + public override IEnumerable Filters + { + get + { + var filters = new List(); + filters.Add(new NodeFilter + { + Property = "IndexKeyType", + Type = typeof(Enum), + TypeToReverse = typeof(SqlIndexQuerier), + ValidFor = ValidForFlag.Sql2016|ValidForFlag.AzureV12, + Values = new List + { + { IndexKeyType.None } + } + }); + return filters; + } + } + internal override Type[] ChildQuerierTypes { get @@ -1416,7 +1579,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { var child = new SmoTreeNode(); child.IsAlwaysLeaf = true; - child.NodeType = "Indexe"; + child.NodeType = "Index"; InitializeChild(child, context); return child; } @@ -1452,6 +1615,21 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { public override IEnumerable ApplicableParents() { return new[] { "SystemViews" }; } + public override IEnumerable Filters + { + get + { + var filters = new List(); + filters.Add(new NodeFilter + { + Property = "IsSystemObject", + Type = typeof(bool), + Values = new List { 1 }, + }); + return filters; + } + } + internal override Type[] ChildQuerierTypes { get @@ -1513,6 +1691,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { var child = new SmoTreeNode(); child.IsAlwaysLeaf = true; + child.NodeType = "View"; InitializeChild(child, context); return child; } @@ -1598,7 +1777,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { var child = new SmoTreeNode(); child.IsAlwaysLeaf = true; - child.NodeType = "Assemblie"; + child.NodeType = "Assembly"; InitializeChild(child, context); return child; } @@ -1936,6 +2115,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { var child = new SmoTreeNode(); child.IsAlwaysLeaf = true; + child.NodeType = "UserDefinedTableType"; InitializeChild(child, context); return child; } @@ -1972,6 +2152,27 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { public override IEnumerable ApplicableParents() { return new[] { "UserDefinedTableTypeKeys" }; } + public override IEnumerable Filters + { + get + { + var filters = new List(); + filters.Add(new NodeFilter + { + Property = "IndexKeyType", + Type = typeof(Enum), + TypeToReverse = typeof(SqlIndexQuerier), + ValidFor = ValidForFlag.Sql2016|ValidForFlag.AzureV12, + Values = new List + { + { IndexKeyType.DriPrimaryKey }, + { IndexKeyType.DriUniqueKey } + } + }); + return filters; + } + } + internal override Type[] ChildQuerierTypes { get @@ -2284,6 +2485,21 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { public override IEnumerable ApplicableParents() { return new[] { "StoredProcedures" }; } + public override IEnumerable Filters + { + get + { + var filters = new List(); + filters.Add(new NodeFilter + { + Property = "IsSystemObject", + Type = typeof(bool), + Values = new List { 0 }, + }); + return filters; + } + } + protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { @@ -2317,6 +2533,21 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { public override IEnumerable ApplicableParents() { return new[] { "SystemStoredProcedures" }; } + public override IEnumerable Filters + { + get + { + var filters = new List(); + filters.Add(new NodeFilter + { + Property = "IsSystemObject", + Type = typeof(bool), + Values = new List { 1 }, + }); + return filters; + } + } + internal override Type[] ChildQuerierTypes { get @@ -2360,6 +2591,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { var child = new SmoTreeNode(); child.IsAlwaysLeaf = true; + child.NodeType = "StoredProcedure"; InitializeChild(child, context); return child; } @@ -2396,6 +2628,31 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { public override IEnumerable ApplicableParents() { return new[] { "TableValuedFunctions" }; } + public override IEnumerable Filters + { + get + { + var filters = new List(); + filters.Add(new NodeFilter + { + Property = "FunctionType", + Type = typeof(Enum), + ValidFor = ValidForFlag.Sql2016|ValidForFlag.AzureV12, + Values = new List + { + { UserDefinedFunctionType.Table } + } + }); + filters.Add(new NodeFilter + { + Property = "IsSystemObject", + Type = typeof(bool), + Values = new List { 0 }, + }); + return filters; + } + } + internal override Type[] ChildQuerierTypes { get @@ -2439,6 +2696,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { var child = new SmoTreeNode(); child.IsAlwaysLeaf = true; + child.NodeType = "TableValuedFunction"; InitializeChild(child, context); return child; } @@ -2475,6 +2733,31 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { public override IEnumerable ApplicableParents() { return new[] { "ScalarValuedFunctions" }; } + public override IEnumerable Filters + { + get + { + var filters = new List(); + filters.Add(new NodeFilter + { + Property = "FunctionType", + Type = typeof(Enum), + ValidFor = ValidForFlag.Sql2016|ValidForFlag.AzureV12, + Values = new List + { + { UserDefinedFunctionType.Scalar } + } + }); + filters.Add(new NodeFilter + { + Property = "IsSystemObject", + Type = typeof(bool), + Values = new List { 0 }, + }); + return filters; + } + } + internal override Type[] ChildQuerierTypes { get @@ -2518,6 +2801,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { var child = new SmoTreeNode(); child.IsAlwaysLeaf = true; + child.NodeType = "ScalarValuedFunction"; InitializeChild(child, context); return child; } @@ -2597,6 +2881,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { var child = new SmoTreeNode(); child.IsAlwaysLeaf = true; + child.NodeType = "AggregateFunction"; InitializeChild(child, context); return child; } @@ -2669,7 +2954,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { var child = new SmoTreeNode(); child.IsAlwaysLeaf = true; - child.NodeType = "BrokerPrioritie"; + child.NodeType = "BrokerPriority"; InitializeChild(child, context); return child; } @@ -3527,5 +3812,5 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel } } -} - +} + diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/TreeNodeGenerator.tt b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/TreeNodeGenerator.tt index 19cb32e5..71880d35 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/TreeNodeGenerator.tt +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/TreeNodeGenerator.tt @@ -10,6 +10,7 @@ using System; using System.Collections.Generic; using System.Composition; +using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlTools.ServiceLayer; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; @@ -84,6 +85,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel var isAlwaysLeaf = nodeElement.GetAttributeNode("IsAlwaysLeaf"); var baseClass = nodeElement.GetAttribute("BaseClass"); var strategy = nodeElement.GetAttribute("Strategy"); + var nodeType = nodeElement.GetAttribute("NodeType"); var ChildQuerierTypes = nodeElement.GetAttribute("ChildQuerierTypes"); var TreeNode = nodeElement.GetAttribute("TreeNode"); var isAsync = nodeElement.GetAttributeNode("IsAsyncLoad"); @@ -104,6 +106,81 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel WriteLine(string.Format(" public override IEnumerable ApplicableParents() {{ return new[] {{ \"{0}\" }}; }}", type)); List children = GetChildren(xmlFile, type); + List filters = GetNodeFilters(xmlFile, type); + + + + + if (filters.Count > 0) + { + WriteLine(""); + WriteLine(" public override IEnumerable Filters"); + WriteLine(" {"); + WriteLine(" get"); + WriteLine(" {"); + + WriteLine(" var filters = new List();"); + 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 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 {{ {0} }},", propertyValue)); + } + if (filterValues != null && filterValues.Count > 0) + { + string filterValueType = "object"; + if (propertyType == "Enum") + { + + } + WriteLine(string.Format(" Values = new List")); + 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) { WriteLine(""); @@ -179,10 +256,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { WriteLine(" var child = new SmoTreeNode();"); 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(" InitializeChild(child, context);"); + + WriteLine(" return child;"); WriteLine(" }"); } @@ -390,4 +470,42 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel } return retElements; } + + public static List GetNodeFilters(string xmlFile, string parentName) + { + XmlElement nodeElement = GetNodeElement(xmlFile, parentName); + XmlDocument doc = new XmlDocument(); + doc.Load(xmlFile); + + List retElements = new List(); + 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 GetNodeFilterValues(string xmlFile, string parentName, string filterProperty) + { + XmlElement nodeElement = GetNodeElement(xmlFile, parentName); + XmlDocument doc = new XmlDocument(); + doc.Load(xmlFile); + + List retElements = new List(); + 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; + } #> \ No newline at end of file diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/ObjectExplorerServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/ObjectExplorerServiceTests.cs index 9f0e6795..970dad7c 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/ObjectExplorerServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/ObjectExplorerServiceTests.cs @@ -1,14 +1,15 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// +// 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.Globalization; using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlTools.ServiceLayer.Connection.Contracts; -using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; @@ -22,78 +23,95 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer { private ObjectExplorerService _service = TestServiceProvider.Instance.ObjectExplorerService; - [Fact] - public async void CreateSessionAndExpandOnTheServerShouldReturnServerAsTheRoot() - { - var query = ""; - string uri = "CreateSessionAndExpandServer"; - string databaseName = null; + [Fact] + public async void CreateSessionAndExpandOnTheServerShouldReturnServerAsTheRoot() + { + var query = ""; + string uri = "CreateSessionAndExpandServer"; + string databaseName = null; using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri)) { var session = await CreateSession(null, uri); await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session); - CancelConnection(uri); } + CancelConnection(uri); } - [Fact] - public async void CreateSessionWithTempdbAndExpandOnTheServerShouldReturnServerAsTheRoot() - { - var query = ""; - string uri = "CreateSessionAndExpandServer"; - string databaseName = null; + [Fact] + public async void CreateSessionWithTempdbAndExpandOnTheServerShouldReturnServerAsTheRoot() + { + var query = ""; + string uri = "CreateSessionAndExpandServer"; + string databaseName = null; using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri)) { var session = await CreateSession("tempdb", uri); await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session); - CancelConnection(uri); } + CancelConnection(uri); + } [Fact] - public async void CreateSessionAndExpandOnTheDatabaseShouldReturnDatabaseAsTheRoot() - { - var query = ""; - string uri = "CreateSessionAndExpandDatabase"; - string databaseName = null; + public async void CreateSessionAndExpandOnTheDatabaseShouldReturnDatabaseAsTheRoot() + { + var query = ""; + string uri = "CreateSessionAndExpandDatabase"; + string databaseName = null; using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri)) { var session = await CreateSession(testDb.DatabaseName, uri); ExpandAndVerifyDatabaseNode(testDb.DatabaseName, session); - CancelConnection(uri); } + CancelConnection(uri); + } private async Task CreateSession(string databaseName, string uri) { ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, databaseName); + connectParams.Connection.Pooling = false; 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 ExpandServerNodeAndVerifyDatabaseHierachy(string databaseName, ObjectExplorerSession session) + private async Task ExpandServerNodeAndVerifyDatabaseHierachy(string databaseName, ObjectExplorerSession session, bool serverNode = true) { Assert.NotNull(session); Assert.NotNull(session.Root); NodeInfo nodeInfo = session.Root.ToNodeInfo(); 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 - foreach (var item in children) + if (serverNode) { - 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); return databaseNode; } @@ -120,154 +138,212 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer private void CancelConnection(string uri) { - //ConnectionService.Instance.CancelConnect(new CancelConnectParams - //{ - // OwnerUri = uri, - // Type = ConnectionType.Default - //}); + ConnectionService.Instance.CancelConnect(new CancelConnectParams + { + OwnerUri = uri, + Type = ConnectionType.Default + }); } 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); - 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) { - //Console.WriteLine(child.Label); - await ExpandTree(child, session); + await _service.ExpandNode(session, child.NodePath); } } } + /// + /// Returns the children of a node with the given label + /// + private async Task 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] public async void VerifyAdventureWorksDatabaseObjects() { - var query = Scripts.AdventureWorksScript; - string uri = "VerifyAdventureWorksDatabaseObjects"; - string databaseName = null; - - using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri)) + var query = Scripts.AdventureWorksScript; + string uri = "VerifyAdventureWorksDatabaseObjects"; + string databaseName = null; + + using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) + using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, true, databaseName, query, uri)) { - var session = await CreateSession(null, uri); - var databaseNodeInfo = await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session); - await ExpandTree(databaseNodeInfo, session); - CancelConnection(uri); + var session = await CreateSession(testDb.DatabaseName, queryTempFile.FilePath); + var databaseNodeInfo = await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session, false); + await ExpandTree(session.Root.ToNodeInfo(), session); + 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() { - var query = LoadScript("Sql_2016_Additions.sql"); - string uri = "VerifySql2016Objects"; - string databaseName = null; - + var query = LoadScript("Sql_2016_Additions.sql"); + string uri = "VerifySql2016Objects"; + string databaseName = null; + using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri)) { var session = await CreateSession(testDb.DatabaseName, uri); var databaseNodeInfo = await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session); - await ExpandTree(databaseNodeInfo, session); - CancelConnection(uri); + await FindNodeByLabel(databaseNodeInfo, session, SR.SchemaHierarchy_Tables); } + CancelConnection(uri); + } - // [Fact] + // [Fact] public async void VerifySqlObjects() { - var query = LoadScript("Sql_Additions.sql"); - string uri = "VerifySqlObjects"; - string databaseName = null; - + var query = LoadScript("Sql_Additions.sql"); + string uri = "VerifySqlObjects"; + string databaseName = null; + using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri)) { var session = await CreateSession(testDb.DatabaseName, uri); var databaseNodeInfo = await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session); - await ExpandTree(databaseNodeInfo, session); - CancelConnection(uri); + await FindNodeByLabel(databaseNodeInfo, session, SR.SchemaHierarchy_Tables); } + CancelConnection(uri); + } - // [Fact] + // [Fact] public async void VerifyFileTableTest() { - var query = LoadScript("FileTableTest.sql"); - string uri = "VerifyFileTableTest"; - string databaseName = null; - + var query = LoadScript("FileTableTest.sql"); + string uri = "VerifyFileTableTest"; + string databaseName = null; + using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri)) { var session = await CreateSession(testDb.DatabaseName, uri); var databaseNodeInfo = await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session); - await ExpandTree(databaseNodeInfo, session); - CancelConnection(uri); + await FindNodeByLabel(databaseNodeInfo, session, SR.SchemaHierarchy_Tables); } + CancelConnection(uri); + } //[Fact] public async void VerifyColumnstoreindexSql16() { - var query = LoadScript("ColumnstoreindexSql16.sql"); - string uri = "VerifyColumnstoreindexSql16"; - string databaseName = null; - + var query = LoadScript("ColumnstoreindexSql16.sql"); + string uri = "VerifyColumnstoreindexSql16"; + string databaseName = null; + using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri)) { var session = await CreateSession(testDb.DatabaseName, uri); var databaseNodeInfo = await ExpandServerNodeAndVerifyDatabaseHierachy(testDb.DatabaseName, session); - await ExpandTree(databaseNodeInfo, session); - CancelConnection(uri); + await FindNodeByLabel(databaseNodeInfo, session, SR.SchemaHierarchy_Tables); + } + CancelConnection(uri); + + } + + private static string TestLocationDirectory + { + get + { + return Path.Combine(RunEnvironmentInfo.GetTestDataLocation(), "ObjectExplorer"); } } - private static string TestLocationDirectory - { - get - { - return Path.Combine(RunEnvironmentInfo.GetTestDataLocation(), "ObjectExplorer"); - } + public DirectoryInfo InputFileDirectory + { + get + { + string d = Path.Combine(TestLocationDirectory, "TestScripts"); + return new DirectoryInfo(d); + } } - public DirectoryInfo InputFileDirectory - { - get - { - string d = Path.Combine(TestLocationDirectory, "TestScripts"); - return new DirectoryInfo(d); - } - } - - public FileInfo GetInputFile(string fileName) - { - return new FileInfo(Path.Combine(InputFileDirectory.FullName, fileName)); + public FileInfo GetInputFile(string fileName) + { + return new FileInfo(Path.Combine(InputFileDirectory.FullName, fileName)); } private string LoadScript(string fileName) diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/SqlTestDb.cs b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/SqlTestDb.cs index 612dea9a..86a4c48f 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/SqlTestDb.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/SqlTestDb.cs @@ -113,12 +113,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common { 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); - TestServiceProvider.Instance.RunQuery(ServerType, MasterDatabaseName, dropDatabaseQuery); - } + + Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Cleaning up database {0}", DatabaseName)); + TestServiceProvider.Instance.RunQuery(ServerType, MasterDatabaseName, dropDatabaseQuery); } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestConnectionProfileService.cs b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestConnectionProfileService.cs index 190f762d..0a38f0e7 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestConnectionProfileService.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestConnectionProfileService.cs @@ -184,6 +184,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common connectParams.Connection.DatabaseName = connectionProfile.Database; connectParams.Connection.UserName = connectionProfile.User; connectParams.Connection.Password = connectionProfile.Password; + connectParams.Connection.MaxPoolSize = 200; connectParams.Connection.AuthenticationType = connectionProfile.AuthenticationType.ToString(); if (!string.IsNullOrEmpty(databaseName)) { diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/ObjectExplorer/NodeTests.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/ObjectExplorer/NodeTests.cs index 376cf1bb..89d5da11 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/ObjectExplorer/NodeTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/ObjectExplorer/NodeTests.cs @@ -1,369 +1,369 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System; -using System.Collections.Generic; -using System.Data.SqlClient; -using System.Globalization; -using Microsoft.SqlServer.Management.Common; -using Microsoft.SqlServer.Management.Smo; -using Microsoft.SqlTools.Extensibility; -using Microsoft.SqlTools.ServiceLayer.Connection; -using Microsoft.SqlTools.ServiceLayer.Connection.Contracts; -using Microsoft.SqlTools.ServiceLayer.ObjectExplorer; -using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts; -using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; -using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel; -using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility; -using Moq; -using Xunit; - -namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer -{ - /// - /// Tests covering basic operation of Node based classes - /// - public class NodeTests : ObjectExplorerTestBase - { - private string defaultOwnerUri = "objectexplorer://myserver"; - private ServerInfo defaultServerInfo; - private ConnectionDetails defaultConnectionDetails; - private ConnectionCompleteParams defaultConnParams; - private string fakeConnectionString = "Data Source=server;Initial Catalog=database;Integrated Security=False;User Id=user"; - - public NodeTests() - { - defaultServerInfo = TestObjects.GetTestServerInfo(); - - defaultConnectionDetails = new ConnectionDetails() - { - DatabaseName = "master", - ServerName = "localhost", - UserName = "serverAdmin", - Password = "..." - }; - defaultConnParams = new ConnectionCompleteParams() - { - ServerInfo = defaultServerInfo, - ConnectionSummary = defaultConnectionDetails, - OwnerUri = defaultOwnerUri - }; - - // TODO can all tests use the standard service provider? - ServiceProvider = ExtensionServiceProvider.CreateDefaultServiceProvider(); - } - - [Fact] - public void ServerNodeConstructorValidatesFields() - { - Assert.Throws(() => new ServerNode(null, ServiceProvider)); - Assert.Throws(() => new ServerNode(defaultConnParams, null)); - } - - [Fact] - public void ServerNodeConstructorShouldSetValuesCorrectly() - { - // Given a server node with valid inputs - ServerNode node = new ServerNode(defaultConnParams, ServiceProvider); - // Then expect all fields set correctly - Assert.False(node.IsAlwaysLeaf, "Server node should never be a leaf"); - Assert.Equal(defaultConnectionDetails.ServerName, node.NodeValue); - - string expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + " - " - + defaultConnectionDetails.UserName + ")"; - Assert.Equal(expectedLabel, node.Label); - - Assert.Equal(NodeTypes.Server.ToString(), node.NodeType); - string[] nodePath = node.GetNodePath().Split(TreeNode.PathPartSeperator); - Assert.Equal(1, nodePath.Length); - Assert.Equal(defaultConnectionDetails.ServerName, nodePath[0]); - } - - [Fact] - public void ServerNodeLabelShouldIgnoreUserNameIfEmptyOrNull() - { - // Given no username set - ConnectionSummary integratedAuthSummary = new ConnectionSummary() - { - DatabaseName = defaultConnectionDetails.DatabaseName, - ServerName = defaultConnectionDetails.ServerName, - UserName = null - }; - ConnectionCompleteParams connParams = new ConnectionCompleteParams() - { - ConnectionSummary = integratedAuthSummary, - ServerInfo = defaultServerInfo, - OwnerUri = defaultOwnerUri - }; - // When querying label - string label = new ServerNode(connParams, ServiceProvider).Label; - // Then only server name and version shown - string expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + ")"; - Assert.Equal(expectedLabel, label); - } - - [Fact] - public void ServerNodeConstructorShouldShowDbNameForCloud() - { - defaultServerInfo.IsCloud = true; - - // Given a server node for a cloud DB, with master name - ServerNode node = new ServerNode(defaultConnParams, ServiceProvider); - // Then expect label to not include db name - string expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + " - " - + defaultConnectionDetails.UserName + ")"; - Assert.Equal(expectedLabel, node.Label); - - // But given a server node for a cloud DB that's not master - defaultConnectionDetails.DatabaseName = "NotMaster"; - node = new ServerNode(defaultConnParams, ServiceProvider); - - // Then expect label to include db name - expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + " - " - + defaultConnectionDetails.UserName + ", " + defaultConnectionDetails.DatabaseName + ")"; - Assert.Equal(expectedLabel, node.Label); - } - - [Fact] - public void ToNodeInfoIncludeAllFields() - { - // Given a server connection - ServerNode node = new ServerNode(defaultConnParams, ServiceProvider); - // When converting to NodeInfo - NodeInfo info = node.ToNodeInfo(); - // Then all fields should match - Assert.Equal(node.IsAlwaysLeaf, info.IsLeaf); - Assert.Equal(node.Label, info.Label); - Assert.Equal(node.NodeType, info.NodeType); - string[] nodePath = node.GetNodePath().Split(TreeNode.PathPartSeperator); - string[] nodeInfoPathParts = info.NodePath.Split(TreeNode.PathPartSeperator); - Assert.Equal(nodePath.Length, nodeInfoPathParts.Length); - for (int i = 0; i < nodePath.Length; i++) - { - Assert.Equal(nodePath[i], nodeInfoPathParts[i]); - } - } - - [Fact] - public void AddChildShouldSetParent() - { - TreeNode parent = new TreeNode("parent"); - TreeNode child = new TreeNode("child"); - Assert.Null(child.Parent); - parent.AddChild(child); - Assert.Equal(parent, child.Parent); - } - - [Fact] - public void GetChildrenShouldReturnReadonlyList() - { - TreeNode node = new TreeNode("parent"); - IList children = node.GetChildren(); - Assert.Throws(() => children.Add(new TreeNode("child"))); - } - - [Fact] - public void GetChildrenShouldReturnAddedNodesInOrder() - { - TreeNode parent = new TreeNode("parent"); - TreeNode[] expectedKids = new TreeNode[] { new TreeNode("1"), new TreeNode("2") }; - foreach (TreeNode child in expectedKids) - { - parent.AddChild(child); - } - IList children = parent.GetChildren(); - Assert.Equal(expectedKids.Length, children.Count); - for (int i = 0; i < expectedKids.Length; i++) - { - Assert.Equal(expectedKids[i], children[i]); - } - } - - public void MultiLevelTreeShouldFormatPath() - { - TreeNode root = new TreeNode("root"); - Assert.Equal("/root" , root.GetNodePath()); - - TreeNode level1Child1 = new TreeNode("L1C1"); - TreeNode level1Child2 = new TreeNode("L1C2"); - root.AddChild(level1Child1); - root.AddChild(level1Child2); - Assert.Equal("/root/L1C1" , level1Child1.GetNodePath()); - Assert.Equal("/root/L1C2", level1Child2.GetNodePath()); - - TreeNode level2Child1 = new TreeNode("L2C2"); - level1Child1.AddChild(level2Child1); - Assert.Equal("/root/L1C1/L2C2", level2Child1.GetNodePath()); - } - - [Fact] - public void ServerNodeContextShouldIncludeServer() - { - // given a successful Server creation - SetupAndRegisterTestConnectionService(); - Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString))); - ServerNode node = SetupServerNodeWithServer(smoServer); - - // When I get the context for a ServerNode - var context = node.GetContextAs(); - - // Then I expect it to contain the server I created - Assert.NotNull(context); - Assert.Equal(smoServer, context.Server); - // And the server should be the parent - Assert.Equal(smoServer, context.Parent); - Assert.Null(context.Database); - } - - [Fact] - public void ServerNodeContextShouldSetErrorMessageIfSqlConnectionIsNull() - { - // given a connectionInfo with no SqlConnection to use for queries - ConnectionService connService = SetupAndRegisterTestConnectionService(); - connService.OwnerToConnectionMap.Remove(defaultOwnerUri); - - Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString))); - ServerNode node = SetupServerNodeWithServer(smoServer); - - // When I get the context for a ServerNode - var context = node.GetContextAs(); - - // Then I expect it to be in an error state - Assert.Null(context); - Assert.Equal( - string.Format(CultureInfo.CurrentCulture, SR.ServerNodeConnectionError, defaultConnectionDetails.ServerName), - node.ErrorStateMessage); - } - - [Fact] - public void ServerNodeContextShouldSetErrorMessageIfConnFailureExceptionThrown() - { - // given a connectionInfo with no SqlConnection to use for queries - SetupAndRegisterTestConnectionService(); - - Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString))); - string expectedMsg = "ConnFailed!"; - ServerNode node = SetupServerNodeWithExceptionCreator(new ConnectionFailureException(expectedMsg)); - - // When I get the context for a ServerNode - var context = node.GetContextAs(); - - // Then I expect it to be in an error state - Assert.Null(context); - Assert.Equal( - string.Format(CultureInfo.CurrentCulture, SR.TreeNodeError, expectedMsg), - node.ErrorStateMessage); - } - - [Fact] - public void ServerNodeContextShouldSetErrorMessageIfExceptionThrown() - { - // given a connectionInfo with no SqlConnection to use for queries - SetupAndRegisterTestConnectionService(); - - Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString))); - string expectedMsg = "Failed!"; - ServerNode node = SetupServerNodeWithExceptionCreator(new Exception(expectedMsg)); - - // When I get the context for a ServerNode - var context = node.GetContextAs(); - - // Then I expect it to be in an error state - Assert.Null(context); - Assert.Equal( - string.Format(CultureInfo.CurrentCulture, SR.TreeNodeError, expectedMsg), - node.ErrorStateMessage); - } - - private ConnectionService SetupAndRegisterTestConnectionService() - { - ConnectionService connService = TestObjects.GetTestConnectionService(); - ConnectionInfo connectionInfo = new ConnectionInfo(TestObjects.GetTestSqlConnectionFactory(), - defaultOwnerUri, defaultConnectionDetails); - connectionInfo.AddConnection("Default", new SqlConnection()); - - connService.OwnerToConnectionMap.Add(defaultOwnerUri, connectionInfo); - ServiceProvider.RegisterSingleService(connService); - return connService; - } - - private ServerNode SetupServerNodeWithServer(Server smoServer) - { - Mock creator = new Mock(); - creator.Setup(c => c.Create(It.IsAny())) - .Returns(() => smoServer); - ServerNode node = SetupServerNodeWithCreator(creator.Object); - return node; - } - - private ServerNode SetupServerNodeWithExceptionCreator(Exception ex) - { - Mock creator = new Mock(); - creator.Setup(c => c.Create(It.IsAny())) - .Throws(ex); - - ServerNode node = SetupServerNodeWithCreator(creator.Object); - return node; - } - - private ServerNode SetupServerNodeWithCreator(SmoServerCreator creator) - { - ServerNode node = new ServerNode(defaultConnParams, ServiceProvider); - node.ServerCreator = creator; - return node; - } - - [Fact] - public void ServerNodeChildrenShouldIncludeFoldersAndDatabases() - { - // Given a server with 1 database - SetupAndRegisterTestConnectionService(); - ServiceProvider.RegisterSingleService(new ObjectExplorerService()); - - string dbName = "DB1"; - Mock smoObjectMock = new Mock(); - smoObjectMock.SetupGet(s => s.Name).Returns(dbName); - - Mock querierMock = new Mock(); - querierMock.Setup(q => q.Query(It.IsAny())) - .Returns(smoObjectMock.Object.SingleItemAsEnumerable()); - - ServiceProvider.Register(() => new[] { querierMock.Object }); - - Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString))); - ServerNode node = SetupServerNodeWithServer(smoServer); - - // When I populate its children - IList children = node.Expand(); - - // Then I expect it to contain server-level folders - Assert.Equal(3, children.Count); - VerifyTreeNode(children[0], "Folder", SR.SchemaHierarchy_Databases); - VerifyTreeNode(children[1], "Folder", SR.SchemaHierarchy_Security); - VerifyTreeNode(children[2], "Folder", SR.SchemaHierarchy_ServerObjects); - // And the database is contained under it - TreeNode databases = children[0]; - IList dbChildren = databases.Expand(); - Assert.Equal(2, dbChildren.Count); - Assert.Equal(SR.SchemaHierarchy_SystemDatabases, dbChildren[0].NodeValue); - - TreeNode dbNode = dbChildren[1]; - Assert.Equal(dbName, dbNode.NodeValue); - Assert.Equal(dbName, dbNode.Label); - 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 - } - - private void VerifyTreeNode(TreeNode node, string nodeType, string folderValue) - where T : TreeNode - { - T nodeAsT = node as T; - Assert.NotNull(nodeAsT); - Assert.Equal(nodeType, nodeAsT.NodeType); - Assert.Equal(folderValue, nodeAsT.NodeValue); - } - } -} +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System; +using System.Collections.Generic; +using System.Data.SqlClient; +using System.Globalization; +using Microsoft.SqlServer.Management.Common; +using Microsoft.SqlServer.Management.Smo; +using Microsoft.SqlTools.Extensibility; +using Microsoft.SqlTools.ServiceLayer.Connection; +using Microsoft.SqlTools.ServiceLayer.Connection.Contracts; +using Microsoft.SqlTools.ServiceLayer.ObjectExplorer; +using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts; +using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; +using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel; +using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility; +using Moq; +using Xunit; + +namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer +{ + /// + /// Tests covering basic operation of Node based classes + /// + public class NodeTests : ObjectExplorerTestBase + { + private string defaultOwnerUri = "objectexplorer://myserver"; + private ServerInfo defaultServerInfo; + private ConnectionDetails defaultConnectionDetails; + private ConnectionCompleteParams defaultConnParams; + private string fakeConnectionString = "Data Source=server;Initial Catalog=database;Integrated Security=False;User Id=user"; + + public NodeTests() + { + defaultServerInfo = TestObjects.GetTestServerInfo(); + + defaultConnectionDetails = new ConnectionDetails() + { + DatabaseName = "master", + ServerName = "localhost", + UserName = "serverAdmin", + Password = "..." + }; + defaultConnParams = new ConnectionCompleteParams() + { + ServerInfo = defaultServerInfo, + ConnectionSummary = defaultConnectionDetails, + OwnerUri = defaultOwnerUri + }; + + // TODO can all tests use the standard service provider? + ServiceProvider = ExtensionServiceProvider.CreateDefaultServiceProvider(); + } + + [Fact] + public void ServerNodeConstructorValidatesFields() + { + Assert.Throws(() => new ServerNode(null, ServiceProvider)); + Assert.Throws(() => new ServerNode(defaultConnParams, null)); + } + + [Fact] + public void ServerNodeConstructorShouldSetValuesCorrectly() + { + // Given a server node with valid inputs + ServerNode node = new ServerNode(defaultConnParams, ServiceProvider); + // Then expect all fields set correctly + Assert.False(node.IsAlwaysLeaf, "Server node should never be a leaf"); + Assert.Equal(defaultConnectionDetails.ServerName, node.NodeValue); + + string expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + " - " + + defaultConnectionDetails.UserName + ")"; + Assert.Equal(expectedLabel, node.Label); + + Assert.Equal(NodeTypes.Server.ToString(), node.NodeType); + string[] nodePath = node.GetNodePath().Split(TreeNode.PathPartSeperator); + Assert.Equal(1, nodePath.Length); + Assert.Equal(defaultConnectionDetails.ServerName, nodePath[0]); + } + + [Fact] + public void ServerNodeLabelShouldIgnoreUserNameIfEmptyOrNull() + { + // Given no username set + ConnectionSummary integratedAuthSummary = new ConnectionSummary() + { + DatabaseName = defaultConnectionDetails.DatabaseName, + ServerName = defaultConnectionDetails.ServerName, + UserName = null + }; + ConnectionCompleteParams connParams = new ConnectionCompleteParams() + { + ConnectionSummary = integratedAuthSummary, + ServerInfo = defaultServerInfo, + OwnerUri = defaultOwnerUri + }; + // When querying label + string label = new ServerNode(connParams, ServiceProvider).Label; + // Then only server name and version shown + string expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + ")"; + Assert.Equal(expectedLabel, label); + } + + [Fact] + public void ServerNodeConstructorShouldShowDbNameForCloud() + { + defaultServerInfo.IsCloud = true; + + // Given a server node for a cloud DB, with master name + ServerNode node = new ServerNode(defaultConnParams, ServiceProvider); + // Then expect label to not include db name + string expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + " - " + + defaultConnectionDetails.UserName + ")"; + Assert.Equal(expectedLabel, node.Label); + + // But given a server node for a cloud DB that's not master + defaultConnectionDetails.DatabaseName = "NotMaster"; + node = new ServerNode(defaultConnParams, ServiceProvider); + + // Then expect label to include db name + expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + " - " + + defaultConnectionDetails.UserName + ", " + defaultConnectionDetails.DatabaseName + ")"; + Assert.Equal(expectedLabel, node.Label); + } + + [Fact] + public void ToNodeInfoIncludeAllFields() + { + // Given a server connection + ServerNode node = new ServerNode(defaultConnParams, ServiceProvider); + // When converting to NodeInfo + NodeInfo info = node.ToNodeInfo(); + // Then all fields should match + Assert.Equal(node.IsAlwaysLeaf, info.IsLeaf); + Assert.Equal(node.Label, info.Label); + Assert.Equal(node.NodeType, info.NodeType); + string[] nodePath = node.GetNodePath().Split(TreeNode.PathPartSeperator); + string[] nodeInfoPathParts = info.NodePath.Split(TreeNode.PathPartSeperator); + Assert.Equal(nodePath.Length, nodeInfoPathParts.Length); + for (int i = 0; i < nodePath.Length; i++) + { + Assert.Equal(nodePath[i], nodeInfoPathParts[i]); + } + } + + [Fact] + public void AddChildShouldSetParent() + { + TreeNode parent = new TreeNode("parent"); + TreeNode child = new TreeNode("child"); + Assert.Null(child.Parent); + parent.AddChild(child); + Assert.Equal(parent, child.Parent); + } + + [Fact] + public void GetChildrenShouldReturnReadonlyList() + { + TreeNode node = new TreeNode("parent"); + IList children = node.GetChildren(); + Assert.Throws(() => children.Add(new TreeNode("child"))); + } + + [Fact] + public void GetChildrenShouldReturnAddedNodesInOrder() + { + TreeNode parent = new TreeNode("parent"); + TreeNode[] expectedKids = new TreeNode[] { new TreeNode("1"), new TreeNode("2") }; + foreach (TreeNode child in expectedKids) + { + parent.AddChild(child); + } + IList children = parent.GetChildren(); + Assert.Equal(expectedKids.Length, children.Count); + for (int i = 0; i < expectedKids.Length; i++) + { + Assert.Equal(expectedKids[i], children[i]); + } + } + + public void MultiLevelTreeShouldFormatPath() + { + TreeNode root = new TreeNode("root"); + Assert.Equal("/root" , root.GetNodePath()); + + TreeNode level1Child1 = new TreeNode("L1C1"); + TreeNode level1Child2 = new TreeNode("L1C2"); + root.AddChild(level1Child1); + root.AddChild(level1Child2); + Assert.Equal("/root/L1C1" , level1Child1.GetNodePath()); + Assert.Equal("/root/L1C2", level1Child2.GetNodePath()); + + TreeNode level2Child1 = new TreeNode("L2C2"); + level1Child1.AddChild(level2Child1); + Assert.Equal("/root/L1C1/L2C2", level2Child1.GetNodePath()); + } + + [Fact] + public void ServerNodeContextShouldIncludeServer() + { + // given a successful Server creation + SetupAndRegisterTestConnectionService(); + Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString))); + ServerNode node = SetupServerNodeWithServer(smoServer); + + // When I get the context for a ServerNode + var context = node.GetContextAs(); + + // Then I expect it to contain the server I created + Assert.NotNull(context); + Assert.Equal(smoServer, context.Server); + // And the server should be the parent + Assert.Equal(smoServer, context.Parent); + Assert.Null(context.Database); + } + + [Fact] + public void ServerNodeContextShouldSetErrorMessageIfSqlConnectionIsNull() + { + // given a connectionInfo with no SqlConnection to use for queries + ConnectionService connService = SetupAndRegisterTestConnectionService(); + connService.OwnerToConnectionMap.Remove(defaultOwnerUri); + + Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString))); + ServerNode node = SetupServerNodeWithServer(smoServer); + + // When I get the context for a ServerNode + var context = node.GetContextAs(); + + // Then I expect it to be in an error state + Assert.Null(context); + Assert.Equal( + string.Format(CultureInfo.CurrentCulture, SR.ServerNodeConnectionError, defaultConnectionDetails.ServerName), + node.ErrorStateMessage); + } + + [Fact] + public void ServerNodeContextShouldSetErrorMessageIfConnFailureExceptionThrown() + { + // given a connectionInfo with no SqlConnection to use for queries + SetupAndRegisterTestConnectionService(); + + Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString))); + string expectedMsg = "ConnFailed!"; + ServerNode node = SetupServerNodeWithExceptionCreator(new ConnectionFailureException(expectedMsg)); + + // When I get the context for a ServerNode + var context = node.GetContextAs(); + + // Then I expect it to be in an error state + Assert.Null(context); + Assert.Equal( + string.Format(CultureInfo.CurrentCulture, SR.TreeNodeError, expectedMsg), + node.ErrorStateMessage); + } + + [Fact] + public void ServerNodeContextShouldSetErrorMessageIfExceptionThrown() + { + // given a connectionInfo with no SqlConnection to use for queries + SetupAndRegisterTestConnectionService(); + + Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString))); + string expectedMsg = "Failed!"; + ServerNode node = SetupServerNodeWithExceptionCreator(new Exception(expectedMsg)); + + // When I get the context for a ServerNode + var context = node.GetContextAs(); + + // Then I expect it to be in an error state + Assert.Null(context); + Assert.Equal( + string.Format(CultureInfo.CurrentCulture, SR.TreeNodeError, expectedMsg), + node.ErrorStateMessage); + } + + private ConnectionService SetupAndRegisterTestConnectionService() + { + ConnectionService connService = TestObjects.GetTestConnectionService(); + ConnectionInfo connectionInfo = new ConnectionInfo(TestObjects.GetTestSqlConnectionFactory(), + defaultOwnerUri, defaultConnectionDetails); + connectionInfo.AddConnection("Default", new SqlConnection()); + + connService.OwnerToConnectionMap.Add(defaultOwnerUri, connectionInfo); + ServiceProvider.RegisterSingleService(connService); + return connService; + } + + private ServerNode SetupServerNodeWithServer(Server smoServer) + { + Mock creator = new Mock(); + creator.Setup(c => c.Create(It.IsAny())) + .Returns(() => smoServer); + ServerNode node = SetupServerNodeWithCreator(creator.Object); + return node; + } + + private ServerNode SetupServerNodeWithExceptionCreator(Exception ex) + { + Mock creator = new Mock(); + creator.Setup(c => c.Create(It.IsAny())) + .Throws(ex); + + ServerNode node = SetupServerNodeWithCreator(creator.Object); + return node; + } + + private ServerNode SetupServerNodeWithCreator(SmoServerCreator creator) + { + ServerNode node = new ServerNode(defaultConnParams, ServiceProvider); + node.ServerCreator = creator; + return node; + } + + [Fact] + public void ServerNodeChildrenShouldIncludeFoldersAndDatabases() + { + // Given a server with 1 database + SetupAndRegisterTestConnectionService(); + ServiceProvider.RegisterSingleService(new ObjectExplorerService()); + + string dbName = "DB1"; + Mock smoObjectMock = new Mock(); + smoObjectMock.SetupGet(s => s.Name).Returns(dbName); + + Mock querierMock = new Mock(); + querierMock.Setup(q => q.Query(It.IsAny(), "")) + .Returns(smoObjectMock.Object.SingleItemAsEnumerable()); + + ServiceProvider.Register(() => new[] { querierMock.Object }); + + Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString))); + ServerNode node = SetupServerNodeWithServer(smoServer); + + // When I populate its children + IList children = node.Expand(); + + // Then I expect it to contain server-level folders + Assert.Equal(3, children.Count); + VerifyTreeNode(children[0], "Folder", SR.SchemaHierarchy_Databases); + VerifyTreeNode(children[1], "Folder", SR.SchemaHierarchy_Security); + VerifyTreeNode(children[2], "Folder", SR.SchemaHierarchy_ServerObjects); + // And the database is contained under it + TreeNode databases = children[0]; + IList dbChildren = databases.Expand(); + Assert.Equal(2, dbChildren.Count); + Assert.Equal(SR.SchemaHierarchy_SystemDatabases, dbChildren[0].NodeValue); + + TreeNode dbNode = dbChildren[1]; + Assert.Equal(dbName, dbNode.NodeValue); + Assert.Equal(dbName, dbNode.Label); + 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 + } + + private void VerifyTreeNode(TreeNode node, string nodeType, string folderValue) + where T : TreeNode + { + T nodeAsT = node as T; + Assert.NotNull(nodeAsT); + Assert.Equal(nodeType, nodeAsT.NodeType); + Assert.Equal(folderValue, nodeAsT.NodeValue); + } + } +}