From c26a2aea142524c9dec4625448fe0f1ff2b2fcde Mon Sep 17 00:00:00 2001 From: Aasim Khan Date: Tue, 14 Feb 2023 13:40:51 -0800 Subject: [PATCH] Adding schema based object folders in OE (#1849) * Making node types automated * Adding schema based OE * added folder types in NodeTypes * Fixing stuff * Moving schema to parent and cleaning up some code * Replacing strings with nameof * Sorting nodetypes generated by tt * Adding option to put folders after nodes * Fixing folder and children order * Fixing tests * Formatting file * Formatting tt files * Fixing tt * fixing types * Update src/Microsoft.SqlTools.ServiceLayer/SqlContext/ObjectExplorerSettings.cs Co-authored-by: Charles Gagnon * Fixing stuff * Updating schema definitions and adding more logs * Fixing copyright * Adding Integration and Unit Tests * Fixing test --------- Co-authored-by: Charles Gagnon --- .../ObjectExplorer/Nodes/ChildFactory.cs | 6 + .../ObjectExplorer/Nodes/INodeFilter.cs | 27 +- .../ObjectExplorer/Nodes/NodeTypes.cs | 251 ++-- .../ObjectExplorer/Nodes/NodeTypes.tt | 117 ++ .../ObjectExplorer/SmoModel/FolderNode.cs | 6 + .../SmoModel/NodePathGenerator.cs | 2 +- .../SmoModel/SmoChildFactoryBase.cs | 20 +- .../ObjectExplorer/SmoModel/SmoQueryModel.cs | 315 +++++ .../ObjectExplorer/SmoModel/SmoQueryModel.tt | 562 ++++---- .../SmoModel/SmoQueryModelDefinition.xml | 121 +- .../ObjectExplorer/SmoModel/SmoTreeNodes.cs | 549 ++++---- .../ObjectExplorer/SmoModel/SmoTreeNodes.tt | 1132 +++++++++-------- .../SmoModel/SmoTreeNodesDefinition.xml | 29 +- .../SqlContext/ObjectExplorerSettings.cs | 8 + .../Workspace/WorkspaceService.cs | 1 + .../ObjectExplorerServiceTests.cs | 54 +- .../ObjectExplorer/GroupBySchemaTests.cs | 66 + .../ObjectExplorer/NodeFilterTests.cs | 25 + 18 files changed, 2068 insertions(+), 1223 deletions(-) create mode 100644 src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodeTypes.tt create mode 100644 test/Microsoft.SqlTools.ServiceLayer.UnitTests/ObjectExplorer/GroupBySchemaTests.cs diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/ChildFactory.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/ChildFactory.cs index 12e24595..45e9cd9b 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/ChildFactory.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/ChildFactory.cs @@ -71,5 +71,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes // TODO Consider whether Remove operations need to be supported //public abstract bool CanRemoveChild(TreeNode parent, object context); //public abstract int GetChildIndexToRemove(TreeNode parent, object context); + + /// + /// A flag that puts child folders after nodes when the node is expanded. + /// + /// + public virtual bool PutFoldersAfterNodes => false; } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/INodeFilter.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/INodeFilter.cs index d597f7c5..54668c41 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/INodeFilter.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/INodeFilter.cs @@ -3,11 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -#nullable disable - using System; using System.Collections.Generic; -//using System.Linq; +using System.Linq; using System.Text; namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes @@ -44,7 +42,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes { string andPrefix = filter.Length == 0 ? string.Empty : " and "; var filterString = value.ToPropertyFilterString(type, validForFlag); - if (filterString != string.Empty) { + if (filterString != string.Empty) + { filter.Append($"{andPrefix}{filterString}"); } } @@ -55,5 +54,25 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes } return string.Empty; } + + /// + /// Appends a list of property filters to an URN query string + /// + public static string AddPropertyFilterToFilterString(string filterString, IEnumerable filters, Type type, ValidForFlag validForFlag) + { + if (string.IsNullOrEmpty(filterString)) + { + return GetPropertyFilter(filters, type, validForFlag); + } + foreach (var value in filters ?? Enumerable.Empty()) + { + var filter = value.ToPropertyFilterString(type, validForFlag); + if (filter != string.Empty) + { + filterString = filterString.Remove(filterString.Length - 1, 1) + $" and {filter}" + "]"; + } + } + return filterString; + } } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodeTypes.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodeTypes.cs index 14fcc15a..aa491571 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodeTypes.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodeTypes.cs @@ -1,147 +1,142 @@ -// +// // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +// This file was generated by a T4 Template. Do not modify directly, instead update the SmoTreeNodesDefinition.xml file +// and re-run the T4 template. This can be done in Visual Studio by right-click in and choosing "Run Custom Tool", +// or from the command-line on any platform by running "build.cmd -Target=CodeGen" or "build.sh -Target=CodeGen" + namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes { /// /// Enum listing possible node types in the object explorer tree /// - // TODO Consider replacing this with an auto-gen'd version public enum NodeTypes { - None, - SqlServersRoot, - Database, - Server, - ScalarValuedFunction, - TableValuedFunction, AggregateFunction, - FileGroup, - StoredProcedure, - UserDefinedTableType, - View, - Table, - HistoryTable, - Folder, - Databases, - ExternalResources, - ServerLevelSecurity, - ServerLevelServerObjects, - ServerLevelManagement, - SystemDatabases, - ServerLevelLinkedServerLogins, - ServerLevelServerAudits, - ServerLevelCryptographicProviders, - ServerLevelCredentials, - ServerLevelServerRoles, - ServerLevelLogins, - ServerLevelEventSessions, - ServerLevelServerAuditSpecifications, - ServerLevelEventNotifications, - ServerLevelErrorMessages, - ServerLevelServerTriggers, - ServerLevelLinkedServers, - ServerLevelEndpoints, - SystemScalarValuedFunctions, - SystemTableValuedFunctions, - SystemFunctions, - DacInstancesFolder, - Tables, - Views, - Synonyms, - Programmability, - ServiceBroker, - Storage, - Security, - SystemTables, - FileTables, - SystemViews, - StoredProcedures, - Functions, - ExtendedStoredProcedures, - DatabaseTriggers, - Defaults, - Rules, - Types, - Assemblies, - MessageTypes, - Contracts, - Queues, - Services, - Routes, - DatabaseAndQueueEventNotifications, - RemoteServiceBindings, - BrokerPriorities, - FileGroups, - FullTextCatalogs, - FullTextStopLists, - SqlLogFiles, - PartitionFunctions, - PartitionSchemes, - SearchPropertyLists, - Users, - Roles, - Schemas, - AsymmetricKeys, - Certificates, - SymmetricKeys, - DatabaseEncryptionKeys, - MasterKeys, - Signatures, - DatabaseAuditSpecifications, - Columns, - Keys, - Constraints, - Triggers, - Indexes, - Statistics, - TableValuedFunctions, - ScalarValuedFunctions, - AggregateFunctions, - SystemDataTypes, - UserDefinedDataTypes, - UserDefinedTableTypes, - UserDefinedTypes, - XmlSchemaCollections, - SystemExactNumerics, - SystemApproximateNumerics, - SystemDateAndTimes, - SystemCharacterStrings, - SystemUnicodeCharacterStrings, - SystemBinaryStrings, - SystemOtherDataTypes, - SystemClrDataTypes, - SystemSpatialDataTypes, - UserDefinedTableTypeColumns, - UserDefinedTableTypeKeys, - UserDefinedTableTypeConstraints, - SystemStoredProcedures, - StoredProcedureParameters, - TableValuedFunctionParameters, - ScalarValuedFunctionParameters, AggregateFunctionParameters, - DatabaseRoles, - ApplicationRoles, - FileGroupFiles, - SystemMessageTypes, - SystemContracts, - SystemServices, - SystemQueues, - Sequences, - SecurityPolicies, - DatabaseScopedCredentials, - ExternalTables, - ExternalResource, - ExternalDataSources, - ExternalFileFormats, - ExternalTable, + AggregateFunctions, AlwaysEncryptedKeys, - ColumnMasterKeys, + ApplicationRoles, + Assemblies, + AsymmetricKeys, + BrokerPriorities, + Certificates, ColumnEncryptionKeys, + ColumnMasterKeys, + Columns, + Constraints, + Contracts, + Database, + DatabaseAndQueueEventNotifications, + DatabaseAuditSpecifications, + DatabaseEncryptionKeys, + DatabaseRoles, + Databases, + DatabaseScopedCredentials, + DatabaseTriggers, + DroppedLedgerColumns, DroppedLedgerTables, DroppedLedgerViews, - DroppedLedgerColumns, + ExpandableSchema, + ExpandableSchemaProgrammability, + ExternalDataSources, + ExternalFileFormats, + ExternalResource, + ExternalResources, + ExternalTable, + ExternalTables, + FileGroup, + FileGroupFiles, + FileGroups, + Folder, + FullTextCatalogs, + FullTextStopLists, + Functions, + HistoryTable, + Indexes, + Keys, + MasterKeys, + MessageTypes, + PartitionFunctions, + PartitionSchemes, + Programmability, + Queues, + RemoteServiceBindings, + Roles, + ScalarValuedFunction, + ScalarValuedFunctionParameters, + ScalarValuedFunctions, + Schemas, + SearchPropertyLists, + Security, + SecurityPolicies, + Sequences, + Server, + ServerLevelCredentials, + ServerLevelCryptographicProviders, + ServerLevelEndpoints, + ServerLevelErrorMessages, + ServerLevelLinkedServerLogins, + ServerLevelLinkedServers, + ServerLevelLogins, + ServerLevelSecurity, + ServerLevelServerAudits, + ServerLevelServerAuditSpecifications, + ServerLevelServerObjects, + ServerLevelServerRoles, + ServerLevelServerTriggers, + ServiceBroker, + Services, + Signatures, + SqlLogFiles, + Statistics, + Storage, + StoredProcedure, + StoredProcedureParameters, + StoredProcedures, + SymmetricKeys, + Synonyms, + SystemApproximateNumerics, + SystemBinaryStrings, + SystemCharacterStrings, + SystemClrDataTypes, + SystemContracts, + SystemDatabases, + SystemDataTypes, + SystemDateAndTimes, + SystemExactNumerics, + SystemFunctions, + SystemMessageTypes, + SystemOtherDataTypes, + SystemQueues, + SystemScalarValuedFunctions, + SystemServices, + SystemSpatialDataTypes, + SystemStoredProcedures, + SystemTables, + SystemTableValuedFunctions, + SystemUnicodeCharacterStrings, + SystemViews, + Table, + Tables, + TableValuedFunction, + TableValuedFunctionParameters, + TableValuedFunctions, + Triggers, + Types, + UserDefinedDataTypes, + UserDefinedTableType, + UserDefinedTableTypeColumns, + UserDefinedTableTypeConstraints, + UserDefinedTableTypeKeys, + UserDefinedTableTypes, + UserDefinedTypes, + Users, + View, + Views, + XmlSchemaCollections, } } + diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodeTypes.tt b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodeTypes.tt new file mode 100644 index 00000000..2b2a5efc --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodeTypes.tt @@ -0,0 +1,117 @@ +<#@ template debug="false" hostspecific="true" language="C#" #> +<#@ output extension=".cs" #> +<#@ assembly name="System.Xml.dll" #> +<#@ assembly name="System.Core.dll" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Globalization" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Xml" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.IO" #> +<#@ import namespace="System.Linq"#> +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +// This file was generated by a T4 Template. Do not modify directly, instead update the SmoTreeNodesDefinition.xml file +// and re-run the T4 template. This can be done in Visual Studio by right-click in and choosing "Run Custom Tool", +// or from the command-line on any platform by running "build.cmd -Target=CodeGen" or "build.sh -Target=CodeGen" + +namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes +{ + /// + /// Enum listing possible node types in the object explorer tree + /// + public enum NodeTypes + { +<# + var directory = Path.GetDirectoryName(Host.TemplateFile); + + string xmlFile = Path.Combine(directory, "..\\SmoModel\\SmoTreeNodesDefinition.xml"); + + var allTreeNodes = GetUniqueNodeTypes(xmlFile); + + foreach (var name in allTreeNodes) + { + WriteLine(" {0},", name); + } + +#> + } +} + +<#+ + public static List GetUniqueNodeTypes(string xmlFile) + { + XmlDocument doc = new XmlDocument(); + doc.Load(xmlFile); + + + // Adding all node types + HashSet retElements = new HashSet(); + XmlNodeList nodeList = doc.SelectNodes("/ServerExplorerTree/Node"); + foreach (XmlElement item in nodeList) + { + retElements.Add(item.GetAttribute("Name")); + foreach (XmlElement child in GetChildren(xmlFile, item.GetAttribute("Name"))) + { + retElements.Add(child.GetAttribute("Name")); + } + } + + // Adding UniqueTreeNodes + foreach(var name in GetUniqueTreeNodes(xmlFile)) + { + retElements.Add(name); + } + + // Adding types that are not present anywhere. These types are referred in tests. + retElements.Add("Folder"); + + var retList = retElements.ToList(); + retList.Sort(); + return retList; + } + + public static List GetChildren(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}']/Child", parentName)); + foreach (var item in nodeList) + { + XmlElement itemAsElement = item as XmlElement; + if (itemAsElement != null) + { + retElements.Add(itemAsElement); + } + } + return retElements; + } + + public static XmlElement GetNodeElement(string xmlFile, string nodeName) + { + XmlDocument doc = new XmlDocument(); + doc.Load(xmlFile); + return (XmlElement)doc.SelectSingleNode(string.Format("/ServerExplorerTree/Node[@Name='{0}']", nodeName)); + } + + public static List GetUniqueTreeNodes(string xmlFile) + { + XmlDocument doc = new XmlDocument(); + doc.Load(xmlFile); + + List retElements = new List(); + XmlNodeList nodeList = doc.SelectNodes("/ServerExplorerTree/CodeGenOptions/UniqueTreeNode"); + foreach (XmlElement item in nodeList) + { + retElements.Add(item.GetAttribute("Name").Replace("TreeNode", string.Empty)); + + } + return retElements; + } +#> \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/FolderNode.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/FolderNode.cs index 11ac8e8e..ede6aba9 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/FolderNode.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/FolderNode.cs @@ -6,6 +6,7 @@ #nullable disable using Microsoft.SqlServer.Management.Smo; +using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { @@ -14,6 +15,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel /// public class FolderNode : SmoTreeNode { + + public FolderNode() + { + this.NodeType = nameof(NodeTypes.Folder); + } /// /// For folders, this copies the context of its parent if available /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/NodePathGenerator.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/NodePathGenerator.cs index 25cebb98..85caccbf 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/NodePathGenerator.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/NodePathGenerator.cs @@ -125,7 +125,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel else { var returnSet = new HashSet(); - if (currentNode.ContainedType() == "Database") + if (currentNode.ContainedType() == "Database" || currentNode.ContainedType() == "ExpandableSchema") { path = databaseName + "/" + path; } diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoChildFactoryBase.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoChildFactoryBase.cs index dc491bcc..73b075b8 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoChildFactoryBase.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoChildFactoryBase.cs @@ -31,14 +31,24 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel try { - OnExpandPopulateFoldersAndFilter(allChildren, parent, includeSystemObjects); - RemoveFoldersFromInvalidSqlServerVersions(allChildren, parent); - OnExpandPopulateNonFolders(allChildren, parent, refresh, name, cancellationToken); + if (this.PutFoldersAfterNodes) + { + OnExpandPopulateNonFolders(allChildren, parent, refresh, name, cancellationToken); + OnExpandPopulateFoldersAndFilter(allChildren, parent, includeSystemObjects); + RemoveFoldersFromInvalidSqlServerVersions(allChildren, parent); + } + else + { + OnExpandPopulateFoldersAndFilter(allChildren, parent, includeSystemObjects); + RemoveFoldersFromInvalidSqlServerVersions(allChildren, parent); + OnExpandPopulateNonFolders(allChildren, parent, refresh, name, cancellationToken); + } + OnBeginAsyncOperations(parent); } - catch(Exception ex) + catch (Exception ex) { - string error = string.Format(CultureInfo.InvariantCulture, "Failed expanding oe children. parent:{0} error:{1} inner:{2} stacktrace:{3}", + string error = string.Format(CultureInfo.InvariantCulture, "Failed expanding oe children. parent:{0} error:{1} inner:{2} stacktrace:{3}", parent != null ? parent.GetNodePath() : "", ex.Message, ex.InnerException != null ? ex.InnerException.Message : "", ex.StackTrace); Logger.Write(TraceEventType.Error, error); throw; diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModel.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModel.cs index 89bb233d..7a6c311a 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModel.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModel.cs @@ -15,6 +15,7 @@ using System.Composition; using System.Linq; using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Smo.Broker; +using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; using Microsoft.SqlTools.Utility; using Index = Microsoft.SqlServer.Management.Smo.Index; @@ -34,6 +35,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Server parentServer = context.Parent as Server; if (parentServer != null) { + Logger.Verbose("Parent of type `Server` found"); var retValue = parentServer.Databases; if (retValue != null) { @@ -60,6 +62,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Server parentServer = context.Parent as Server; if (parentServer != null) { + Logger.Verbose("Parent of type `Server` found"); var retValue = parentServer.LinkedServers; if (retValue != null) { @@ -86,6 +89,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Server parentServer = context.Parent as Server; if (parentServer != null) { + Logger.Verbose("Parent of type `Server` found"); var retValue = parentServer.Logins; if (retValue != null) { @@ -112,6 +116,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Server parentServer = context.Parent as Server; if (parentServer != null) { + Logger.Verbose("Parent of type `Server` found"); var retValue = parentServer.Roles; if (retValue != null) { @@ -138,6 +143,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Server parentServer = context.Parent as Server; if (parentServer != null) { + Logger.Verbose("Parent of type `Server` found"); var retValue = parentServer.Credentials; if (retValue != null) { @@ -164,6 +170,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Server parentServer = context.Parent as Server; if (parentServer != null) { + Logger.Verbose("Parent of type `Server` found"); var retValue = parentServer.CryptographicProviders; if (retValue != null) { @@ -190,6 +197,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Server parentServer = context.Parent as Server; if (parentServer != null) { + Logger.Verbose("Parent of type `Server` found"); var retValue = parentServer.Audits; if (retValue != null) { @@ -216,6 +224,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Server parentServer = context.Parent as Server; if (parentServer != null) { + Logger.Verbose("Parent of type `Server` found"); var retValue = parentServer.ServerAuditSpecifications; if (retValue != null) { @@ -242,6 +251,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Server parentServer = context.Parent as Server; if (parentServer != null) { + Logger.Verbose("Parent of type `Server` found"); var retValue = parentServer.Endpoints; if (retValue != null) { @@ -268,6 +278,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Server parentServer = context.Parent as Server; if (parentServer != null) { + Logger.Verbose("Parent of type `Server` found"); var retValue = parentServer.LinkedServers; if (retValue != null) { @@ -297,6 +308,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Server parentServer = context.Parent as Server; if (parentServer != null) { + Logger.Verbose("Parent of type `Server` found"); var retValue = parentServer.Triggers; if (retValue != null) { @@ -323,6 +335,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Server parentServer = context.Parent as Server; if (parentServer != null) { + Logger.Verbose("Parent of type `Server` found"); var retValue = parentServer.UserDefinedMessages; if (retValue != null) { @@ -349,6 +362,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.Tables; if (retValue != null) { @@ -358,6 +372,28 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel return ret; } } + Schema parentSchema = context.Parent as Schema; + if (parentSchema != null) + { + Logger.Verbose("Parent of type `Schema` found"); + List filters = new List(); + filters.Add(new NodePropertyFilter() + { + Property = nameof(Schema), + Type = typeof(string), + Values = new List { parentSchema.Name }, + ValidFor = ValidForFlag.All + }); + filter = INodeFilter.AddPropertyFilterToFilterString(filter, filters, this.GetType(), context.ValidFor); + var retValue = parentSchema.Parent.Tables; + if (retValue != null) + { + retValue.ClearAndInitialize(filter, extraProperties); + var ret = new SmoCollectionWrapper(retValue).Where(c => PassesFinalFilters(parentSchema, c)); + Logger.Verbose("End query Table"); + return ret; + } + } return Enumerable.Empty(); } } @@ -375,6 +411,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Table parentTable = context.Parent as Table; if (parentTable != null) { + Logger.Verbose("Parent of type `Table` found"); var retValue = parentTable.Parent.Tables; if (retValue != null) { @@ -401,6 +438,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.Views; if (retValue != null) { @@ -410,6 +448,28 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel return ret; } } + Schema parentSchema = context.Parent as Schema; + if (parentSchema != null) + { + Logger.Verbose("Parent of type `Schema` found"); + List filters = new List(); + filters.Add(new NodePropertyFilter() + { + Property = nameof(Schema), + Type = typeof(string), + Values = new List { parentSchema.Name }, + ValidFor = ValidForFlag.All + }); + filter = INodeFilter.AddPropertyFilterToFilterString(filter, filters, this.GetType(), context.ValidFor); + var retValue = parentSchema.Parent.Views; + if (retValue != null) + { + retValue.ClearAndInitialize(filter, extraProperties); + var ret = new SmoCollectionWrapper(retValue).Where(c => PassesFinalFilters(parentSchema, c)); + Logger.Verbose("End query View"); + return ret; + } + } return Enumerable.Empty(); } } @@ -430,6 +490,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.Synonyms; if (retValue != null) { @@ -439,6 +500,28 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel return ret; } } + Schema parentSchema = context.Parent as Schema; + if (parentSchema != null) + { + Logger.Verbose("Parent of type `Schema` found"); + List filters = new List(); + filters.Add(new NodePropertyFilter() + { + Property = nameof(Schema), + Type = typeof(string), + Values = new List { parentSchema.Name }, + ValidFor = ValidForFlag.All + }); + filter = INodeFilter.AddPropertyFilterToFilterString(filter, filters, this.GetType(), context.ValidFor); + var retValue = parentSchema.Parent.Synonyms; + if (retValue != null) + { + retValue.ClearAndInitialize(filter, extraProperties); + var ret = new SmoCollectionWrapper(retValue).Where(c => PassesFinalFilters(parentSchema, c)); + Logger.Verbose("End query Synonym"); + return ret; + } + } return Enumerable.Empty(); } } @@ -456,6 +539,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel TableViewTableTypeBase parentTableViewTableTypeBase = context.Parent as TableViewTableTypeBase; if (parentTableViewTableTypeBase != null) { + Logger.Verbose("Parent of type `TableViewTableTypeBase` found"); var retValue = parentTableViewTableTypeBase.Columns; if (retValue != null) { @@ -482,6 +566,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel TableViewTableTypeBase parentTableViewTableTypeBase = context.Parent as TableViewTableTypeBase; if (parentTableViewTableTypeBase != null) { + Logger.Verbose("Parent of type `TableViewTableTypeBase` found"); var retValue = parentTableViewTableTypeBase.Indexes; if (retValue != null) { @@ -508,6 +593,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Table parentTable = context.Parent as Table; if (parentTable != null) { + Logger.Verbose("Parent of type `Table` found"); var retValue = parentTable.Checks; if (retValue != null) { @@ -534,6 +620,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Table parentTable = context.Parent as Table; if (parentTable != null) { + Logger.Verbose("Parent of type `Table` found"); var retValue = parentTable.ForeignKeys; if (retValue != null) { @@ -560,6 +647,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Table parentTable = context.Parent as Table; if (parentTable != null) { + Logger.Verbose("Parent of type `Table` found"); var retValue = parentTable.Columns; if (retValue != null) { @@ -581,6 +669,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel UserDefinedTableType parentUserDefinedTableType = context.Parent as UserDefinedTableType; if (parentUserDefinedTableType != null) { + Logger.Verbose("Parent of type `UserDefinedTableType` found"); var retValue = parentUserDefinedTableType.Columns; if (retValue != null) { @@ -619,6 +708,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Table parentTable = context.Parent as Table; if (parentTable != null) { + Logger.Verbose("Parent of type `Table` found"); var retValue = parentTable.Triggers; if (retValue != null) { @@ -631,6 +721,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel View parentView = context.Parent as View; if (parentView != null) { + Logger.Verbose("Parent of type `View` found"); var retValue = parentView.Triggers; if (retValue != null) { @@ -660,6 +751,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Table parentTable = context.Parent as Table; if (parentTable != null) { + Logger.Verbose("Parent of type `Table` found"); var retValue = parentTable.FullTextIndex; if (retValue != null) { @@ -687,6 +779,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel TableViewBase parentTableViewBase = context.Parent as TableViewBase; if (parentTableViewBase != null) { + Logger.Verbose("Parent of type `TableViewBase` found"); var retValue = parentTableViewBase.Statistics; if (retValue != null) { @@ -716,6 +809,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.Triggers; if (retValue != null) { @@ -742,6 +836,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.Assemblies; if (retValue != null) { @@ -768,6 +863,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.Sequences; if (retValue != null) { @@ -777,6 +873,28 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel return ret; } } + Schema parentSchema = context.Parent as Schema; + if (parentSchema != null) + { + Logger.Verbose("Parent of type `Schema` found"); + List filters = new List(); + filters.Add(new NodePropertyFilter() + { + Property = nameof(Schema), + Type = typeof(string), + Values = new List { parentSchema.Name }, + ValidFor = ValidForFlag.All + }); + filter = INodeFilter.AddPropertyFilterToFilterString(filter, filters, this.GetType(), context.ValidFor); + var retValue = parentSchema.Parent.Sequences; + if (retValue != null) + { + retValue.ClearAndInitialize(filter, extraProperties); + var ret = new SmoCollectionWrapper(retValue).Where(c => PassesFinalFilters(parentSchema, c)); + Logger.Verbose("End query Sequence"); + return ret; + } + } return Enumerable.Empty(); } } @@ -797,6 +915,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.UserDefinedDataTypes; if (retValue != null) { @@ -806,6 +925,28 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel return ret; } } + Schema parentSchema = context.Parent as Schema; + if (parentSchema != null) + { + Logger.Verbose("Parent of type `Schema` found"); + List filters = new List(); + filters.Add(new NodePropertyFilter() + { + Property = nameof(Schema), + Type = typeof(string), + Values = new List { parentSchema.Name }, + ValidFor = ValidForFlag.All + }); + filter = INodeFilter.AddPropertyFilterToFilterString(filter, filters, this.GetType(), context.ValidFor); + var retValue = parentSchema.Parent.UserDefinedDataTypes; + if (retValue != null) + { + retValue.ClearAndInitialize(filter, extraProperties); + var ret = new SmoCollectionWrapper(retValue).Where(c => PassesFinalFilters(parentSchema, c)); + Logger.Verbose("End query UserDefinedDataType"); + return ret; + } + } return Enumerable.Empty(); } } @@ -823,6 +964,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.UserDefinedTableTypes; if (retValue != null) { @@ -832,6 +974,28 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel return ret; } } + Schema parentSchema = context.Parent as Schema; + if (parentSchema != null) + { + Logger.Verbose("Parent of type `Schema` found"); + List filters = new List(); + filters.Add(new NodePropertyFilter() + { + Property = nameof(Schema), + Type = typeof(string), + Values = new List { parentSchema.Name }, + ValidFor = ValidForFlag.All + }); + filter = INodeFilter.AddPropertyFilterToFilterString(filter, filters, this.GetType(), context.ValidFor); + var retValue = parentSchema.Parent.UserDefinedTableTypes; + if (retValue != null) + { + retValue.ClearAndInitialize(filter, extraProperties); + var ret = new SmoCollectionWrapper(retValue).Where(c => PassesFinalFilters(parentSchema, c)); + Logger.Verbose("End query UserDefinedTableType"); + return ret; + } + } return Enumerable.Empty(); } } @@ -849,6 +1013,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.XmlSchemaCollections; if (retValue != null) { @@ -858,6 +1023,28 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel return ret; } } + Schema parentSchema = context.Parent as Schema; + if (parentSchema != null) + { + Logger.Verbose("Parent of type `Schema` found"); + List filters = new List(); + filters.Add(new NodePropertyFilter() + { + Property = nameof(Schema), + Type = typeof(string), + Values = new List { parentSchema.Name }, + ValidFor = ValidForFlag.All + }); + filter = INodeFilter.AddPropertyFilterToFilterString(filter, filters, this.GetType(), context.ValidFor); + var retValue = parentSchema.Parent.XmlSchemaCollections; + if (retValue != null) + { + retValue.ClearAndInitialize(filter, extraProperties); + var ret = new SmoCollectionWrapper(retValue).Where(c => PassesFinalFilters(parentSchema, c)); + Logger.Verbose("End query XmlSchemaCollection"); + return ret; + } + } return Enumerable.Empty(); } } @@ -875,6 +1062,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.UserDefinedTypes; if (retValue != null) { @@ -884,6 +1072,28 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel return ret; } } + Schema parentSchema = context.Parent as Schema; + if (parentSchema != null) + { + Logger.Verbose("Parent of type `Schema` found"); + List filters = new List(); + filters.Add(new NodePropertyFilter() + { + Property = nameof(Schema), + Type = typeof(string), + Values = new List { parentSchema.Name }, + ValidFor = ValidForFlag.All + }); + filter = INodeFilter.AddPropertyFilterToFilterString(filter, filters, this.GetType(), context.ValidFor); + var retValue = parentSchema.Parent.UserDefinedTypes; + if (retValue != null) + { + retValue.ClearAndInitialize(filter, extraProperties); + var ret = new SmoCollectionWrapper(retValue).Where(c => PassesFinalFilters(parentSchema, c)); + Logger.Verbose("End query UserDefinedType"); + return ret; + } + } return Enumerable.Empty(); } } @@ -901,6 +1111,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.UserDefinedFunctions; if (retValue != null) { @@ -910,6 +1121,28 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel return ret; } } + Schema parentSchema = context.Parent as Schema; + if (parentSchema != null) + { + Logger.Verbose("Parent of type `Schema` found"); + List filters = new List(); + filters.Add(new NodePropertyFilter() + { + Property = nameof(Schema), + Type = typeof(string), + Values = new List { parentSchema.Name }, + ValidFor = ValidForFlag.All + }); + filter = INodeFilter.AddPropertyFilterToFilterString(filter, filters, this.GetType(), context.ValidFor); + var retValue = parentSchema.Parent.UserDefinedFunctions; + if (retValue != null) + { + retValue.ClearAndInitialize(filter, extraProperties); + var ret = new SmoCollectionWrapper(retValue).Where(c => PassesFinalFilters(parentSchema, c)); + Logger.Verbose("End query UserDefinedFunction"); + return ret; + } + } return Enumerable.Empty(); } } @@ -927,6 +1160,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.UserDefinedAggregates; if (retValue != null) { @@ -936,6 +1170,28 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel return ret; } } + Schema parentSchema = context.Parent as Schema; + if (parentSchema != null) + { + Logger.Verbose("Parent of type `Schema` found"); + List filters = new List(); + filters.Add(new NodePropertyFilter() + { + Property = nameof(Schema), + Type = typeof(string), + Values = new List { parentSchema.Name }, + ValidFor = ValidForFlag.All + }); + filter = INodeFilter.AddPropertyFilterToFilterString(filter, filters, this.GetType(), context.ValidFor); + var retValue = parentSchema.Parent.UserDefinedAggregates; + if (retValue != null) + { + retValue.ClearAndInitialize(filter, extraProperties); + var ret = new SmoCollectionWrapper(retValue).Where(c => PassesFinalFilters(parentSchema, c)); + Logger.Verbose("End query UserDefinedAggregate"); + return ret; + } + } return Enumerable.Empty(); } } @@ -953,6 +1209,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.FileGroups; if (retValue != null) { @@ -979,6 +1236,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel FileGroup parentFileGroup = context.Parent as FileGroup; if (parentFileGroup != null) { + Logger.Verbose("Parent of type `FileGroup` found"); var retValue = parentFileGroup.Files; if (retValue != null) { @@ -1005,6 +1263,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.FullTextCatalogs; if (retValue != null) { @@ -1031,6 +1290,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.FullTextStopLists; if (retValue != null) { @@ -1057,6 +1317,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.PartitionFunctions; if (retValue != null) { @@ -1083,6 +1344,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.PartitionSchemes; if (retValue != null) { @@ -1109,6 +1371,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.SearchPropertyLists; if (retValue != null) { @@ -1135,6 +1398,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.Users; if (retValue != null) { @@ -1161,6 +1425,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.Schemas; if (retValue != null) { @@ -1187,6 +1452,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.AsymmetricKeys; if (retValue != null) { @@ -1213,6 +1479,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.Certificates; if (retValue != null) { @@ -1239,6 +1506,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.SymmetricKeys; if (retValue != null) { @@ -1265,6 +1533,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.DatabaseEncryptionKey; if (retValue != null) { @@ -1292,6 +1561,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.MasterKey; if (retValue != null) { @@ -1319,6 +1589,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.DatabaseAuditSpecifications; if (retValue != null) { @@ -1345,6 +1616,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.SecurityPolicies; if (retValue != null) { @@ -1371,6 +1643,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.DatabaseScopedCredentials; if (retValue != null) { @@ -1397,6 +1670,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.Roles; if (retValue != null) { @@ -1423,6 +1697,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.ApplicationRoles; if (retValue != null) { @@ -1449,6 +1724,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.ColumnMasterKeys; if (retValue != null) { @@ -1475,6 +1751,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.ColumnEncryptionKeys; if (retValue != null) { @@ -1501,6 +1778,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.ServiceBroker; if (retValue != null) { @@ -1528,6 +1806,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel ServiceBroker parentServiceBroker = context.Parent as ServiceBroker; if (parentServiceBroker != null) { + Logger.Verbose("Parent of type `ServiceBroker` found"); var retValue = parentServiceBroker.Services; if (retValue != null) { @@ -1554,6 +1833,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel ServiceBroker parentServiceBroker = context.Parent as ServiceBroker; if (parentServiceBroker != null) { + Logger.Verbose("Parent of type `ServiceBroker` found"); var retValue = parentServiceBroker.ServiceContracts; if (retValue != null) { @@ -1580,6 +1860,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel ServiceBroker parentServiceBroker = context.Parent as ServiceBroker; if (parentServiceBroker != null) { + Logger.Verbose("Parent of type `ServiceBroker` found"); var retValue = parentServiceBroker.Queues; if (retValue != null) { @@ -1606,6 +1887,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel ServiceBroker parentServiceBroker = context.Parent as ServiceBroker; if (parentServiceBroker != null) { + Logger.Verbose("Parent of type `ServiceBroker` found"); var retValue = parentServiceBroker.RemoteServiceBindings; if (retValue != null) { @@ -1632,6 +1914,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel ServiceBroker parentServiceBroker = context.Parent as ServiceBroker; if (parentServiceBroker != null) { + Logger.Verbose("Parent of type `ServiceBroker` found"); var retValue = parentServiceBroker.Priorities; if (retValue != null) { @@ -1658,6 +1941,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel ServiceBroker parentServiceBroker = context.Parent as ServiceBroker; if (parentServiceBroker != null) { + Logger.Verbose("Parent of type `ServiceBroker` found"); var retValue = parentServiceBroker.MessageTypes; if (retValue != null) { @@ -1684,6 +1968,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.ExternalDataSources; if (retValue != null) { @@ -1710,6 +1995,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.ExternalFileFormats; if (retValue != null) { @@ -1736,6 +2022,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.StoredProcedures; if (retValue != null) { @@ -1745,6 +2032,28 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel return ret; } } + Schema parentSchema = context.Parent as Schema; + if (parentSchema != null) + { + Logger.Verbose("Parent of type `Schema` found"); + List filters = new List(); + filters.Add(new NodePropertyFilter() + { + Property = nameof(Schema), + Type = typeof(string), + Values = new List { parentSchema.Name }, + ValidFor = ValidForFlag.All + }); + filter = INodeFilter.AddPropertyFilterToFilterString(filter, filters, this.GetType(), context.ValidFor); + var retValue = parentSchema.Parent.StoredProcedures; + if (retValue != null) + { + retValue.ClearAndInitialize(filter, extraProperties); + var ret = new SmoCollectionWrapper(retValue).Where(c => PassesFinalFilters(parentSchema, c)); + Logger.Verbose("End query StoredProcedure"); + return ret; + } + } return Enumerable.Empty(); } } @@ -1762,6 +2071,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.ExtendedStoredProcedures; if (retValue != null) { @@ -1788,6 +2098,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel StoredProcedure parentStoredProcedure = context.Parent as StoredProcedure; if (parentStoredProcedure != null) { + Logger.Verbose("Parent of type `StoredProcedure` found"); var retValue = parentStoredProcedure.Parameters; if (retValue != null) { @@ -1800,6 +2111,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel UserDefinedAggregate parentUserDefinedAggregate = context.Parent as UserDefinedAggregate; if (parentUserDefinedAggregate != null) { + Logger.Verbose("Parent of type `UserDefinedAggregate` found"); var retValue = parentUserDefinedAggregate.Parameters; if (retValue != null) { @@ -1812,6 +2124,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel UserDefinedFunction parentUserDefinedFunction = context.Parent as UserDefinedFunction; if (parentUserDefinedFunction != null) { + Logger.Verbose("Parent of type `UserDefinedFunction` found"); var retValue = parentUserDefinedFunction.Parameters; if (retValue != null) { @@ -1838,6 +2151,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel PartitionFunction parentPartitionFunction = context.Parent as PartitionFunction; if (parentPartitionFunction != null) { + Logger.Verbose("Parent of type `PartitionFunction` found"); var retValue = parentPartitionFunction.PartitionFunctionParameters; if (retValue != null) { @@ -1864,6 +2178,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel Database parentDatabase = context.Parent as Database; if (parentDatabase != null) { + Logger.Verbose("Parent of type `Database` found"); var retValue = parentDatabase.Parent.SystemDataTypes; if (retValue != null) { diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModel.tt b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModel.tt index c962a887..38ad407a 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModel.tt +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModel.tt @@ -24,318 +24,354 @@ using System.Composition; using System.Linq; using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Smo.Broker; +using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; using Microsoft.SqlTools.Utility; using Index = Microsoft.SqlServer.Management.Smo.Index; namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { <# - var directory = Path.GetDirectoryName(Host.TemplateFile); - string xmlFile = Path.Combine(directory, "SmoQueryModelDefinition.xml"); + var directory = Path.GetDirectoryName(Host.TemplateFile); + string xmlFile = Path.Combine(directory, "SmoQueryModelDefinition.xml"); - ///////// - // Now generate all the Query methods - ///////// - var allNodes = GetNodes(xmlFile); - var indent = " "; - foreach (var nodeName in allNodes) - { - XmlElement nodeElement = GetNodeElement(xmlFile, nodeName); - IList parents = GetParents(nodeElement, xmlFile, nodeName); - string nodeType = GetNodeType(nodeElement, nodeName); - var validFor = nodeElement.GetAttribute("ValidFor"); - - string queryBaseClass = "SmoQuerier"; - PushIndent(indent); - WriteLine(""); - WriteLine("[Export(typeof({0}))]", queryBaseClass); - WriteLine("internal partial class {0}Querier: {1}", nodeName, queryBaseClass); - WriteLine("{"); - PushIndent(indent); - - // Supported Types - WriteLine("Type[] supportedTypes = new Type[] { typeof("+ nodeType + ") };"); - if (!string.IsNullOrWhiteSpace(validFor)) + ///////// + // Now generate all the Query methods + ///////// + var allNodes = GetNodes(xmlFile); + var indent = " "; + foreach (var nodeName in allNodes) { - WriteLine(""); - WriteLine("public override ValidForFlag ValidFor {{ get {{ return {0}; }} }}", GetValidForFlags(validFor)); - WriteLine(""); - } + XmlElement nodeElement = GetNodeElement(xmlFile, nodeName); + IList parents = GetParents(nodeElement, xmlFile, nodeName); + string nodeType = GetNodeType(nodeElement, nodeName); + var validFor = nodeElement.GetAttribute("ValidFor"); - WriteLine(""); - WriteLine("public override Type[] SupportedObjectTypes { get { return supportedTypes; } }"); - WriteLine(""); - - // Query impl - WriteLine("public override IEnumerable Query(SmoQueryContext context, string filter, bool refresh, IEnumerable extraProperties)"); - WriteLine("{"); - PushIndent(indent); - WriteLine("Logger.Verbose(\"Begin query {0}\");", nodeType); - // TODO Allow override of the navigation path - foreach(var parentType in parents) - { - string parentVar = string.Format("parent{0}", parentType); - WriteLine("{0} {1} = context.Parent as {0};", parentType, parentVar); - WriteLine("if ({0} != null)", parentVar); - WriteLine("{"); - PushIndent(indent); - - XmlElement navPathElement = GetNavPathElement(xmlFile, nodeName, parentType); - string navigationPath = GetNavigationPath(nodeElement, nodeName, navPathElement); - string subField = GetNavPathAttribute(navPathElement, "SubField"); - string fieldType = GetNavPathAttribute(navPathElement, "FieldType"); - - - WriteLine("var retValue = {0}.{1};", parentVar, navigationPath); - WriteLine("if (retValue != null)"); - WriteLine("{"); - PushIndent(indent); - - - if (IsCollection(nodeElement)) - { - WriteLine("retValue.ClearAndInitialize(filter, extraProperties);"); - if (string.IsNullOrEmpty(subField) ) - { - WriteLine("var ret = new SmoCollectionWrapper<{0}>(retValue).Where(c => PassesFinalFilters({1}, c));", nodeType, parentVar); - WriteLine("Logger.Verbose(\"End query {0}\");", nodeType); - WriteLine("return ret;"); - } - else - { - WriteLine("List<{0}> subFieldResult = new List<{0}>();", nodeType); - WriteLine("foreach({0} field in retValue)", fieldType); - WriteLine("{"); - PushIndent(indent); - WriteLine("{0} subField = field.{1};", nodeType, subField); - WriteLine("if (subField != null)"); - WriteLine("{"); - PushIndent(indent); - WriteLine("subFieldResult.Add(subField);"); - PopIndent(); - WriteLine("}"); - PopIndent(); - WriteLine("}"); - WriteLine("var ret = subFieldResult.Where(c => PassesFinalFilters({1}, c));", nodeType, parentVar); - WriteLine("Logger.Verbose(\"End query {0}\");", nodeType); - WriteLine("return ret;"); - } - } - else - { - WriteLine("if (refresh)"); + string queryBaseClass = "SmoQuerier"; + PushIndent(indent); + WriteLine(""); + WriteLine("[Export(typeof({0}))]", queryBaseClass); + WriteLine("internal partial class {0}Querier: {1}", nodeName, queryBaseClass); WriteLine("{"); PushIndent(indent); - WriteLine("{0}.{1}.Refresh();", parentVar, navigationPath); + + // Supported Types + WriteLine("Type[] supportedTypes = new Type[] { typeof("+ nodeType + ") };"); + if (!string.IsNullOrWhiteSpace(validFor)) + { + WriteLine(""); + WriteLine("public override ValidForFlag ValidFor {{ get {{ return {0}; }} }}", GetValidForFlags(validFor)); + WriteLine(""); + } + + WriteLine(""); + WriteLine("public override Type[] SupportedObjectTypes { get { return supportedTypes; } }"); + WriteLine(""); + + // Query impl + WriteLine("public override IEnumerable Query(SmoQueryContext context, string filter, bool refresh, IEnumerable extraProperties)"); + WriteLine("{"); + PushIndent(indent); + WriteLine("Logger.Verbose(\"Begin query {0}\");", nodeType); + // TODO Allow override of the navigation path + foreach(var parentType in parents) + { + string parentVar = string.Format("parent{0}", parentType); + WriteLine("{0} {1} = context.Parent as {0};", parentType, parentVar); + WriteLine("if ({0} != null)", parentVar); + WriteLine("{"); + PushIndent(indent); + WriteLine("Logger.Verbose(\"Parent of type `{0}` found\");",parentType); + XmlElement navPathElement = GetNavPathElement(xmlFile, nodeName, parentType); + string navigationPath = GetNavigationPath(nodeElement, nodeName, navPathElement); + string subField = GetNavPathAttribute(navPathElement, "SubField"); + string fieldType = GetNavPathAttribute(navPathElement, "FieldType"); + if(navPathElement != null){ + /** + Adding runtime filters to the querier based on the property values available in the context. + The code below will go through all the filters in the navPath element and add them to the filter string + recieved by the querier. + **/ + XmlNodeList runtimeFilters = navPathElement.GetElementsByTagName("Filter"); + if(runtimeFilters.Count > 0) + { + WriteLine("List filters = new List();"); + foreach(XmlElement filter in runtimeFilters) + { + string filterName = filter.GetAttribute("Property"); + string filterField = filter.GetAttribute("Field"); + string filterType = filter.GetAttribute("Type"); + string filterValidFor = filter.GetAttribute("ValidFor"); + WriteLine("filters.Add(new NodePropertyFilter()"); + WriteLine("{"); + PushIndent(indent); + WriteLine("Property = nameof({0}),", filterName); + WriteLine("Type = typeof({0}),", filterType); + WriteLine("Values = new List {{ {0}.{1} }},", parentVar, filterField); + if(!string.IsNullOrWhiteSpace(filterValidFor)) + { + WriteLine("ValidFor = {0},", GetValidForFlags(filterValidFor)); + } + else + { + WriteLine("ValidFor = ValidForFlag.All "); + } + PopIndent(); + WriteLine("});"); + } + WriteLine("filter = INodeFilter.AddPropertyFilterToFilterString(filter, filters, this.GetType(), context.ValidFor);"); + } + } + + WriteLine("var retValue = {0}.{1};", parentVar, navigationPath); + WriteLine("if (retValue != null)"); + WriteLine("{"); + PushIndent(indent); + + + if (IsCollection(nodeElement)) + { + WriteLine("retValue.ClearAndInitialize(filter, extraProperties);"); + if (string.IsNullOrEmpty(subField) ) + { + WriteLine("var ret = new SmoCollectionWrapper<{0}>(retValue).Where(c => PassesFinalFilters({1}, c));", nodeType, parentVar); + WriteLine("Logger.Verbose(\"End query {0}\");", nodeType); + WriteLine("return ret;"); + } + else + { + WriteLine("List<{0}> subFieldResult = new List<{0}>();", nodeType); + WriteLine("foreach({0} field in retValue)", fieldType); + WriteLine("{"); + PushIndent(indent); + WriteLine("{0} subField = field.{1};", nodeType, subField); + WriteLine("if (subField != null)"); + WriteLine("{"); + PushIndent(indent); + WriteLine("subFieldResult.Add(subField);"); + PopIndent(); + WriteLine("}"); + PopIndent(); + WriteLine("}"); + WriteLine("var ret = subFieldResult.Where(c => PassesFinalFilters({1}, c));", nodeType, parentVar); + WriteLine("Logger.Verbose(\"End query {0}\");", nodeType); + WriteLine("return ret;"); + } + } + else + { + WriteLine("if (refresh)"); + WriteLine("{"); + PushIndent(indent); + WriteLine("{0}.{1}.Refresh();", parentVar, navigationPath); + PopIndent(); + WriteLine("}"); + WriteLine("return new SqlSmoObject[] { retValue };"); + } + + PopIndent(); + WriteLine("}"); + PopIndent(); + WriteLine("}"); // close If + } + + WriteLine("return Enumerable.Empty();"); + + PopIndent(); + WriteLine("}"); // close Query method + PopIndent(); + WriteLine("}"); // close Class PopIndent(); - WriteLine("}"); - WriteLine("return new SqlSmoObject[] { retValue };"); - } - - PopIndent(); - WriteLine("}"); - PopIndent(); - WriteLine("}"); // close If } - - WriteLine("return Enumerable.Empty();"); - - PopIndent(); - WriteLine("}"); // close Query method - PopIndent(); - WriteLine("}"); // close Class - PopIndent(); - } #> } <#+ - public static string[] GetNodes(string xmlFile) - { - List typesList = new List(); - XmlDocument doc = new XmlDocument(); - doc.Load(xmlFile); - XmlNodeList treeTypes = doc.SelectNodes("/SmoQueryModel/Node"); - if (treeTypes != null) + public static string[] GetNodes(string xmlFile) { - foreach (var type in treeTypes) - { - XmlElement element = type as XmlElement; - if (element != null) + List typesList = new List(); + XmlDocument doc = new XmlDocument(); + doc.Load(xmlFile); + XmlNodeList treeTypes = doc.SelectNodes("/SmoQueryModel/Node"); + if (treeTypes != null) { - typesList.Add(element.GetAttribute("Name")); + foreach (var type in treeTypes) + { + XmlElement element = type as XmlElement; + if (element != null) + { + typesList.Add(element.GetAttribute("Name")); + } + } } - } + return typesList.ToArray(); } - return typesList.ToArray(); - } - public static XmlElement GetNodeElement(string xmlFile, string nodeName) - { - XmlDocument doc = new XmlDocument(); - doc.Load(xmlFile); - return (XmlElement)doc.SelectSingleNode(string.Format("/SmoQueryModel/Node[@Name='{0}']", nodeName)); - } - - public static XmlElement GetNavPathElement(string xmlFile, string nodeName, string parent) - { - XmlDocument doc = new XmlDocument(); - doc.Load(xmlFile); - XmlElement navPathElement = (XmlElement)doc.SelectSingleNode(string.Format("/SmoQueryModel/Node[@Name='{0}']/NavigationPath[@Parent='{1}']", nodeName, parent)); - - return navPathElement; - } - - public static string GetNavPathAttribute(XmlElement navPathElement, string attributeName) - { - return navPathElement == null ? null : navPathElement.GetAttribute(attributeName); - } - - public static string GetNavigationPath(XmlElement nodeElement, string nodeName, XmlElement navPathElement) - { - string navPathField = GetNavPathAttribute(navPathElement, "Field"); - if (!string.IsNullOrEmpty(navPathField)) + public static XmlElement GetNodeElement(string xmlFile, string nodeName) { - return navPathField; - } - // else use pluralized type as this is the most common scenario - string nodeType = GetNodeType(nodeElement, nodeName); - - string nodeTypeAccessor = IsCollection(nodeElement) ? string.Format("{0}s", nodeType) : nodeType; - return nodeTypeAccessor; - } - - public static string GetNodeType(XmlElement nodeElement, string nodeName) - { - var type = nodeElement.GetAttribute("Type"); - if (!string.IsNullOrEmpty(type)) - { - return type; - } - // Otherwise assume the type is the node name without "Sql" at the start - var prefix = "Sql"; - return nodeName.IndexOf(prefix) == 0 ? nodeName.Substring(prefix.Length) : nodeName; - } - - public static bool IsCollection(XmlElement nodeElement) - { - var collection = nodeElement.GetAttribute("Collection"); - bool result; - if (bool.TryParse(collection, out result)) - { - return result; - } - // Default is true - return true; - } - - public static IList GetParents(XmlElement nodeElement, string xmlFile, string parentName) - { - var parentAttr = nodeElement.GetAttribute("Parent"); - if (!string.IsNullOrEmpty(parentAttr)) - { - return new string[] { parentAttr }; + XmlDocument doc = new XmlDocument(); + doc.Load(xmlFile); + return (XmlElement)doc.SelectSingleNode(string.Format("/SmoQueryModel/Node[@Name='{0}']", nodeName)); } - var parentNodes = GetChildren(xmlFile, parentName, "Parent"); - if (parentNodes != null && parentNodes.Count > 0) + public static XmlElement GetNavPathElement(string xmlFile, string nodeName, string parent) { - List parents = new List(); - foreach(var node in parentNodes) - { - parents.Add(node.InnerText); - } - return parents; + XmlDocument doc = new XmlDocument(); + doc.Load(xmlFile); + XmlElement navPathElement = (XmlElement)doc.SelectSingleNode(string.Format("/SmoQueryModel/Node[@Name='{0}']/NavigationPath[@Parent='{1}']", nodeName, parent)); + + return navPathElement; } - // default to assuming a type is under Database - return new string[] { "Database" }; - } - - public static List GetChildren(string xmlFile, string parentName, string childNode) - { - XmlElement nodeElement = GetNodeElement(xmlFile, parentName); - XmlDocument doc = new XmlDocument(); - doc.Load(xmlFile); - - List retElements = new List(); - XmlNodeList nodeList = doc.SelectNodes(string.Format("/SmoQueryModel/Node[@Name='{0}']/{1}", parentName, childNode)); - foreach (var item in nodeList) + public static string GetNavPathAttribute(XmlElement navPathElement, string attributeName) { - XmlElement itemAsElement = item as XmlElement; - if (itemAsElement != null) - { - retElements.Add(itemAsElement); - } - } - return retElements; - } - - public static string GetValidForFlags(string validForStr) - { - List flags = new List(); - if (validForStr.Contains("Sql2005")) - { - flags.Add("ValidForFlag.Sql2005"); + return navPathElement == null ? null : navPathElement.GetAttribute(attributeName); } - if (validForStr.Contains("Sql2008")) + public static string GetNavigationPath(XmlElement nodeElement, string nodeName, XmlElement navPathElement) { - flags.Add("ValidForFlag.Sql2008"); + string navPathField = GetNavPathAttribute(navPathElement, "Field"); + if (!string.IsNullOrEmpty(navPathField)) + { + return navPathField; + } + // else use pluralized type as this is the most common scenario + string nodeType = GetNodeType(nodeElement, nodeName); + + string nodeTypeAccessor = IsCollection(nodeElement) ? string.Format("{0}s", nodeType) : nodeType; + return nodeTypeAccessor; } - if (validForStr.Contains("Sql2012")) + public static string GetNodeType(XmlElement nodeElement, string nodeName) { - flags.Add("ValidForFlag.Sql2012"); + var type = nodeElement.GetAttribute("Type"); + if (!string.IsNullOrEmpty(type)) + { + return type; + } + // Otherwise assume the type is the node name without "Sql" at the start + var prefix = "Sql"; + return nodeName.IndexOf(prefix) == 0 ? nodeName.Substring(prefix.Length) : nodeName; } - if (validForStr.Contains("Sql2014")) + public static bool IsCollection(XmlElement nodeElement) { - flags.Add("ValidForFlag.Sql2014"); + var collection = nodeElement.GetAttribute("Collection"); + bool result; + if (bool.TryParse(collection, out result)) + { + return result; + } + // Default is true + return true; } - if (validForStr.Contains("Sql2016")) + public static IList GetParents(XmlElement nodeElement, string xmlFile, string parentName) { - flags.Add("ValidForFlag.Sql2016"); + var parentAttr = nodeElement.GetAttribute("Parent"); + if (!string.IsNullOrEmpty(parentAttr)) + { + return new string[] { parentAttr }; + } + + var parentNodes = GetChildren(xmlFile, parentName, "Parent"); + if (parentNodes != null && parentNodes.Count > 0) + { + List parents = new List(); + foreach(var node in parentNodes) + { + parents.Add(node.InnerText); + } + return parents; + } + + // default to assuming a type is under Database + return new string[] { "Database" }; } - if (validForStr.Contains("Sql2017")) + public static List GetChildren(string xmlFile, string parentName, string childNode) { - flags.Add("ValidForFlag.Sql2017"); + XmlElement nodeElement = GetNodeElement(xmlFile, parentName); + XmlDocument doc = new XmlDocument(); + doc.Load(xmlFile); + + List retElements = new List(); + XmlNodeList nodeList = doc.SelectNodes(string.Format("/SmoQueryModel/Node[@Name='{0}']/{1}", parentName, childNode)); + foreach (var item in nodeList) + { + XmlElement itemAsElement = item as XmlElement; + if (itemAsElement != null) + { + retElements.Add(itemAsElement); + } + } + return retElements; } - if (validForStr.Contains("AzureV12")) + public static string GetValidForFlags(string validForStr) { - flags.Add("ValidForFlag.AzureV12"); - } + List flags = new List(); + if (validForStr.Contains("Sql2005")) + { + flags.Add("ValidForFlag.Sql2005"); + } - if (validForStr.Contains("AllOnPrem")) - { - flags.Add("ValidForFlag.AllOnPrem"); - } - if (validForStr.Contains("AllAzure")) - { - flags.Add("ValidForFlag.AllAzure"); - } - if (validForStr.Contains("NotSqlDw")) - { - flags.Add("ValidForFlag.NotSqlDw"); - } - if (validForStr.Contains("SqlOnDemand")) - { - flags.Add("ValidForFlag.SqlOnDemand"); - } - if (validForStr == "NotSqlDemand") - { - flags.Add("ValidForFlag.NotSqlDemand"); - } - if (validForStr == "All") - { - flags.Add("ValidForFlag.All"); - } + if (validForStr.Contains("Sql2008")) + { + flags.Add("ValidForFlag.Sql2008"); + } - return string.Join("|", flags); - } + if (validForStr.Contains("Sql2012")) + { + flags.Add("ValidForFlag.Sql2012"); + } + + if (validForStr.Contains("Sql2014")) + { + flags.Add("ValidForFlag.Sql2014"); + } + + if (validForStr.Contains("Sql2016")) + { + flags.Add("ValidForFlag.Sql2016"); + } + + if (validForStr.Contains("Sql2017")) + { + flags.Add("ValidForFlag.Sql2017"); + } + + if (validForStr.Contains("AzureV12")) + { + flags.Add("ValidForFlag.AzureV12"); + } + + if (validForStr.Contains("AllOnPrem")) + { + flags.Add("ValidForFlag.AllOnPrem"); + } + if (validForStr.Contains("AllAzure")) + { + flags.Add("ValidForFlag.AllAzure"); + } + if (validForStr.Contains("NotSqlDw")) + { + flags.Add("ValidForFlag.NotSqlDw"); + } + if (validForStr.Contains("SqlOnDemand")) + { + flags.Add("ValidForFlag.SqlOnDemand"); + } + if (validForStr == "NotSqlDemand") + { + flags.Add("ValidForFlag.NotSqlDemand"); + } + if (validForStr == "All") + { + flags.Add("ValidForFlag.All"); + } + + return string.Join("|", flags); + } #> \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModelDefinition.xml b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModelDefinition.xml index 35223278..3d498832 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModelDefinition.xml +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQueryModelDefinition.xml @@ -5,13 +5,21 @@ into code using a T4 template. Key properties: - Name: This maps - Type: Optional SMO type. If not specified, the Name without the Sql prefix is used - Parent: Expected parent type. Needed to codegen the response. if there are multiple parents - then each one + attr.Name: This maps + attr.Type: Optional SMO type. If not specified, the Name without the Sql prefix is used + attr.Parent: Expected parent type. Needed to codegen the response. + Parent: In case a node has multiple parents, chilren of type parents need to be added. + Each parent should have corresponding navigation path. NavigationPath: For types whose access path differs based on parent or needs custom navigation this can be used. - + attr.Parent: The parent type that this navigation path is valid for + attr.Field: The field to use to navigate to the child type + Filter: Optional filter to apply to the navigation path. This is used to filter out + results that are not of the expected type. For example, the SqlTable type has a + filter on the Schema field to ensure that the table is in the expected schema. + attr.Property: The property to filter on + attr.Field: The field to use from the parent to filter on the property + attr.Type: The type of the field. --> @@ -35,14 +43,37 @@ - + + Database + Schema + + + + + + + - + + Database + Schema + + + + + - + + Database + Schema + + + + + @@ -75,17 +106,68 @@ --> - + + Database + Schema + + + + + - + + Database + Schema + + + + + - - - + + Database + Schema + + + + + - + + Database + Schema + + + + + - + + Database + Schema + + + + + + + + Database + Schema + + + + + + + + Database + Schema + + + + + @@ -135,7 +217,14 @@ - + + Database + Schema + + + + + StoredProcedure diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodes.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodes.cs index 97346a06..9764058b 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodes.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodes.cs @@ -14,6 +14,8 @@ using System.Collections.Generic; using System.Composition; using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; +using Microsoft.SqlTools.ServiceLayer.SqlContext; +using Microsoft.SqlTools.ServiceLayer.Workspace; namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { @@ -150,24 +152,33 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel } } + internal sealed partial class ExpandableSchemaTreeNode : SmoTreeNode + { + public ExpandableSchemaTreeNode() : base() + { + NodeValue = string.Empty; + this.NodeType = "Schema"; + this.NodeTypeId = NodeTypes.ExpandableSchema; + OnInitialize(); + } + } + [Export(typeof(ChildFactory))] [Shared] internal partial class ServerChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Server" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Server) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Databases, - NodeType = "Folder", NodeTypeId = NodeTypes.Databases, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Security, - NodeType = "Folder", NodeTypeId = NodeTypes.ServerLevelSecurity, IsSystemObject = false, ValidFor = ValidForFlag.All, @@ -175,7 +186,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_ServerObjects, - NodeType = "Folder", NodeTypeId = NodeTypes.ServerLevelServerObjects, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem, @@ -188,7 +198,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class DatabasesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Databases" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Databases) }; } public override IEnumerable Filters { @@ -228,7 +238,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemDatabases, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemDatabases, IsSystemObject = true, ValidFor = ValidForFlag.All, @@ -256,13 +265,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ServerLevelSecurityChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ServerLevelSecurity" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ServerLevelSecurity) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_LinkedServerLogins, - NodeType = "Folder", NodeTypeId = NodeTypes.ServerLevelLinkedServerLogins, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem, @@ -270,14 +278,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Logins, - NodeType = "Folder", NodeTypeId = NodeTypes.ServerLevelLogins, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_ServerRoles, - NodeType = "Folder", NodeTypeId = NodeTypes.ServerLevelServerRoles, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem, @@ -285,7 +291,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Credentials, - NodeType = "Folder", NodeTypeId = NodeTypes.ServerLevelCredentials, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem, @@ -293,7 +298,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_CryptographicProviders, - NodeType = "Folder", NodeTypeId = NodeTypes.ServerLevelCryptographicProviders, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem, @@ -301,7 +305,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_ServerAudits, - NodeType = "Folder", NodeTypeId = NodeTypes.ServerLevelServerAudits, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem, @@ -309,7 +312,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_ServerAuditSpecifications, - NodeType = "Folder", NodeTypeId = NodeTypes.ServerLevelServerAuditSpecifications, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem, @@ -330,13 +332,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ServerLevelServerObjectsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ServerLevelServerObjects" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ServerLevelServerObjects) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Endpoints, - NodeType = "Folder", NodeTypeId = NodeTypes.ServerLevelEndpoints, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem, @@ -344,21 +345,18 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_LinkedServers, - NodeType = "Folder", NodeTypeId = NodeTypes.ServerLevelLinkedServers, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_ServerTriggers, - NodeType = "Folder", NodeTypeId = NodeTypes.ServerLevelServerTriggers, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_ErrorMessages, - NodeType = "Folder", NodeTypeId = NodeTypes.ServerLevelErrorMessages, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, @@ -378,7 +376,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemDatabasesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemDatabases" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemDatabases) }; } public override IEnumerable Filters { @@ -415,7 +413,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ServerLevelLinkedServerLoginsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ServerLevelLinkedServerLogins" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ServerLevelLinkedServerLogins) }; } internal override Type[] ChildQuerierTypes { @@ -439,7 +437,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ServerLevelLoginsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ServerLevelLogins" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ServerLevelLogins) }; } internal override Type[] ChildQuerierTypes { @@ -463,7 +461,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ServerLevelServerRolesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ServerLevelServerRoles" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ServerLevelServerRoles) }; } internal override Type[] ChildQuerierTypes { @@ -487,7 +485,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ServerLevelCredentialsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ServerLevelCredentials" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ServerLevelCredentials) }; } internal override Type[] ChildQuerierTypes { @@ -511,7 +509,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ServerLevelCryptographicProvidersChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ServerLevelCryptographicProviders" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ServerLevelCryptographicProviders) }; } internal override Type[] ChildQuerierTypes { @@ -535,7 +533,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ServerLevelServerAuditsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ServerLevelServerAudits" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ServerLevelServerAudits) }; } internal override Type[] ChildQuerierTypes { @@ -559,7 +557,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ServerLevelServerAuditSpecificationsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ServerLevelServerAuditSpecifications" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ServerLevelServerAuditSpecifications) }; } internal override Type[] ChildQuerierTypes { @@ -583,7 +581,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ServerLevelEndpointsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ServerLevelEndpoints" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ServerLevelEndpoints) }; } internal override Type[] ChildQuerierTypes { @@ -607,7 +605,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ServerLevelLinkedServersChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ServerLevelLinkedServers" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ServerLevelLinkedServers) }; } internal override Type[] ChildQuerierTypes { @@ -631,7 +629,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ServerLevelServerTriggersChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ServerLevelServerTriggers" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ServerLevelServerTriggers) }; } internal override Type[] ChildQuerierTypes { @@ -655,7 +653,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ServerLevelErrorMessagesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ServerLevelErrorMessages" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ServerLevelErrorMessages) }; } internal override Type[] ChildQuerierTypes { @@ -679,35 +677,41 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class DatabaseChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Database" }; } + public override bool PutFoldersAfterNodes => true; + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Database) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { - currentChildren.Add(new FolderNode { - NodeValue = SR.SchemaHierarchy_Tables, - NodeType = "Folder", - NodeTypeId = NodeTypes.Tables, - IsSystemObject = false, - SortPriority = SmoTreeNode.NextSortPriority, - }); - currentChildren.Add(new FolderNode { - NodeValue = SR.SchemaHierarchy_Views, - NodeType = "Folder", - NodeTypeId = NodeTypes.Views, - IsSystemObject = false, - SortPriority = SmoTreeNode.NextSortPriority, - }); - currentChildren.Add(new FolderNode { - NodeValue = SR.SchemaHierarchy_Synonyms, - NodeType = "Folder", - NodeTypeId = NodeTypes.Synonyms, - IsSystemObject = false, - ValidFor = ValidForFlag.AllOnPrem|ValidForFlag.AzureV12, - SortPriority = SmoTreeNode.NextSortPriority, - }); + if (!WorkspaceService.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema) + { + currentChildren.Add(new FolderNode { + NodeValue = SR.SchemaHierarchy_Tables, + NodeTypeId = NodeTypes.Tables, + IsSystemObject = false, + SortPriority = SmoTreeNode.NextSortPriority, + }); + } + if (!WorkspaceService.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema) + { + currentChildren.Add(new FolderNode { + NodeValue = SR.SchemaHierarchy_Views, + NodeTypeId = NodeTypes.Views, + IsSystemObject = false, + SortPriority = SmoTreeNode.NextSortPriority, + }); + } + if (!WorkspaceService.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema) + { + currentChildren.Add(new FolderNode { + NodeValue = SR.SchemaHierarchy_Synonyms, + NodeTypeId = NodeTypes.Synonyms, + IsSystemObject = false, + ValidFor = ValidForFlag.AllOnPrem|ValidForFlag.AzureV12, + SortPriority = SmoTreeNode.NextSortPriority, + }); + } currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Programmability, - NodeType = "Folder", NodeTypeId = NodeTypes.Programmability, IsSystemObject = false, ValidFor = ValidForFlag.NotSqlDemand, @@ -715,7 +719,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_ExternalResources, - NodeType = "Folder", NodeTypeId = NodeTypes.ExternalResources, IsSystemObject = false, ValidFor = ValidForFlag.Sql2016OrHigher|ValidForFlag.AzureV12|ValidForFlag.SqlOnDemand, @@ -723,7 +726,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_ServiceBroker, - NodeType = "Folder", NodeTypeId = NodeTypes.ServiceBroker, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem, @@ -731,7 +733,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Storage, - NodeType = "Folder", NodeTypeId = NodeTypes.Storage, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem|ValidForFlag.AzureV12, @@ -739,13 +740,69 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Security, - NodeType = "Folder", NodeTypeId = NodeTypes.Security, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); } + internal override Type[] ChildQuerierTypes + { + get + { + List conditionalTypesList = new List(); + if (WorkspaceService.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema) + { + conditionalTypesList.Add(typeof(SqlSchemaQuerier)); + } + return conditionalTypesList.ToArray(); + } + } + + public override TreeNode CreateChild(TreeNode parent, object context) + { + var child = new ExpandableSchemaTreeNode(); + InitializeChild(parent, child, context); + return child; + } + } + + [Export(typeof(ChildFactory))] + [Shared] + internal partial class ExpandableSchemaChildFactory : SmoChildFactoryBase + { + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ExpandableSchema) }; } + + protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) + { + currentChildren.Add(new FolderNode { + NodeValue = SR.SchemaHierarchy_Tables, + NodeTypeId = NodeTypes.Tables, + IsSystemObject = false, + SortPriority = SmoTreeNode.NextSortPriority, + }); + currentChildren.Add(new FolderNode { + NodeValue = SR.SchemaHierarchy_Views, + NodeTypeId = NodeTypes.Views, + IsSystemObject = false, + SortPriority = SmoTreeNode.NextSortPriority, + }); + currentChildren.Add(new FolderNode { + NodeValue = SR.SchemaHierarchy_Synonyms, + NodeTypeId = NodeTypes.Synonyms, + IsSystemObject = false, + ValidFor = ValidForFlag.AllOnPrem|ValidForFlag.AzureV12, + SortPriority = SmoTreeNode.NextSortPriority, + }); + currentChildren.Add(new FolderNode { + NodeValue = SR.SchemaHierarchy_Programmability, + NodeTypeId = NodeTypes.ExpandableSchemaProgrammability, + IsSystemObject = false, + ValidFor = ValidForFlag.NotSqlDemand, + SortPriority = SmoTreeNode.NextSortPriority, + }); + } + internal override Type[] ChildQuerierTypes { get @@ -758,7 +815,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { var child = new SmoTreeNode(); child.IsAlwaysLeaf = true; - child.NodeType = "Database"; InitializeChild(parent, child, context); return child; } @@ -768,7 +824,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class TablesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Tables" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Tables) }; } public override IEnumerable Filters { @@ -863,7 +919,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemTables, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemTables, IsSystemObject = true, IsMsShippedOwned = true, @@ -871,7 +926,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_DroppedLedgerTables, - NodeType = "Folder", NodeTypeId = NodeTypes.DroppedLedgerTables, IsSystemObject = false, ValidFor = ValidForFlag.Sql2022OrHigher|ValidForFlag.AzureV12, @@ -899,7 +953,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ViewsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Views" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Views) }; } public override IEnumerable Filters { @@ -941,7 +995,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemViews, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemViews, IsSystemObject = true, IsMsShippedOwned = true, @@ -949,7 +1002,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_DroppedLedgerViews, - NodeType = "Folder", NodeTypeId = NodeTypes.DroppedLedgerViews, IsSystemObject = false, IsMsShippedOwned = true, @@ -978,7 +1030,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SynonymsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Synonyms" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Synonyms) }; } internal override Type[] ChildQuerierTypes { @@ -1002,28 +1054,31 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ProgrammabilityChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Programmability" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Programmability) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { - currentChildren.Add(new FolderNode { - NodeValue = SR.SchemaHierarchy_StoredProcedures, - NodeType = "Folder", - NodeTypeId = NodeTypes.StoredProcedures, - IsSystemObject = false, - SortPriority = SmoTreeNode.NextSortPriority, - }); - currentChildren.Add(new FolderNode { - NodeValue = SR.SchemaHierarchy_Functions, - NodeType = "Folder", - NodeTypeId = NodeTypes.Functions, - IsSystemObject = false, - ValidFor = ValidForFlag.NotSqlDemand, - SortPriority = SmoTreeNode.NextSortPriority, - }); + if (!WorkspaceService.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema) + { + currentChildren.Add(new FolderNode { + NodeValue = SR.SchemaHierarchy_StoredProcedures, + NodeTypeId = NodeTypes.StoredProcedures, + IsSystemObject = false, + SortPriority = SmoTreeNode.NextSortPriority, + }); + } + if (!WorkspaceService.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema) + { + currentChildren.Add(new FolderNode { + NodeValue = SR.SchemaHierarchy_Functions, + NodeTypeId = NodeTypes.Functions, + IsSystemObject = false, + ValidFor = ValidForFlag.NotSqlDemand, + SortPriority = SmoTreeNode.NextSortPriority, + }); + } currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_DatabaseTriggers, - NodeType = "Folder", NodeTypeId = NodeTypes.DatabaseTriggers, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem|ValidForFlag.AzureV12, @@ -1031,15 +1086,65 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Assemblies, - NodeType = "Folder", NodeTypeId = NodeTypes.Assemblies, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem|ValidForFlag.AzureV12, SortPriority = SmoTreeNode.NextSortPriority, + }); + if (!WorkspaceService.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema) + { + currentChildren.Add(new FolderNode { + NodeValue = SR.SchemaHierarchy_Types, + NodeTypeId = NodeTypes.Types, + IsSystemObject = false, + ValidFor = ValidForFlag.NotSqlDemand, + SortPriority = SmoTreeNode.NextSortPriority, + }); + } + if (!WorkspaceService.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema) + { + currentChildren.Add(new FolderNode { + NodeValue = SR.SchemaHierarchy_Sequences, + NodeTypeId = NodeTypes.Sequences, + IsSystemObject = false, + ValidFor = ValidForFlag.Sql2012OrHigher|ValidForFlag.AzureV12, + SortPriority = SmoTreeNode.NextSortPriority, + }); + } + } + + internal override Type[] ChildQuerierTypes { get {return null;} } + + + public override TreeNode CreateChild(TreeNode parent, object context) + { + return null; + } + } + + [Export(typeof(ChildFactory))] + [Shared] + internal partial class ExpandableSchemaProgrammabilityChildFactory : SmoChildFactoryBase + { + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ExpandableSchemaProgrammability) }; } + + protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) + { + currentChildren.Add(new FolderNode { + NodeValue = SR.SchemaHierarchy_StoredProcedures, + NodeTypeId = NodeTypes.StoredProcedures, + IsSystemObject = false, + SortPriority = SmoTreeNode.NextSortPriority, + }); + currentChildren.Add(new FolderNode { + NodeValue = SR.SchemaHierarchy_Functions, + NodeTypeId = NodeTypes.Functions, + IsSystemObject = false, + ValidFor = ValidForFlag.NotSqlDemand, + SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Types, - NodeType = "Folder", NodeTypeId = NodeTypes.Types, IsSystemObject = false, ValidFor = ValidForFlag.NotSqlDemand, @@ -1047,7 +1152,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Sequences, - NodeType = "Folder", NodeTypeId = NodeTypes.Sequences, IsSystemObject = false, ValidFor = ValidForFlag.Sql2012OrHigher|ValidForFlag.AzureV12, @@ -1068,13 +1172,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ExternalResourcesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ExternalResources" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ExternalResources) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_ExternalDataSources, - NodeType = "Folder", NodeTypeId = NodeTypes.ExternalDataSources, IsSystemObject = false, ValidFor = ValidForFlag.Sql2016OrHigher|ValidForFlag.AzureV12|ValidForFlag.SqlOnDemand, @@ -1082,7 +1185,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_ExternalFileFormats, - NodeType = "Folder", NodeTypeId = NodeTypes.ExternalFileFormats, IsSystemObject = false, ValidFor = ValidForFlag.Sql2016OrHigher|ValidForFlag.SqlOnDemand, @@ -1103,48 +1205,42 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ServiceBrokerChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ServiceBroker" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ServiceBroker) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_MessageTypes, - NodeType = "Folder", NodeTypeId = NodeTypes.MessageTypes, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Contracts, - NodeType = "Folder", NodeTypeId = NodeTypes.Contracts, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Queues, - NodeType = "Folder", NodeTypeId = NodeTypes.Queues, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Services, - NodeType = "Folder", NodeTypeId = NodeTypes.Services, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_RemoteServiceBindings, - NodeType = "Folder", NodeTypeId = NodeTypes.RemoteServiceBindings, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_BrokerPriorities, - NodeType = "Folder", NodeTypeId = NodeTypes.BrokerPriorities, IsSystemObject = false, ValidFor = ValidForFlag.Sql2008OrHigher, @@ -1165,27 +1261,24 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class StorageChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Storage" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Storage) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_FileGroups, - NodeType = "Folder", NodeTypeId = NodeTypes.FileGroups, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_FullTextCatalogs, - NodeType = "Folder", NodeTypeId = NodeTypes.FullTextCatalogs, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_FullTextStopLists, - NodeType = "Folder", NodeTypeId = NodeTypes.FullTextStopLists, IsSystemObject = false, ValidFor = ValidForFlag.Sql2008OrHigher|ValidForFlag.AzureV12, @@ -1193,28 +1286,24 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_LogFiles, - NodeType = "Folder", NodeTypeId = NodeTypes.SqlLogFiles, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_PartitionFunctions, - NodeType = "Folder", NodeTypeId = NodeTypes.PartitionFunctions, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_PartitionSchemes, - NodeType = "Folder", NodeTypeId = NodeTypes.PartitionSchemes, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SearchPropertyLists, - NodeType = "Folder", NodeTypeId = NodeTypes.SearchPropertyLists, IsSystemObject = false, ValidFor = ValidForFlag.Sql2012OrHigher|ValidForFlag.AzureV12, @@ -1235,34 +1324,30 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SecurityChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Security" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Security) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Users, - NodeType = "Folder", NodeTypeId = NodeTypes.Users, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Roles, - NodeType = "Folder", NodeTypeId = NodeTypes.Roles, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Schemas, - NodeType = "Folder", NodeTypeId = NodeTypes.Schemas, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_AsymmetricKeys, - NodeType = "Folder", NodeTypeId = NodeTypes.AsymmetricKeys, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem, @@ -1270,7 +1355,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Certificates, - NodeType = "Folder", NodeTypeId = NodeTypes.Certificates, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem, @@ -1278,7 +1362,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SymmetricKeys, - NodeType = "Folder", NodeTypeId = NodeTypes.SymmetricKeys, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem, @@ -1286,7 +1369,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_DatabaseScopedCredentials, - NodeType = "Folder", NodeTypeId = NodeTypes.DatabaseScopedCredentials, IsSystemObject = false, ValidFor = ValidForFlag.Sql2016OrHigher|ValidForFlag.AzureV12, @@ -1294,7 +1376,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_DatabaseEncryptionKeys, - NodeType = "Folder", NodeTypeId = NodeTypes.DatabaseEncryptionKeys, IsSystemObject = false, ValidFor = ValidForFlag.Sql2008OrHigher, @@ -1302,7 +1383,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_MasterKeys, - NodeType = "Folder", NodeTypeId = NodeTypes.MasterKeys, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem, @@ -1310,7 +1390,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_DatabaseAuditSpecifications, - NodeType = "Folder", NodeTypeId = NodeTypes.DatabaseAuditSpecifications, IsSystemObject = false, ValidFor = ValidForFlag.Sql2008OrHigher, @@ -1318,7 +1397,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SecurityPolicies, - NodeType = "Folder", NodeTypeId = NodeTypes.SecurityPolicies, IsSystemObject = false, ValidFor = ValidForFlag.Sql2016OrHigher|ValidForFlag.AzureV12, @@ -1326,7 +1404,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_AlwaysEncryptedKeys, - NodeType = "Folder", NodeTypeId = NodeTypes.AlwaysEncryptedKeys, IsSystemObject = false, ValidFor = ValidForFlag.Sql2016OrHigher|ValidForFlag.AzureV12, @@ -1347,7 +1424,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemTablesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemTables" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemTables) }; } public override IEnumerable Filters { @@ -1384,7 +1461,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class DroppedLedgerTablesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "DroppedLedgerTables" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.DroppedLedgerTables) }; } public override IEnumerable Filters { @@ -1435,7 +1512,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class TableChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Table" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Table) }; } public override IEnumerable Filters { @@ -1496,14 +1573,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Columns, - NodeType = "Folder", NodeTypeId = NodeTypes.Columns, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Keys, - NodeType = "Folder", NodeTypeId = NodeTypes.Keys, IsSystemObject = false, ValidFor = ValidForFlag.NotSqlDw, @@ -1511,14 +1586,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Constraints, - NodeType = "Folder", NodeTypeId = NodeTypes.Constraints, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Triggers, - NodeType = "Folder", NodeTypeId = NodeTypes.Triggers, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem|ValidForFlag.AzureV12, @@ -1526,7 +1599,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Indexes, - NodeType = "Folder", NodeTypeId = NodeTypes.Indexes, IsSystemObject = false, ValidFor = ValidForFlag.NotSqlDemand, @@ -1534,7 +1606,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Statistics, - NodeType = "Folder", NodeTypeId = NodeTypes.Statistics, IsSystemObject = false, ValidFor = ValidForFlag.NotSqlDemand, @@ -1562,27 +1633,24 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class HistoryTableChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "HistoryTable" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.HistoryTable) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Columns, - NodeType = "Folder", NodeTypeId = NodeTypes.Columns, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Constraints, - NodeType = "Folder", NodeTypeId = NodeTypes.Constraints, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Indexes, - NodeType = "Folder", NodeTypeId = NodeTypes.Indexes, IsSystemObject = false, ValidFor = ValidForFlag.NotSqlDemand, @@ -1590,7 +1658,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Statistics, - NodeType = "Folder", NodeTypeId = NodeTypes.Statistics, IsSystemObject = false, ValidFor = ValidForFlag.NotSqlDemand, @@ -1620,20 +1687,18 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ExternalTableChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ExternalTable" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ExternalTable) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Columns, - NodeType = "Folder", NodeTypeId = NodeTypes.Columns, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Statistics, - NodeType = "Folder", NodeTypeId = NodeTypes.Statistics, IsSystemObject = false, ValidFor = ValidForFlag.NotSqlDemand, @@ -1663,7 +1728,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ColumnsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Columns" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Columns) }; } public override IEnumerable Filters { @@ -1685,7 +1750,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_DroppedLedgerColumns, - NodeType = "Folder", NodeTypeId = NodeTypes.DroppedLedgerColumns, IsSystemObject = false, ValidFor = ValidForFlag.Sql2022OrHigher|ValidForFlag.AzureV12, @@ -1716,7 +1780,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class DroppedLedgerColumnsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "DroppedLedgerColumns" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.DroppedLedgerColumns) }; } public override IEnumerable Filters { @@ -1756,7 +1820,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class KeysChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Keys" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Keys) }; } public override IEnumerable Filters { @@ -1801,7 +1865,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ConstraintsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Constraints" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Constraints) }; } internal override Type[] ChildQuerierTypes { @@ -1825,7 +1889,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class TriggersChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Triggers" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Triggers) }; } internal override Type[] ChildQuerierTypes { @@ -1849,7 +1913,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class IndexesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Indexes" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Indexes) }; } public override IEnumerable Filters { @@ -1895,7 +1959,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class StatisticsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Statistics" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Statistics) }; } internal override Type[] ChildQuerierTypes { @@ -1919,7 +1983,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemViewsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemViews" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemViews) }; } public override IEnumerable Filters { @@ -1956,7 +2020,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class DroppedLedgerViewsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "DroppedLedgerViews" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.DroppedLedgerViews) }; } public override IEnumerable Filters { @@ -1994,20 +2058,18 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ViewChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "View" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.View) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Columns, - NodeType = "Folder", NodeTypeId = NodeTypes.Columns, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Triggers, - NodeType = "Folder", NodeTypeId = NodeTypes.Triggers, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem|ValidForFlag.AzureV12, @@ -2015,7 +2077,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Indexes, - NodeType = "Folder", NodeTypeId = NodeTypes.Indexes, IsSystemObject = false, ValidFor = ValidForFlag.NotSqlDemand, @@ -2023,7 +2084,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Statistics, - NodeType = "Folder", NodeTypeId = NodeTypes.Statistics, IsSystemObject = false, ValidFor = ValidForFlag.NotSqlDemand, @@ -2053,13 +2113,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class FunctionsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Functions" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Functions) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemFunctions, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemFunctions, IsSystemObject = true, IsMsShippedOwned = true, @@ -2067,7 +2126,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_TableValuedFunctions, - NodeType = "Folder", NodeTypeId = NodeTypes.TableValuedFunctions, IsSystemObject = false, ValidFor = ValidForFlag.NotSqlDw, @@ -2075,14 +2133,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_ScalarValuedFunctions, - NodeType = "Folder", NodeTypeId = NodeTypes.ScalarValuedFunctions, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_AggregateFunctions, - NodeType = "Folder", NodeTypeId = NodeTypes.AggregateFunctions, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem|ValidForFlag.AzureV12, @@ -2103,13 +2159,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemFunctionsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemFunctions" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemFunctions) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_TableValuedFunctions, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemTableValuedFunctions, IsSystemObject = true, ValidFor = ValidForFlag.NotSqlDw, @@ -2117,7 +2172,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_ScalarValuedFunctions, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemScalarValuedFunctions, IsSystemObject = true, SortPriority = SmoTreeNode.NextSortPriority, @@ -2144,7 +2198,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class DatabaseTriggersChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "DatabaseTriggers" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.DatabaseTriggers) }; } internal override Type[] ChildQuerierTypes { @@ -2168,7 +2222,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class AssembliesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Assemblies" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Assemblies) }; } internal override Type[] ChildQuerierTypes { @@ -2192,20 +2246,18 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class TypesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Types" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Types) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemDataTypes, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemDataTypes, IsSystemObject = true, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_UserDefinedDataTypes, - NodeType = "Folder", NodeTypeId = NodeTypes.UserDefinedDataTypes, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem|ValidForFlag.AzureV12, @@ -2213,7 +2265,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_UserDefinedTableTypes, - NodeType = "Folder", NodeTypeId = NodeTypes.UserDefinedTableTypes, IsSystemObject = false, ValidFor = ValidForFlag.Sql2008OrHigher|ValidForFlag.AzureV12, @@ -2221,7 +2272,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_UserDefinedTypes, - NodeType = "Folder", NodeTypeId = NodeTypes.UserDefinedTypes, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem|ValidForFlag.AzureV12, @@ -2229,7 +2279,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_XMLSchemaCollections, - NodeType = "Folder", NodeTypeId = NodeTypes.XmlSchemaCollections, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem|ValidForFlag.AzureV12, @@ -2250,7 +2299,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SequencesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Sequences" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Sequences) }; } internal override Type[] ChildQuerierTypes { @@ -2274,62 +2323,54 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemDataTypesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemDataTypes" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemDataTypes) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemExactNumerics, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemExactNumerics, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemApproximateNumerics, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemApproximateNumerics, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemDateAndTime, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemDateAndTimes, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemCharacterStrings, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemCharacterStrings, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemUnicodeCharacterStrings, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemUnicodeCharacterStrings, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemBinaryStrings, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemBinaryStrings, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemOtherDataTypes, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemOtherDataTypes, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemCLRDataTypes, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemClrDataTypes, IsSystemObject = false, ValidFor = ValidForFlag.All, @@ -2337,7 +2378,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemSpatialDataTypes, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemSpatialDataTypes, IsSystemObject = false, ValidFor = ValidForFlag.Sql2008OrHigher|ValidForFlag.AzureV12, @@ -2358,7 +2398,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class UserDefinedDataTypesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "UserDefinedDataTypes" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.UserDefinedDataTypes) }; } internal override Type[] ChildQuerierTypes { @@ -2382,7 +2422,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class UserDefinedTableTypesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "UserDefinedTableTypes" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.UserDefinedTableTypes) }; } internal override Type[] ChildQuerierTypes { @@ -2404,7 +2444,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class UserDefinedTypesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "UserDefinedTypes" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.UserDefinedTypes) }; } internal override Type[] ChildQuerierTypes { @@ -2428,7 +2468,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class XmlSchemaCollectionsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "XmlSchemaCollections" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.XmlSchemaCollections) }; } internal override Type[] ChildQuerierTypes { @@ -2452,27 +2492,24 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class UserDefinedTableTypeChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "UserDefinedTableType" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.UserDefinedTableType) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Columns, - NodeType = "Folder", NodeTypeId = NodeTypes.UserDefinedTableTypeColumns, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Keys, - NodeType = "Folder", NodeTypeId = NodeTypes.UserDefinedTableTypeKeys, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Constraints, - NodeType = "Folder", NodeTypeId = NodeTypes.UserDefinedTableTypeConstraints, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, @@ -2501,7 +2538,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class UserDefinedTableTypeColumnsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "UserDefinedTableTypeColumns" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.UserDefinedTableTypeColumns) }; } internal override Type[] ChildQuerierTypes { @@ -2526,7 +2563,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class UserDefinedTableTypeKeysChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "UserDefinedTableTypeKeys" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.UserDefinedTableTypeKeys) }; } public override IEnumerable Filters { @@ -2571,7 +2608,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class UserDefinedTableTypeConstraintsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "UserDefinedTableTypeConstraints" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.UserDefinedTableTypeConstraints) }; } internal override Type[] ChildQuerierTypes { @@ -2595,7 +2632,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemExactNumericsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemExactNumerics" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemExactNumerics) }; } internal override Type[] ChildQuerierTypes { @@ -2619,7 +2656,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemApproximateNumericsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemApproximateNumerics" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemApproximateNumerics) }; } internal override Type[] ChildQuerierTypes { @@ -2643,7 +2680,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemDateAndTimesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemDateAndTimes" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemDateAndTimes) }; } internal override Type[] ChildQuerierTypes { @@ -2667,7 +2704,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemCharacterStringsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemCharacterStrings" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemCharacterStrings) }; } internal override Type[] ChildQuerierTypes { @@ -2691,7 +2728,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemUnicodeCharacterStringsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemUnicodeCharacterStrings" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemUnicodeCharacterStrings) }; } internal override Type[] ChildQuerierTypes { @@ -2715,7 +2752,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemBinaryStringsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemBinaryStrings" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemBinaryStrings) }; } internal override Type[] ChildQuerierTypes { @@ -2739,7 +2776,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemOtherDataTypesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemOtherDataTypes" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemOtherDataTypes) }; } internal override Type[] ChildQuerierTypes { @@ -2763,7 +2800,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemClrDataTypesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemClrDataTypes" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemClrDataTypes) }; } internal override Type[] ChildQuerierTypes { @@ -2787,7 +2824,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemSpatialDataTypesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemSpatialDataTypes" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemSpatialDataTypes) }; } internal override Type[] ChildQuerierTypes { @@ -2811,7 +2848,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ExternalDataSourcesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ExternalDataSources" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ExternalDataSources) }; } internal override Type[] ChildQuerierTypes { @@ -2835,7 +2872,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ExternalFileFormatsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ExternalFileFormats" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ExternalFileFormats) }; } internal override Type[] ChildQuerierTypes { @@ -2859,7 +2896,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class StoredProceduresChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "StoredProcedures" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.StoredProcedures) }; } public override IEnumerable Filters { @@ -2880,7 +2917,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemStoredProcedures, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemStoredProcedures, IsSystemObject = true, IsMsShippedOwned = true, @@ -2908,7 +2944,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemStoredProceduresChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemStoredProcedures" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemStoredProcedures) }; } public override IEnumerable Filters { @@ -2945,13 +2981,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class StoredProcedureChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "StoredProcedure" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.StoredProcedure) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Parameters, - NodeType = "Folder", NodeTypeId = NodeTypes.StoredProcedureParameters, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, @@ -2980,7 +3015,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class StoredProcedureParametersChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "StoredProcedureParameters" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.StoredProcedureParameters) }; } internal override Type[] ChildQuerierTypes { @@ -3005,7 +3040,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class TableValuedFunctionsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "TableValuedFunctions" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.TableValuedFunctions) }; } public override IEnumerable Filters { @@ -3052,7 +3087,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemTableValuedFunctionsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemTableValuedFunctions" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemTableValuedFunctions) }; } public override IEnumerable Filters { @@ -3099,13 +3134,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class TableValuedFunctionChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "TableValuedFunction" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.TableValuedFunction) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Parameters, - NodeType = "Folder", NodeTypeId = NodeTypes.TableValuedFunctionParameters, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, @@ -3134,7 +3168,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class TableValuedFunctionParametersChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "TableValuedFunctionParameters" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.TableValuedFunctionParameters) }; } internal override Type[] ChildQuerierTypes { @@ -3159,7 +3193,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ScalarValuedFunctionsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ScalarValuedFunctions" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ScalarValuedFunctions) }; } public override IEnumerable Filters { @@ -3206,7 +3240,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemScalarValuedFunctionsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemScalarValuedFunctions" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemScalarValuedFunctions) }; } public override IEnumerable Filters { @@ -3253,13 +3287,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ScalarValuedFunctionChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ScalarValuedFunction" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ScalarValuedFunction) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Parameters, - NodeType = "Folder", NodeTypeId = NodeTypes.ScalarValuedFunctionParameters, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, @@ -3288,7 +3321,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ScalarValuedFunctionParametersChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ScalarValuedFunctionParameters" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ScalarValuedFunctionParameters) }; } internal override Type[] ChildQuerierTypes { @@ -3313,7 +3346,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class AggregateFunctionsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "AggregateFunctions" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.AggregateFunctions) }; } internal override Type[] ChildQuerierTypes { @@ -3335,13 +3368,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class AggregateFunctionChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "AggregateFunction" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.AggregateFunction) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_Parameters, - NodeType = "Folder", NodeTypeId = NodeTypes.AggregateFunctionParameters, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, @@ -3370,7 +3402,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class AggregateFunctionParametersChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "AggregateFunctionParameters" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.AggregateFunctionParameters) }; } internal override Type[] ChildQuerierTypes { @@ -3395,7 +3427,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class RemoteServiceBindingsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "RemoteServiceBindings" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.RemoteServiceBindings) }; } internal override Type[] ChildQuerierTypes { @@ -3419,7 +3451,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class BrokerPrioritiesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "BrokerPriorities" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.BrokerPriorities) }; } internal override Type[] ChildQuerierTypes { @@ -3443,7 +3475,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class FileGroupsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "FileGroups" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.FileGroups) }; } internal override Type[] ChildQuerierTypes { @@ -3465,7 +3497,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class FullTextCatalogsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "FullTextCatalogs" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.FullTextCatalogs) }; } internal override Type[] ChildQuerierTypes { @@ -3489,7 +3521,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class FullTextStopListsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "FullTextStopLists" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.FullTextStopLists) }; } internal override Type[] ChildQuerierTypes { @@ -3513,7 +3545,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SqlLogFilesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SqlLogFiles" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SqlLogFiles) }; } internal override Type[] ChildQuerierTypes { @@ -3537,7 +3569,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class PartitionFunctionsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "PartitionFunctions" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.PartitionFunctions) }; } internal override Type[] ChildQuerierTypes { @@ -3561,7 +3593,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class PartitionSchemesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "PartitionSchemes" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.PartitionSchemes) }; } internal override Type[] ChildQuerierTypes { @@ -3585,7 +3617,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SearchPropertyListsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SearchPropertyLists" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SearchPropertyLists) }; } internal override Type[] ChildQuerierTypes { @@ -3609,13 +3641,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class FileGroupChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "FileGroup" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.FileGroup) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_FilegroupFiles, - NodeType = "Folder", NodeTypeId = NodeTypes.FileGroupFiles, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, @@ -3635,7 +3666,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class FileGroupFilesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "FileGroupFiles" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.FileGroupFiles) }; } internal override Type[] ChildQuerierTypes { @@ -3659,7 +3690,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class UsersChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Users" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Users) }; } internal override Type[] ChildQuerierTypes { @@ -3683,20 +3714,18 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class RolesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Roles" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Roles) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_DatabaseRoles, - NodeType = "Folder", NodeTypeId = NodeTypes.DatabaseRoles, IsSystemObject = false, SortPriority = SmoTreeNode.NextSortPriority, }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_ApplicationRoles, - NodeType = "Folder", NodeTypeId = NodeTypes.ApplicationRoles, IsSystemObject = false, ValidFor = ValidForFlag.AllOnPrem|ValidForFlag.AzureV12, @@ -3717,7 +3746,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SchemasChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Schemas" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Schemas) }; } internal override Type[] ChildQuerierTypes { @@ -3741,7 +3770,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class AsymmetricKeysChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "AsymmetricKeys" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.AsymmetricKeys) }; } internal override Type[] ChildQuerierTypes { @@ -3765,7 +3794,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class CertificatesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Certificates" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Certificates) }; } internal override Type[] ChildQuerierTypes { @@ -3789,7 +3818,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SymmetricKeysChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SymmetricKeys" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SymmetricKeys) }; } internal override Type[] ChildQuerierTypes { @@ -3813,7 +3842,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class DatabaseEncryptionKeysChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "DatabaseEncryptionKeys" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.DatabaseEncryptionKeys) }; } internal override Type[] ChildQuerierTypes { @@ -3837,7 +3866,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class MasterKeysChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "MasterKeys" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.MasterKeys) }; } internal override Type[] ChildQuerierTypes { @@ -3861,7 +3890,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class DatabaseAuditSpecificationsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "DatabaseAuditSpecifications" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.DatabaseAuditSpecifications) }; } internal override Type[] ChildQuerierTypes { @@ -3885,7 +3914,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SecurityPoliciesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SecurityPolicies" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SecurityPolicies) }; } internal override Type[] ChildQuerierTypes { @@ -3909,7 +3938,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class DatabaseScopedCredentialsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "DatabaseScopedCredentials" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.DatabaseScopedCredentials) }; } internal override Type[] ChildQuerierTypes { @@ -3933,13 +3962,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class AlwaysEncryptedKeysChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "AlwaysEncryptedKeys" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.AlwaysEncryptedKeys) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_ColumnMasterKeys, - NodeType = "Folder", NodeTypeId = NodeTypes.ColumnMasterKeys, IsSystemObject = false, ValidFor = ValidForFlag.Sql2016OrHigher|ValidForFlag.AzureV12, @@ -3947,7 +3975,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel }); currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_ColumnEncryptionKeys, - NodeType = "Folder", NodeTypeId = NodeTypes.ColumnEncryptionKeys, IsSystemObject = false, ValidFor = ValidForFlag.Sql2016OrHigher|ValidForFlag.AzureV12, @@ -3968,7 +3995,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class DatabaseRolesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "DatabaseRoles" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.DatabaseRoles) }; } internal override Type[] ChildQuerierTypes { @@ -3992,7 +4019,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ApplicationRolesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ApplicationRoles" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ApplicationRoles) }; } internal override Type[] ChildQuerierTypes { @@ -4016,7 +4043,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ColumnMasterKeysChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ColumnMasterKeys" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ColumnMasterKeys) }; } internal override Type[] ChildQuerierTypes { @@ -4040,7 +4067,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ColumnEncryptionKeysChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "ColumnEncryptionKeys" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.ColumnEncryptionKeys) }; } internal override Type[] ChildQuerierTypes { @@ -4064,13 +4091,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class MessageTypesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "MessageTypes" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.MessageTypes) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemMessageTypes, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemMessageTypes, IsSystemObject = true, IsMsShippedOwned = true, @@ -4100,7 +4126,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemMessageTypesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemMessageTypes" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemMessageTypes) }; } internal override Type[] ChildQuerierTypes { @@ -4124,13 +4150,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ContractsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Contracts" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Contracts) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemContracts, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemContracts, IsSystemObject = true, IsMsShippedOwned = true, @@ -4160,7 +4185,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemContractsChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemContracts" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemContracts) }; } internal override Type[] ChildQuerierTypes { @@ -4184,13 +4209,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class QueuesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Queues" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Queues) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemQueues, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemQueues, IsSystemObject = true, IsMsShippedOwned = true, @@ -4220,7 +4244,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemQueuesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemQueues" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemQueues) }; } internal override Type[] ChildQuerierTypes { @@ -4244,13 +4268,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class ServicesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "Services" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.Services) }; } protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { NodeValue = SR.SchemaHierarchy_SystemServices, - NodeType = "Folder", NodeTypeId = NodeTypes.SystemServices, IsSystemObject = true, IsMsShippedOwned = true, @@ -4280,7 +4303,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel [Shared] internal partial class SystemServicesChildFactory : SmoChildFactoryBase { - public override IEnumerable ApplicableParents() { return new[] { "SystemServices" }; } + public override IEnumerable ApplicableParents() { return new[] { nameof(NodeTypes.SystemServices) }; } internal override Type[] ChildQuerierTypes { diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodes.tt b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodes.tt index 21aac318..7f41c0e8 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodes.tt +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodes.tt @@ -25,580 +25,648 @@ using System.Collections.Generic; using System.Composition; using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; +using Microsoft.SqlTools.ServiceLayer.SqlContext; +using Microsoft.SqlTools.ServiceLayer.Workspace; namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { <# - var directory = Path.GetDirectoryName(Host.TemplateFile); - string xmlFile = Path.Combine(directory, "SmoTreeNodesDefinition.xml"); + var directory = Path.GetDirectoryName(Host.TemplateFile); + string xmlFile = Path.Combine(directory, "SmoTreeNodesDefinition.xml"); + var indent = " "; - ///////// - // TODO - is Generate all the ReverseDependencies needed? - ///////// - // var allReverseDependencies = GetReverseDependencies(xmlFile); - // WriteLine(" internal static class TreeNodeRules"); - // WriteLine(" {"); - // WriteLine(" internal static Dictionary> TypeReverseDependencyMap = new Dictionary>()"); - // WriteLine(" {"); - // foreach (var reverseDependencyKey in allReverseDependencies.Keys) - // { - // bool isFirstDependentType = true; - // StringBuilder dependentListBuilder = new StringBuilder("{"); - // foreach (var dependentType in allReverseDependencies[reverseDependencyKey]) - // { - // if (isFirstDependentType) - // { - // isFirstDependentType = false; - // } - // else - // { - // dependentListBuilder.Append(","); - // } - // - // dependentListBuilder.Append(string.Format(CultureInfo.InvariantCulture, " typeof({0})", dependentType)); - // } - // dependentListBuilder.Append(" }"); - // - // WriteLine(string.Format(CultureInfo.InvariantCulture, " {{ typeof({0}), new List {1} }}", reverseDependencyKey, dependentListBuilder.ToString())); - // } - // WriteLine(" };"); - // WriteLine(" }"); - // WriteLine(""); + ///////// + // TODO - is Generate all the ReverseDependencies needed? + ///////// + // var allReverseDependencies = GetReverseDependencies(xmlFile); + // WriteLine(" internal static class TreeNodeRules"); + // WriteLine(" {"); + // WriteLine(" internal static Dictionary> TypeReverseDependencyMap = new Dictionary>()"); + // WriteLine(" {"); + // foreach (var reverseDependencyKey in allReverseDependencies.Keys) + // { + // bool isFirstDependentType = true; + // StringBuilder dependentListBuilder = new StringBuilder("{"); + // foreach (var dependentType in allReverseDependencies[reverseDependencyKey]) + // { + // if (isFirstDependentType) + // { + // isFirstDependentType = false; + // } + // else + // { + // dependentListBuilder.Append(","); + // } + // + // dependentListBuilder.Append(string.Format(CultureInfo.InvariantCulture, " typeof({0})", dependentType)); + // } + // dependentListBuilder.Append(" }"); + // + // WriteLine(string.Format(CultureInfo.InvariantCulture, " {{ typeof({0}), new List {1} }}", reverseDependencyKey, dependentListBuilder.ToString())); + // } + // WriteLine(" };"); + // WriteLine(" }"); + // WriteLine(""); - ///////// - // First generate all the TreeNodes - ///////// - var allTreeNodes = GetUniqueTreeNodes(xmlFile); - foreach (var TreeNode in allTreeNodes) - { - var name = TreeNode.GetAttribute("Name"); - WriteLine(" internal sealed partial class {0} : SmoTreeNode", name); - WriteLine(" {"); - WriteLine(" public {0}() : base()", name); - WriteLine(" {"); - WriteLine(" NodeValue = string.Empty;"); - WriteLine(" this.NodeType = \"{0}\";", name.Replace("TreeNode", string.Empty)); - WriteLine(" this.NodeTypeId = NodeTypes.{0};", name.Replace("TreeNode", string.Empty)); - WriteLine(" OnInitialize();"); - WriteLine(" }"); - WriteLine(" }"); - WriteLine(""); - } - - ///////// - // Now generate all the ChildFactories - ///////// - var allNodes = GetNodes(xmlFile); - foreach (var type in allNodes) - { - XmlElement nodeElement = GetNodeElement(xmlFile, type); - var imageAttr = nodeElement.GetAttribute("Image"); - 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"); - var disableSort = nodeElement.GetAttributeNode("DisableSort"); - - string childFactoryBaseClass = "SmoChildFactoryBase"; - - // TODO Will we need alternative child factories? If so, add code here to support this - - if (isAlwaysLeaf == null) + ///////// + // First generate all the TreeNodes + ///////// + var allTreeNodes = GetUniqueTreeNodes(xmlFile); + foreach (var TreeNode in allTreeNodes) { - WriteLine(" [Export(typeof(ChildFactory))]"); - WriteLine(" [Shared]"); - - WriteLine(" internal partial class {0}ChildFactory : {1}", type, childFactoryBaseClass); - - WriteLine(" {"); - WriteLine(" public override IEnumerable ApplicableParents() {{ return new[] {{ \"{0}\" }}; }}", type); - - List children = GetChildren(xmlFile, type); - List smoProperties = GetNodeSmoProperties(xmlFile, type); - - // Load and parse Filters node - // A node is comprised of and nodes - // - A node defines the properties to construct a NodePropertyFilter object - // - An node defines a list of nodes that are or'ed in the resulting URN Query - // can have an arbitrary number of top-level and nodes. - // All filters defined at the top-level are and'ed in the resulting URN Query. - // This is generated into the IEnumerable Filters object for a particular SMO object. - // Currently there is not support for nested nodes - XmlNode filtersNode = GetFiltersNode(xmlFile, type); - if (filtersNode != null) - { - // Get the children nodes for the Filters - XmlNodeList childNodes = filtersNode.ChildNodes; - if (childNodes.Count > 0) - { - // Write initial declarator for the filters object - WriteLine(""); - WriteLine(" public override IEnumerable Filters"); - WriteLine(" {"); - WriteLine(" get"); - WriteLine(" {"); - WriteLine(" var filters = new List();"); - - // Parse each of the nodes in - foreach (var orNode in filtersNode.SelectNodes("Or")) - { - XmlElement or = orNode as XmlElement; - if (or == null) - { - continue; - } - - // Write initial declarator for the object, which is just a list of NodePropertyFilters - WriteLine(" filters.Add(new NodeOrFilter"); - WriteLine(" {"); - WriteLine(" FilterList = new List {"); - - foreach(var orFilterNode in or.GetElementsByTagName("Filter")) - { - XmlElement orFilter = orFilterNode as XmlElement; - if (orFilter == null) - { - continue; - } - - // Declaration of Filter node - WriteLine(" new NodePropertyFilter"); - - // Parse the elements in the node into a string, and write - ParseAndWriteFilterNode(xmlFile, type, orFilter, true /*orFilter*/); - - // Close out filter object definition - WriteLine(" },"); - } - - // Close out declaration of the NodeOrFilter - WriteLine(" }"); - WriteLine(" });"); - } - - // Parse each of the top-level nodes in - foreach (var filterNode in filtersNode.SelectNodes("Filter")) - { - XmlElement filter = filterNode as XmlElement; - if (filter == null) - { - continue; - } - - // Start declaration of Filter node - WriteLine(" filters.Add(new NodePropertyFilter"); - - // Parse the elements in the node into a string, and write - ParseAndWriteFilterNode(xmlFile, type, filter); - - // Close out filter object definition - WriteLine(" });"); - } - - // Close out declaration of the Filters object - WriteLine(" return filters;"); - WriteLine(" }"); - WriteLine(" }"); - } - } - - if (smoProperties.Count > 0) - { - WriteLine(""); - WriteLine(" public override IEnumerable SmoProperties"); - WriteLine(" {"); - WriteLine(" get"); - WriteLine(" {"); - - WriteLine(" var properties = new List();"); - foreach (var smoPropertiy in smoProperties) - { - var propertyName = smoPropertiy.GetAttribute("Name"); - var validFor = smoPropertiy.GetAttribute("ValidFor"); - - WriteLine(" properties.Add(new NodeSmoProperty"); - WriteLine(" {"); - WriteLine(" Name = \"{0}\",", propertyName); - - if (!string.IsNullOrWhiteSpace(validFor)) - { - WriteLine(" ValidFor = {0}", GetValidForFlags(validFor)); - } - WriteLine(" });"); - } - - WriteLine(" return properties;"); - WriteLine(" }"); - WriteLine(" }"); - } - - if (children.Count > 0) - { - WriteLine(""); - WriteLine(" protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent)"); + var name = TreeNode.GetAttribute("Name"); + var type = !string.IsNullOrWhiteSpace(TreeNode.GetAttribute("Type")) ? TreeNode.GetAttribute("Type") : TreeNode.GetAttribute("Name"); + WriteLine(" internal sealed partial class {0} : SmoTreeNode", name); + WriteLine(" {"); + WriteLine(" public {0}() : base()", name); WriteLine(" {"); - foreach (var child in children) - { - var childName = child.GetAttribute("Name"); - - XmlElement childAsXmlElement = GetNodeElement(xmlFile, childName); - if (childAsXmlElement == null) - { - // TODO SHould we error with clear message that this needs to be fixed? - continue; - } - string childImage = childAsXmlElement.GetAttribute("Image"); - var msShippedOwned = childAsXmlElement.GetAttributeNode("IsMsShippedOwned"); - var validFor = childAsXmlElement.GetAttribute("ValidFor"); - - var sortPriority = childAsXmlElement.GetAttribute("SortPriority"); - if (sortPriority == string.Empty) - { - sortPriority = "SmoTreeNode.NextSortPriority"; - } - - if (TreeNodeExists(xmlFile, childName + "TreeNode")) - { - WriteLine(" currentChildren.Add(new {0}TreeNode {{ SortPriority = {1} }} );", childName, sortPriority); - } - else - { - WriteLine(" currentChildren.Add(new FolderNode {"); - WriteLine(" NodeValue = {0},", childAsXmlElement.GetAttribute("LocLabel")); - WriteLine(" NodeType = \"{0}\",", "Folder"); - WriteLine(" NodeTypeId = NodeTypes.{0},", childName); - WriteLine(" IsSystemObject = {0},", child.GetAttribute("IsSystemObject") == "1" ? "true" : "false"); - - if (msShippedOwned != null) - { - WriteLine(" IsMsShippedOwned = true,"); - } - if (!string.IsNullOrWhiteSpace(validFor)) - { - WriteLine(" ValidFor = {0},", GetValidForFlags(validFor)); - } - WriteLine(" SortPriority = {0},", sortPriority); - WriteLine(" });"); - } - } + WriteLine(" NodeValue = string.Empty;"); + WriteLine(" this.NodeType = \"{0}\";", type.Replace("TreeNode", string.Empty)); + WriteLine(" this.NodeTypeId = NodeTypes.{0};", name.Replace("TreeNode", string.Empty)); + WriteLine(" OnInitialize();"); WriteLine(" }"); - } - - if (!string.IsNullOrWhiteSpace(strategy)) - { - string[] allTypes = ChildQuerierTypes.Split(new [] { ';' }, StringSplitOptions.RemoveEmptyEntries); + WriteLine(" }"); WriteLine(""); - WriteLine(" internal override Type[] ChildQuerierTypes"); - WriteLine(" {"); - WriteLine(" get"); - WriteLine(" {"); - if (!string.IsNullOrWhiteSpace(ChildQuerierTypes)) - { - Write(" return new [] {"); - foreach (var typeToRe in allTypes) - { - Write(" typeof({0}Querier),", typeToRe); - } - WriteLine(" };"); - } - else - { - WriteLine(" return new Type[0];"); - } - WriteLine(" }"); - WriteLine(" }"); - - WriteLine(""); - - WriteLine(" public override TreeNode CreateChild(TreeNode parent, object context)"); - WriteLine(" {"); - if (string.IsNullOrWhiteSpace(TreeNode)) - { - WriteLine(" var child = new SmoTreeNode();"); - WriteLine(" child.IsAlwaysLeaf = true;"); - - if (!string.IsNullOrEmpty(nodeType)) - { - WriteLine(" child.NodeType = \"{0}\";", nodeType); - } - } - else - { - var modelNodeChildren = GetNodeElement(xmlFile, TreeNode.Replace("TreeNode",string.Empty)); - WriteLine(" var child = new {0}();", TreeNode); - if (modelNodeChildren.ChildNodes.Count == 0) - { - WriteLine(" child.IsAlwaysLeaf = true;"); - } - } - if (disableSort != null) - { - WriteLine(" child.SortPriority = SmoTreeNode.NextSortPriority;"); - } - WriteLine(" InitializeChild(parent, child, context);"); - WriteLine(" return child;"); - WriteLine(" }"); - } - else if (baseClass == "ModelBased") - { - WriteLine(""); - WriteLine(" internal override Type[] ChildQuerierTypes { get {return null;} }"); - WriteLine(""); - // TODO Is reverse engineering strategy every needed? - // WriteLine(" protected override ReverseEngineeringStrategy Strategy { get {return ReverseEngineeringStrategy.None;} }"); - WriteLine(""); - WriteLine(" public override TreeNode CreateChild(TreeNode parent, object context)"); - WriteLine(" {"); - WriteLine(" return null;"); - WriteLine(" }"); - } - - WriteLine(" }"); - WriteLine(""); } - } + + ///////// + // Now generate all the ChildFactories + ///////// + var allNodes = GetNodes(xmlFile); + foreach (var type in allNodes) + { + XmlElement nodeElement = GetNodeElement(xmlFile, type); + var imageAttr = nodeElement.GetAttribute("Image"); + 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 ConditionalChildQuerierTypes = nodeElement.GetElementsByTagName("ConditionalChildQuerierType"); + var TreeNode = nodeElement.GetAttribute("TreeNode"); + var isAsync = nodeElement.GetAttributeNode("IsAsyncLoad"); + var disableSort = nodeElement.GetAttributeNode("DisableSort"); + + string childFactoryBaseClass = "SmoChildFactoryBase"; + + // TODO Will we need alternative child factories? If so, add code here to support this + + if (isAlwaysLeaf == null) + { + WriteLine(" [Export(typeof(ChildFactory))]"); + WriteLine(" [Shared]"); + + WriteLine(" internal partial class {0}ChildFactory : {1}", type, childFactoryBaseClass); + + WriteLine(" {"); + if(!string.IsNullOrEmpty(nodeElement.GetAttribute("PutFoldersAfterNodes"))) + { + WriteLine(" public override bool PutFoldersAfterNodes => {0};", nodeElement.GetAttribute("PutFoldersAfterNodes")); + } + WriteLine(" public override IEnumerable ApplicableParents() {{ return new[] {{ nameof(NodeTypes.{0}) }}; }}", type); + + List children = GetChildren(xmlFile, type); + List smoProperties = GetNodeSmoProperties(xmlFile, type); + + // Load and parse Filters node + // A node is comprised of and nodes + // - A node defines the properties to construct a NodePropertyFilter object + // - An node defines a list of nodes that are or'ed in the resulting URN Query + // can have an arbitrary number of top-level and nodes. + // All filters defined at the top-level are and'ed in the resulting URN Query. + // This is generated into the IEnumerable Filters object for a particular SMO object. + // Currently there is not support for nested nodes + XmlNode filtersNode = GetFiltersNode(xmlFile, type); + if (filtersNode != null) + { + // Get the children nodes for the Filters + XmlNodeList childNodes = filtersNode.ChildNodes; + if (childNodes.Count > 0) + { + // Write initial declarator for the filters object + WriteLine(""); + WriteLine(" public override IEnumerable Filters"); + WriteLine(" {"); + WriteLine(" get"); + WriteLine(" {"); + WriteLine(" var filters = new List();"); + + // Parse each of the nodes in + foreach (var orNode in filtersNode.SelectNodes("Or")) + { + XmlElement or = orNode as XmlElement; + if (or == null) + { + continue; + } + + // Write initial declarator for the object, which is just a list of NodePropertyFilters + WriteLine(" filters.Add(new NodeOrFilter"); + WriteLine(" {"); + WriteLine(" FilterList = new List {"); + + foreach(var orFilterNode in or.GetElementsByTagName("Filter")) + { + XmlElement orFilter = orFilterNode as XmlElement; + if (orFilter == null) + { + continue; + } + + // Declaration of Filter node + WriteLine(" new NodePropertyFilter"); + + // Parse the elements in the node into a string, and write + ParseAndWriteFilterNode(xmlFile, type, orFilter, true /*orFilter*/); + + // Close out filter object definition + WriteLine(" },"); + } + + // Close out declaration of the NodeOrFilter + WriteLine(" }"); + WriteLine(" });"); + } + + // Parse each of the top-level nodes in + foreach (var filterNode in filtersNode.SelectNodes("Filter")) + { + XmlElement filter = filterNode as XmlElement; + if (filter == null) + { + continue; + } + + // Start declaration of Filter node + WriteLine(" filters.Add(new NodePropertyFilter"); + + // Parse the elements in the node into a string, and write + ParseAndWriteFilterNode(xmlFile, type, filter); + + // Close out filter object definition + WriteLine(" });"); + } + + // Close out declaration of the Filters object + WriteLine(" return filters;"); + WriteLine(" }"); + WriteLine(" }"); + } + } + + if (smoProperties.Count > 0) + { + WriteLine(""); + WriteLine(" public override IEnumerable SmoProperties"); + WriteLine(" {"); + WriteLine(" get"); + WriteLine(" {"); + + WriteLine(" var properties = new List();"); + foreach (var smoPropertiy in smoProperties) + { + var propertyName = smoPropertiy.GetAttribute("Name"); + var validFor = smoPropertiy.GetAttribute("ValidFor"); + + WriteLine(" properties.Add(new NodeSmoProperty"); + WriteLine(" {"); + WriteLine(" Name = \"{0}\",", propertyName); + + if (!string.IsNullOrWhiteSpace(validFor)) + { + WriteLine(" ValidFor = {0}", GetValidForFlags(validFor)); + } + WriteLine(" });"); + } + + WriteLine(" return properties;"); + WriteLine(" }"); + WriteLine(" }"); + } + + if (children.Count > 0) + { + WriteLine(""); + WriteLine(" protected override void OnExpandPopulateFolders(IList currentChildren, TreeNode parent)"); + WriteLine(" {"); + foreach (var child in children) + { + var childName = child.GetAttribute("Name"); + var settingsFlag = child.GetAttribute("SettingsFlag"); + + XmlElement childAsXmlElement = GetNodeElement(xmlFile, childName); + if (childAsXmlElement == null) + { + // TODO SHould we error with clear message that this needs to be fixed? + continue; + } + string childImage = childAsXmlElement.GetAttribute("Image"); + var msShippedOwned = childAsXmlElement.GetAttributeNode("IsMsShippedOwned"); + var validFor = childAsXmlElement.GetAttribute("ValidFor"); + + var sortPriority = childAsXmlElement.GetAttribute("SortPriority"); + if (sortPriority == string.Empty) + { + sortPriority = "SmoTreeNode.NextSortPriority"; + } + + var doesSettingsFlagExist = !string.IsNullOrEmpty(settingsFlag); + + if(doesSettingsFlagExist){ + WriteLine(" if ({0})", GetSettingsString(settingsFlag)); + WriteLine(" {"); + PushIndent(indent); + } + + if (TreeNodeExists(xmlFile, childName + "TreeNode")) + { + WriteLine(" currentChildren.Add(new {0}TreeNode {{ SortPriority = {1} }} );", childName, sortPriority); + } + else + { + WriteLine(" currentChildren.Add(new FolderNode {"); + WriteLine(" NodeValue = {0},", childAsXmlElement.GetAttribute("LocLabel")); + WriteLine(" NodeTypeId = NodeTypes.{0},", childName); + WriteLine(" IsSystemObject = {0},", child.GetAttribute("IsSystemObject") == "1" ? "true" : "false"); + + if (msShippedOwned != null) + { + WriteLine(" IsMsShippedOwned = true,"); + } + if (!string.IsNullOrWhiteSpace(validFor)) + { + WriteLine(" ValidFor = {0},", GetValidForFlags(validFor)); + } + WriteLine(" SortPriority = {0},", sortPriority); + WriteLine(" });"); + } + + if(doesSettingsFlagExist){ + PopIndent(); + WriteLine(" }"); + } + + } + WriteLine(" }"); + } + + if (!string.IsNullOrWhiteSpace(strategy)) + { + if(ConditionalChildQuerierTypes.Count > 0) + { + WriteLine(""); + WriteLine(" internal override Type[] ChildQuerierTypes"); + WriteLine(" {"); + WriteLine(" get"); + WriteLine(" {"); + WriteLine(" List conditionalTypesList = new List();"); + foreach(XmlElement Querier in ConditionalChildQuerierTypes) + { + var settingsFlag = Querier.GetAttribute("SettingsFlag"); + var QuerierName = Querier.GetAttribute("Name"); + + if(!string.IsNullOrEmpty(settingsFlag)) + { + WriteLine(" if ({0})", GetSettingsString(settingsFlag)); + WriteLine(" {"); + WriteLine(" conditionalTypesList.Add(typeof({0}Querier));", QuerierName); + WriteLine(" }"); + } + else + { + WriteLine(" conditionalTypesList.Add(typeof({0}Querier));", QuerierName); + } + } + WriteLine(" return conditionalTypesList.ToArray();"); + WriteLine(" }"); + WriteLine(" }"); + } + else + { + string[] allTypes = ChildQuerierTypes.Split(new [] { ';' }, StringSplitOptions.RemoveEmptyEntries); + WriteLine(""); + WriteLine(" internal override Type[] ChildQuerierTypes"); + WriteLine(" {"); + WriteLine(" get"); + WriteLine(" {"); + if (!string.IsNullOrWhiteSpace(ChildQuerierTypes)) + { + Write(" return new [] {"); + foreach (var typeToRe in allTypes) + { + Write(" typeof({0}Querier),", typeToRe); + } + WriteLine(" };"); + } + else + { + WriteLine(" return new Type[0];"); + } + WriteLine(" }"); + WriteLine(" }"); + } + + WriteLine(""); + + WriteLine(" public override TreeNode CreateChild(TreeNode parent, object context)"); + WriteLine(" {"); + if (string.IsNullOrWhiteSpace(TreeNode)) + { + WriteLine(" var child = new SmoTreeNode();"); + WriteLine(" child.IsAlwaysLeaf = true;"); + + if (!string.IsNullOrEmpty(nodeType)) + { + WriteLine(" child.NodeType = \"{0}\";", nodeType); + } + } + else + { + var modelNodeChildren = GetNodeElement(xmlFile, TreeNode.Replace("TreeNode",string.Empty)); + WriteLine(" var child = new {0}();", TreeNode); + if (modelNodeChildren.ChildNodes.Count == 0) + { + WriteLine(" child.IsAlwaysLeaf = true;"); + } + } + if (disableSort != null) + { + WriteLine(" child.SortPriority = SmoTreeNode.NextSortPriority;"); + } + WriteLine(" InitializeChild(parent, child, context);"); + WriteLine(" return child;"); + WriteLine(" }"); + } + else if (baseClass == "ModelBased") + { + WriteLine(""); + WriteLine(" internal override Type[] ChildQuerierTypes { get {return null;} }"); + WriteLine(""); + // TODO Is reverse engineering strategy every needed? + // WriteLine(" protected override ReverseEngineeringStrategy Strategy { get {return ReverseEngineeringStrategy.None;} }"); + WriteLine(""); + WriteLine(" public override TreeNode CreateChild(TreeNode parent, object context)"); + WriteLine(" {"); + WriteLine(" return null;"); + WriteLine(" }"); + } + + WriteLine(" }"); + WriteLine(""); + } + } #> } <#+ - public static string GetValidForFlags(string validForStr) - { - var flags = validForStr.Split('|').Select(validForFlag => "ValidForFlag." + validForFlag); - - return string.Join("|", flags); - } - - public static string[] GetNodes(string xmlFile) - { - List typesList = new List(); - XmlDocument doc = new XmlDocument(); - doc.Load(xmlFile); - XmlNodeList treeTypes = doc.SelectNodes("/ServerExplorerTree/Node"); - if (treeTypes != null) + public static string GetValidForFlags(string validForStr) { - foreach (var type in treeTypes) - { - XmlElement element = type as XmlElement; - if (element != null) + var flags = validForStr.Split('|').Select(validForFlag => "ValidForFlag." + validForFlag); + + return string.Join("|", flags); + } + + public static string[] GetNodes(string xmlFile) + { + List typesList = new List(); + XmlDocument doc = new XmlDocument(); + doc.Load(xmlFile); + XmlNodeList treeTypes = doc.SelectNodes("/ServerExplorerTree/Node"); + if (treeTypes != null) { - typesList.Add(element.GetAttribute("Name")); + foreach (var type in treeTypes) + { + XmlElement element = type as XmlElement; + if (element != null) + { + typesList.Add(element.GetAttribute("Name")); + } + } } - } + return typesList.ToArray(); } - return typesList.ToArray(); - } - public static Dictionary> GetReverseDependencies(string xmlFile) - { - Dictionary> dependencyMap = new Dictionary>(); - XmlDocument doc = new XmlDocument(); - doc.Load(xmlFile); - XmlNodeList treeTypes = doc.SelectNodes("/ServerExplorerTree/ReverseDependencyList/ReverseDependency"); - if (treeTypes != null) + public static Dictionary> GetReverseDependencies(string xmlFile) { - foreach (var type in treeTypes) - { - XmlElement element = type as XmlElement; - if (element != null) + Dictionary> dependencyMap = new Dictionary>(); + XmlDocument doc = new XmlDocument(); + doc.Load(xmlFile); + XmlNodeList treeTypes = doc.SelectNodes("/ServerExplorerTree/ReverseDependencyList/ReverseDependency"); + if (treeTypes != null) { - string typeName = element.GetAttribute("Type"); - string dependency = element.GetAttribute("DependsOn"); - List dependenciesForType; - if (dependencyMap.TryGetValue(typeName, out dependenciesForType)) - { - dependenciesForType.Add(dependency); - } - else - { - string[] allDepedencies = dependency.Split(new [] { ';' }, StringSplitOptions.RemoveEmptyEntries); - dependenciesForType = new List(); - dependenciesForType.AddRange(allDepedencies); - dependencyMap.Add(typeName, dependenciesForType); - } + foreach (var type in treeTypes) + { + XmlElement element = type as XmlElement; + if (element != null) + { + string typeName = element.GetAttribute("Type"); + string dependency = element.GetAttribute("DependsOn"); + List dependenciesForType; + if (dependencyMap.TryGetValue(typeName, out dependenciesForType)) + { + dependenciesForType.Add(dependency); + } + else + { + string[] allDepedencies = dependency.Split(new [] { ';' }, StringSplitOptions.RemoveEmptyEntries); + dependenciesForType = new List(); + dependenciesForType.AddRange(allDepedencies); + dependencyMap.Add(typeName, dependenciesForType); + } + } + } } - } + return dependencyMap; } - return dependencyMap; - } - public static XmlElement GetNodeElement(string xmlFile, string nodeName) - { - XmlDocument doc = new XmlDocument(); - doc.Load(xmlFile); - return (XmlElement)doc.SelectSingleNode(string.Format("/ServerExplorerTree/Node[@Name='{0}']", nodeName)); - } - - public static bool TreeNodeExists(string xmlFile, string TreeNode) - { - XmlDocument doc = new XmlDocument(); - doc.Load(xmlFile); - var found = (XmlElement)doc.SelectSingleNode(string.Format("/ServerExplorerTree/CodeGenOptions/UniqueTreeNode[@Name='{0}']", TreeNode)); - - return (found != null); - } - - public static List GetUniqueTreeNodes(string xmlFile) - { - XmlDocument doc = new XmlDocument(); - doc.Load(xmlFile); - - List retElements = new List(); - XmlNodeList nodeList = doc.SelectNodes("/ServerExplorerTree/CodeGenOptions/UniqueTreeNode"); - foreach (var item in nodeList) + public static XmlElement GetNodeElement(string xmlFile, string nodeName) { - XmlElement itemAsElement = item as XmlElement; - if (itemAsElement != null) - { - retElements.Add(itemAsElement); - } + XmlDocument doc = new XmlDocument(); + doc.Load(xmlFile); + return (XmlElement)doc.SelectSingleNode(string.Format("/ServerExplorerTree/Node[@Name='{0}']", nodeName)); } - return retElements; - } - public static List GetChildren(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}']/Child", parentName)); - foreach (var item in nodeList) + public static bool TreeNodeExists(string xmlFile, string TreeNode) { - XmlElement itemAsElement = item as XmlElement; - if (itemAsElement != null) - { - retElements.Add(itemAsElement); - } + XmlDocument doc = new XmlDocument(); + doc.Load(xmlFile); + var found = (XmlElement)doc.SelectSingleNode(string.Format("/ServerExplorerTree/CodeGenOptions/UniqueTreeNode[@Name='{0}']", TreeNode)); + + return (found != null); } - return retElements; - } - public static List GetNodeOrFilters(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/Or/Filter", parentName)); - foreach (var item in nodeList) + public static List GetUniqueTreeNodes(string xmlFile) { - XmlElement itemAsElement = item as XmlElement; - if (itemAsElement != null) - { - retElements.Add(itemAsElement); - } + XmlDocument doc = new XmlDocument(); + doc.Load(xmlFile); + + List retElements = new List(); + XmlNodeList nodeList = doc.SelectNodes("/ServerExplorerTree/CodeGenOptions/UniqueTreeNode"); + foreach (var item in nodeList) + { + XmlElement itemAsElement = item as XmlElement; + if (itemAsElement != null) + { + retElements.Add(itemAsElement); + } + } + return retElements; } - return retElements; - } - public static XmlNode GetFiltersNode(string xmlFile, string parentName) - { - XmlElement nodeElement = GetNodeElement(xmlFile, parentName); - XmlDocument doc = new XmlDocument(); - doc.Load(xmlFile); - - return doc.SelectSingleNode(string.Format("/ServerExplorerTree/Node[@Name='{0}']/Filters", parentName)); - } - - public static List GetNodeSmoProperties(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}']/Properties/Property", parentName)); - foreach (var item in nodeList) + public static List GetChildren(string xmlFile, string parentName) { - XmlElement itemAsElement = item as XmlElement; - if (itemAsElement != null) - { - retElements.Add(itemAsElement); - } + 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}']/Child", parentName)); + foreach (var item in nodeList) + { + XmlElement itemAsElement = item as XmlElement; + if (itemAsElement != null) + { + retElements.Add(itemAsElement); + } + } + return retElements; } - return retElements; - } - public static List GetNodeFilterValues(string xmlFile, string parentName, string filterProperty, bool orFilter = false) - { - XmlElement nodeElement = GetNodeElement(xmlFile, parentName); - XmlDocument doc = new XmlDocument(); - doc.Load(xmlFile); - - List retElements = new List(); - - var xpath = string.Format( - "/ServerExplorerTree/Node[@Name='{0}']/Filters/{1}Filter[@Property='{2}']/Value", - parentName, - orFilter ? "Or/" : string.Empty, - filterProperty); - XmlNodeList nodeList = doc.SelectNodes(xpath); - foreach (var item in nodeList) + public static List GetNodeOrFilters(string xmlFile, string parentName) { - XmlElement itemAsElement = item as XmlElement; - if (itemAsElement != null) - { - retElements.Add(itemAsElement); - } + 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/Or/Filter", parentName)); + foreach (var item in nodeList) + { + XmlElement itemAsElement = item as XmlElement; + if (itemAsElement != null) + { + retElements.Add(itemAsElement); + } + } + return retElements; } - return retElements; - } - /// - /// Helper function to parse out and write the contents of a node. - /// - /// Base xml doc - /// name of the parent object in the xml - /// The filter to be parsed - /// Whether this filter is a sub-node of an node - public void ParseAndWriteFilterNode(string xmlFile, string parentName, XmlElement filter, bool orFilter = false) - { - // Filters start at a larger base indentation than nodes directly under - var indent = orFilter ? " " : " "; - - var propertyName = filter.GetAttribute("Property"); - var propertyType = filter.GetAttribute("Type"); - var propertyValue = filter.GetAttribute("Value"); - var validFor = filter.GetAttribute("ValidFor"); - var typeToReverse = filter.GetAttribute("TypeToReverse"); - - List filterValues = GetNodeFilterValues(xmlFile, parentName, propertyName, orFilter); - - // Write out the "meat" of the object definition - WriteLine(indent + "{"); - WriteLine(indent + " Property = \"{0}\",", propertyName); - WriteLine(indent + " Type = typeof({0}),", propertyType); - if (!string.IsNullOrWhiteSpace(typeToReverse)) + public static XmlNode GetFiltersNode(string xmlFile, string parentName) { - WriteLine(indent + " TypeToReverse = typeof({0}Querier),", typeToReverse); - } - if (!string.IsNullOrWhiteSpace(validFor)) - { - WriteLine(indent + " ValidFor = {0},", GetValidForFlags(validFor)); - } - if (propertyValue != null && (filterValues == null || filterValues.Count == 0)) - { - WriteLine(indent + " Values = new List {{ {0} }},", propertyValue); - } - if (filterValues != null && filterValues.Count > 0) - { - WriteLine(indent + " Values = new List"); - WriteLine(indent + " {"); + XmlElement nodeElement = GetNodeElement(xmlFile, parentName); + XmlDocument doc = new XmlDocument(); + doc.Load(xmlFile); - for(int i = 0; i < filterValues.Count; i++) - { - string separator = (i != filterValues.Count - 1) ? "," : ""; - var filterValue = filterValues[i]; - WriteLine(indent + " {{ {0} }}{1}", filterValue.InnerText, separator); - } - - WriteLine(indent + " }"); + return doc.SelectSingleNode(string.Format("/ServerExplorerTree/Node[@Name='{0}']/Filters", parentName)); + } + + public static List GetNodeSmoProperties(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}']/Properties/Property", 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, bool orFilter = false) + { + XmlElement nodeElement = GetNodeElement(xmlFile, parentName); + XmlDocument doc = new XmlDocument(); + doc.Load(xmlFile); + + List retElements = new List(); + + var xpath = string.Format( + "/ServerExplorerTree/Node[@Name='{0}']/Filters/{1}Filter[@Property='{2}']/Value", + parentName, + orFilter ? "Or/" : string.Empty, + filterProperty); + XmlNodeList nodeList = doc.SelectNodes(xpath); + foreach (var item in nodeList) + { + XmlElement itemAsElement = item as XmlElement; + if (itemAsElement != null) + { + retElements.Add(itemAsElement); + } + } + return retElements; + } + + /// + /// Helper function to parse out and write the contents of a node. + /// + /// Base xml doc + /// name of the parent object in the xml + /// The filter to be parsed + /// Whether this filter is a sub-node of an node + public void ParseAndWriteFilterNode(string xmlFile, string parentName, XmlElement filter, bool orFilter = false) + { + // Filters start at a larger base indentation than nodes directly under + var indent = orFilter ? " " : " "; + + var propertyName = filter.GetAttribute("Property"); + var propertyType = filter.GetAttribute("Type"); + var propertyValue = filter.GetAttribute("Value"); + var validFor = filter.GetAttribute("ValidFor"); + var typeToReverse = filter.GetAttribute("TypeToReverse"); + + List filterValues = GetNodeFilterValues(xmlFile, parentName, propertyName, orFilter); + + // Write out the "meat" of the object definition + WriteLine(indent + "{"); + WriteLine(indent + " Property = \"{0}\",", propertyName); + WriteLine(indent + " Type = typeof({0}),", propertyType); + if (!string.IsNullOrWhiteSpace(typeToReverse)) + { + WriteLine(indent + " TypeToReverse = typeof({0}Querier),", typeToReverse); + } + if (!string.IsNullOrWhiteSpace(validFor)) + { + WriteLine(indent + " ValidFor = {0},", GetValidForFlags(validFor)); + } + if (propertyValue != null && (filterValues == null || filterValues.Count == 0)) + { + WriteLine(indent + " Values = new List {{ {0} }},", propertyValue); + } + if (filterValues != null && filterValues.Count > 0) + { + WriteLine(indent + " Values = new List"); + WriteLine(indent + " {"); + + for(int i = 0; i < filterValues.Count; i++) + { + string separator = (i != filterValues.Count - 1) ? "," : ""; + var filterValue = filterValues[i]; + WriteLine(indent + " {{ {0} }}{1}", filterValue.InnerText, separator); + } + + WriteLine(indent + " }"); + } + } + + /// + /// Helper function to parse out settings Name with not operators and return code to + /// + public string GetSettingsString(string settingsName) + { + var notOperator = ""; + if(settingsName.Substring(0, 1) == "!"){ + notOperator = "!"; + settingsName = settingsName.Substring(1, settingsName.Length-1); + } + return String.Format("{0}WorkspaceService.Instance.CurrentSettings.SqlTools.ObjectExplorer.{1}", notOperator, settingsName); } - } #> \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodesDefinition.xml b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodesDefinition.xml index 375fc2c1..7e31f73c 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodesDefinition.xml +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodesDefinition.xml @@ -62,10 +62,11 @@ - - - - + + + + + @@ -73,6 +74,13 @@ + + + + + + + @@ -115,15 +123,21 @@ - - + + - + + + + + + + @@ -511,6 +525,7 @@ + diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlContext/ObjectExplorerSettings.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlContext/ObjectExplorerSettings.cs index cc7c1c5e..8b65752b 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SqlContext/ObjectExplorerSettings.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SqlContext/ObjectExplorerSettings.cs @@ -14,11 +14,13 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlContext { public static int DefaultCreateSessionTimeout = 45; public static int DefaultExpandTimeout = 45; + public static bool DefaultGroupBySchema = false; public ObjectExplorerSettings() { CreateSessionTimeout = DefaultCreateSessionTimeout; ExpandTimeout = DefaultExpandTimeout; + GroupBySchema = DefaultGroupBySchema; } /// @@ -30,5 +32,11 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlContext /// Number of seconds to wait before fail expand request with timeout error /// public int ExpandTimeout { get; set; } + + /// + /// Moves Schema to the top level of OE and then move schema-bound nodes under it. + /// + /// + public bool GroupBySchema { get; set; } } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/Workspace/WorkspaceService.cs b/src/Microsoft.SqlTools.ServiceLayer/Workspace/WorkspaceService.cs index 65686638..93e2b0f2 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Workspace/WorkspaceService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Workspace/WorkspaceService.cs @@ -331,6 +331,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace { Logger.Write(TraceEventType.Verbose, "HandleDidChangeConfigurationNotification"); + this.CurrentSettings = configChangeParams.Settings; // Propagate the changes to the event handlers var configUpdateTasks = ConfigChangeCallbacks.Select( t => t(configChangeParams.Settings, CurrentSettings, eventContext)); diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/ObjectExplorerServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/ObjectExplorerServiceTests.cs index e046fa9f..27767f01 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/ObjectExplorerServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/ObjectExplorerServiceTests.cs @@ -19,8 +19,10 @@ 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.SqlContext; using Microsoft.SqlTools.ServiceLayer.Test.Common; using Microsoft.SqlTools.ServiceLayer.Test.Common.Extensions; +using Microsoft.SqlTools.ServiceLayer.Workspace; using NUnit.Framework; using static Microsoft.SqlTools.ServiceLayer.ObjectExplorer.ObjectExplorerService; @@ -210,6 +212,50 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer }); } + [Test] + public async Task GroupBySchemaisDisabled() + { + string query = @"Create schema t1 + GO + Create schema t2 + GO"; + string databaseName = "#testDb#"; + await RunTest(databaseName, query, "TestDb", async (testDbName, session) => + { + WorkspaceService.Instance.CurrentSettings.SqlTools.ObjectExplorer = new ObjectExplorerSettings() { GroupBySchema = false }; + var databaseNode = session.Root.ToNodeInfo(); + var databaseChildren = await _service.ExpandNode(session, databaseNode.NodePath); + Assert.True(databaseChildren.Nodes.Any(t => t.Label == SR.SchemaHierarchy_Tables), "Tables node should be found in database node when group by schema is disabled"); + Assert.True(databaseChildren.Nodes.Any(t => t.Label == SR.SchemaHierarchy_Views), "Views node should be found in database node when group by schema is disabled"); + }); + } + + [Test] + public async Task GroupBySchemaisEnabled() + { + string query = @"Create schema t1 + GO + Create schema t2 + GO"; + string databaseName = "#testDb#"; + await RunTest(databaseName, query, "TestDb", async (testDbName, session) => + { + WorkspaceService.Instance.CurrentSettings.SqlTools.ObjectExplorer = new ObjectExplorerSettings() { GroupBySchema = true }; + var databaseNode = session.Root.ToNodeInfo(); + var databaseChildren = await _service.ExpandNode(session, databaseNode.NodePath); + Assert.True(databaseChildren.Nodes.Any(t => t.Label == "t1"), "Schema node t1 should be found in database node when group by schema is enabled"); + Assert.True(databaseChildren.Nodes.Any(t => t.Label == "t2"), "Schema node t2 should be found in database node when group by schema is enabled"); + Assert.False(databaseChildren.Nodes.Any(t => t.Label == SR.SchemaHierarchy_Tables), "Tables node should not be found in database node when group by schema is enabled"); + Assert.False(databaseChildren.Nodes.Any(t => t.Label == SR.SchemaHierarchy_Views), "Views node should not be found in database node when group by schema is enabled"); + Assert.True(databaseChildren.Nodes.Any(t => t.Label == SR.SchemaHierarchy_Programmability), "Programmability node should be found in database node when group by schema is enabled"); + var lastSchemaPosition = Array.FindLastIndex(databaseChildren.Nodes, t => t.ObjectType == nameof(NodeTypes.ExpandableSchema)); + var firstNonSchemaPosition = Array.FindIndex(databaseChildren.Nodes, t => t.ObjectType != nameof(NodeTypes.ExpandableSchema)); + Assert.True(lastSchemaPosition < firstNonSchemaPosition, "Schema nodes should be before non-schema nodes"); + WorkspaceService.Instance.CurrentSettings.SqlTools.ObjectExplorer = new ObjectExplorerSettings() { GroupBySchema = false }; + }); + } + + private async Task VerifyRefresh(ObjectExplorerSession session, string tablePath, string tableName, bool deleted = true) { //Refresh Root @@ -217,7 +263,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer //Verify tables cache is empty var rootChildrenCache = session.Root.GetChildren(); - var tablesCache = rootChildrenCache.First(x => x.Label == SR.SchemaHierarchy_Tables).GetChildren(); + var tablesCache = rootChildrenCache.First(x => x.Label == SR.SchemaHierarchy_Tables).GetChildren(); Assert.False(tablesCache.Any()); //Expand Tables @@ -292,7 +338,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer ConnectionDetails details = connectParams.Connection; string uri = ObjectExplorerService.GenerateUri(details); - var session = 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; } @@ -403,7 +449,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer /// private async Task FindNodeByLabel(NodeInfo node, ObjectExplorerSession session, string label) { - if(node != null && node.Label == label) + if (node != null && node.Label == label) { return node; } @@ -434,7 +480,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer { // These are node types for which the label doesn't include a schema // (usually because the objects themselves aren't schema-bound) - var schemalessLabelNodeTypes = new List () { + var schemalessLabelNodeTypes = new List() { "Column", "Key", "Constraint", diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/ObjectExplorer/GroupBySchemaTests.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/ObjectExplorer/GroupBySchemaTests.cs new file mode 100644 index 00000000..dd57a696 --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/ObjectExplorer/GroupBySchemaTests.cs @@ -0,0 +1,66 @@ +// +// 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.Linq; +using Microsoft.SqlServer.Management.Smo; +using Microsoft.SqlTools.ServiceLayer.ObjectExplorer; +using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; +using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel; +using Microsoft.SqlTools.ServiceLayer.SqlContext; +using Microsoft.SqlTools.ServiceLayer.Workspace; +using Moq; +using NUnit.Framework; + +namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer +{ + class GroupBySchemaTests + { + Mock factory; + Mock node; + + [SetUp] + public void init() + { + factory = new Mock(); + factory.SetupGet(c => c.ChildQuerierTypes).Returns(null as Type[]); + factory.Setup(c => c.CreateChild(It.IsAny(), It.IsAny())).Returns((TreeNode node, Schema obj) => { + return new TreeNode(){ + Label = obj.Name, + NodeType = nameof(NodeTypes.Schemas) + }; + }); + factory.CallBase = true; + Mock context = new Mock(new Server(), null); + context.CallBase = true; + context.Object.ValidFor = ValidForFlag.None; + + node = new Mock(); + node.Setup(n => n.GetContext()).Returns(context.Object); + } + + [Test] + public void SchemaBasedFoldersExcludedWhenGroupBySchemaIsEnabled() + { + WorkspaceService.Instance.CurrentSettings.SqlTools.ObjectExplorer = new ObjectExplorerSettings() { GroupBySchema = true }; + var children = factory.Object.Expand(node.Object, true, "TestDB", true, new System.Threading.CancellationToken()); + Assert.False(children.Any(c => c.Label == "Tables"), "Tables subfolder in database should be excluded when group by schema is enabled"); + Assert.False(children.Any(c => c.Label == "Views"), "Views subfolder in database should be excluded when group by schema is enabled"); + Assert.False(children.Any(c => c.Label == "Synonyms"), "Synonyms subfolder in database should be excluded when group by schema is enabled"); + } + + [Test] + public void SchemaBasedFoldersIncludedWhenGroupBySchemaIsDisabled() + { + WorkspaceService.Instance.CurrentSettings.SqlTools.ObjectExplorer = new ObjectExplorerSettings() { GroupBySchema = false }; + var children = factory.Object.Expand(node.Object, true, "TestDB", true, new System.Threading.CancellationToken()); + Assert.True(children.Any(c => c.Label == "Tables"), "Tables subfolder in database should be included when group by schema is disabled"); + Assert.True(children.Any(c => c.Label == "Views"), "Views subfolder in database should be included when group by schema is disabled"); + Assert.True(children.Any(c => c.Label == "Synonyms"), "Synonyms subfolder in database should be included when group by schema is disabled"); + } + + + } + +} \ No newline at end of file diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/ObjectExplorer/NodeFilterTests.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/ObjectExplorer/NodeFilterTests.cs index f796b16c..b9a7fece 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/ObjectExplorer/NodeFilterTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/ObjectExplorer/NodeFilterTests.cs @@ -193,5 +193,30 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer string expectedTableQuerierFilters = "[(@IsSystemObject = 1) and ((@IsSystemObject = 1))]"; Assert.That(invalidQuerierType, Is.EqualTo(expectedTableQuerierFilters), "GetPropertyFilter did not construct the URN filter string as expected when excluding filters that don't match the querier type."); } + [Test] + public void TestAddPropertyFiltersToExistingURNs() + { + var Node = new List { + TemporalFilter, + LedgerHistoryFilter + }; + + var nodeList = new List { + new NodePropertyFilter(){ + Property = "Schema", + Values = new List {"jsdafl983!@$#%535343]]]][[["}, + Type = typeof(string), + ValidFor = ValidForFlag.Sql2022OrHigher + } + }; + + string allFiltersValid = INodeFilter.GetPropertyFilter(Node, typeof(SqlHistoryTableQuerier), ValidForFlag.Sql2022OrHigher); + string expectedAllFilters = "[(@TemporalType = 1) and (@LedgerType = 1)]"; + Assert.That(allFiltersValid, Is.EqualTo(expectedAllFilters), "GetPropertyFilter did not construct the URN filter string as expected"); + + string newUrn = INodeFilter.AddPropertyFilterToFilterString(allFiltersValid, nodeList, typeof(SqlHistoryTableQuerier), ValidForFlag.Sql2022OrHigher); + string expectedNewUrn = "[(@TemporalType = 1) and (@LedgerType = 1) and (@Schema = 'jsdafl983!@$#%535343]]]][[[')]"; + Assert.That(newUrn, Is.EqualTo(expectedNewUrn), "GetPropertyFilter did not construct the URN filter string as expected"); + } } }