Creating a new Sql Core project that stores OE classes. (#2165)

* init

* More fixes

* moving filters from contracts to core OE classes

* Fixing some tests

* More fixes and added doc comments

* Fixing tests

* Quick refactoring

* more cleanups

* cleanup

* Adding stateless OE

* Adding null checks

* Making group by schema independent of settings

* Fixing tests

* Removing node info from core oe code

* Fixing tests and moving OE code to its own project

* moving oe to own project

* Removing changes to Kusto

* Removing azure access token from service layer

* Fixing project description and title

* Fixing file name typo

* Removing unused  strings from service layer

* Fixing localized strings in tests
Adding comments to stateless OE

* Fixing stuff

* Update src/Microsoft.SqlTools.SqlCore/Microsoft.SqlTools.SqlCore.csproj

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Fixing project nesting

* Fixing more stuff and removing OE class

* Cleanup

* Code cleanup

* fixing oe service provider

* Fixing test name

* Remove using

* Update src/Microsoft.SqlTools.SqlCore/ObjectExplorer/SmoModel/SmoQueryContext.cs

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Fixing syntax error

* Adding project to locproject

* Fixing stuff

* Fixing errors

* sorting usings

---------

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
This commit is contained in:
Aasim Khan
2023-08-17 05:11:35 +00:00
committed by GitHub
parent 4ae9534ac8
commit 73c2a75fba
98 changed files with 6755 additions and 6116 deletions

View File

@@ -44,6 +44,12 @@
"LclFile": "src\\Microsoft.Kusto.ServiceLayer\\Localization\\LCL\\{Lang}\\sr.xlf.lcl",
"CopyOption": "LangIDOnName",
"OutputPath": "src\\Microsoft.Kusto.ServiceLayer\\Localization\\transXliff"
},
{
"SourceFile": "src\\Microsoft.SqlTools.SqlCore\\Localization\\sr.xlf",
"LclFile": "src\\Microsoft.SqlTools.SqlCore\\Localization\\LCL\\{Lang}\\sr.xlf.lcl",
"CopyOption": "LangIDOnName",
"OutputPath": "src\\Microsoft.SqlTools.SqlCore\\Localization\\transXliff"
}
]
}

View File

@@ -17,6 +17,7 @@ using AzureEdition = Microsoft.SqlTools.ServiceLayer.Admin.AzureSqlDbHelper.Azur
using System;
using System.Data;
using Microsoft.SqlTools.Utility;
using Microsoft.SqlTools.SqlCore.Utility;
namespace Microsoft.SqlTools.ServiceLayer.Admin
{
@@ -377,7 +378,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
private static string CreateAzureAlterDbStatement(string dbName, string options)
{
return string.Format(CultureInfo.InvariantCulture, AlterDbStatementFormat,
CUtils.EscapeString(CUtils.EscapeString(dbName, ']'), '\''),
StringUtils.EscapeString(StringUtils.EscapeString(dbName, ']'), '\''),
options);
}
}

View File

@@ -11,6 +11,7 @@ using System.Collections.Generic;
using System.Data.Common;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
using Microsoft.SqlTools.SqlCore.Connection;
using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.Connection

View File

@@ -29,6 +29,7 @@ using Microsoft.SqlTools.Authentication;
using System.IO;
using Microsoft.SqlTools.Hosting.Utility;
using Constants = Microsoft.SqlTools.Hosting.Protocol.Constants;
using Microsoft.SqlTools.SqlCore.Connection;
namespace Microsoft.SqlTools.ServiceLayer.Connection
{
@@ -1983,24 +1984,4 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
return databaseName != null ? databaseName.IndexOf('@') != -1 : false;
}
}
public class AzureAccessToken : IRenewableToken
{
public DateTimeOffset TokenExpiry { get; set; }
public string Resource { get; set; }
public string Tenant { get; set; }
public string UserId { get; set; }
private string accessToken;
public AzureAccessToken(string accessToken)
{
this.accessToken = accessToken;
}
public string GetAccessToken()
{
return this.accessToken;
}
}
}

View File

@@ -11,7 +11,7 @@ using System.Data.Common;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlTools.ServiceLayer.Admin.Contracts;
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
using Microsoft.SqlTools.ServiceLayer.Utility;
using Microsoft.SqlTools.SqlCore.Utility;
using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.Connection

View File

@@ -11,9 +11,9 @@ using System.Data.Common;
using Microsoft.Data.SqlClient;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection;
using Microsoft.SqlTools.ServiceLayer.Utility.SqlScriptFormatters;
using Microsoft.SqlTools.SqlCore.Connection;
using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.EditData

View File

@@ -82,7 +82,8 @@ namespace Microsoft.SqlTools.ServiceLayer
ExtensionServiceProvider serviceProvider = ExtensionServiceProvider.CreateDefaultServiceProvider(new string[] {
"microsofsqltoolscredentials.dll",
"microsoft.sqltools.hosting.dll",
"microsoftsqltoolsservicelayer.dll"
"microsoftsqltoolsservicelayer.dll",
"microsoftsqltoolssqlcore.dll"
});
serviceProvider.RegisterSingleService(sqlToolsContext);
serviceProvider.RegisterSingleService(serviceHost);

View File

@@ -6,7 +6,7 @@
#nullable disable
using Microsoft.SqlTools.ServiceLayer.LanguageExtensibility.Contracts;
using Microsoft.SqlTools.ServiceLayer.Management;
using Microsoft.SqlTools.SqlCore.Utility;
using Microsoft.SqlTools.Utility;
using System;
using System.Collections.Generic;
@@ -67,7 +67,7 @@ ORDER BY platform";
private string GetDropScript(string languageName)
{
return $@"{DropScript} [{CUtils.EscapeStringCBracket(languageName)}]";
return $@"{DropScript} [{StringUtils.EscapeStringCBracket(languageName)}]";
}
/// <summary>
@@ -262,7 +262,7 @@ ORDER BY platform";
contentScript = $"{contentScript}{seperator}{GetLanguageContent(content, i, parameters)}";
}
string ownerScript = string.IsNullOrWhiteSpace(language.Owner) ? "" : $"AUTHORIZATION [{CUtils.EscapeStringCBracket(language.Owner)}]";
string ownerScript = string.IsNullOrWhiteSpace(language.Owner) ? "" : $"AUTHORIZATION [{StringUtils.EscapeStringCBracket(language.Owner)}]";
string scriptAction = modifyType == ModifyType.Create ? CreateScript : AlterScript;
string contentAction = "FROM";
if (modifyType == ModifyType.Alter)
@@ -281,7 +281,7 @@ ORDER BY platform";
}
}
return $@"
{scriptAction} [{CUtils.EscapeStringCBracket(language.Name)}]
{scriptAction} [{StringUtils.EscapeStringCBracket(language.Name)}]
{ownerScript}
{contentAction} {contentScript}
";
@@ -289,7 +289,7 @@ ORDER BY platform";
private string AddStringParameter(string paramName, string prefix, string paramValue)
{
string value = string.IsNullOrWhiteSpace(paramValue) ? paramValue : CUtils.EscapeStringSQuote(paramValue);
string value = string.IsNullOrWhiteSpace(paramValue) ? paramValue : StringUtils.EscapeStringSQuote(paramValue);
return $"{prefix} {paramName} = N'{value}'";
}

File diff suppressed because it is too large Load Diff

View File

@@ -678,854 +678,6 @@
<value>Scalar column missing scale</value>
<comment></comment>
</data>
<data name="TreeNodeError" xml:space="preserve">
<value>Error expanding: {0}</value>
<comment></comment>
</data>
<data name="ServerNodeConnectionError" xml:space="preserve">
<value>Error connecting to {0}</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Aggregates" xml:space="preserve">
<value>Aggregates</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerRoles" xml:space="preserve">
<value>Server Roles</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ApplicationRoles" xml:space="preserve">
<value>Application Roles</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Assemblies" xml:space="preserve">
<value>Assemblies</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_AssemblyFiles" xml:space="preserve">
<value>Assembly Files</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_AsymmetricKeys" xml:space="preserve">
<value>Asymmetric Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DatabaseAsymmetricKeys" xml:space="preserve">
<value>Asymmetric Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DataCompressionOptions" xml:space="preserve">
<value>Data Compression Options</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Certificates" xml:space="preserve">
<value>Certificates</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_FileTables" xml:space="preserve">
<value>FileTables</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DatabaseCertificates" xml:space="preserve">
<value>Certificates</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_CheckConstraints" xml:space="preserve">
<value>Check Constraints</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Columns" xml:space="preserve">
<value>Columns</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Constraints" xml:space="preserve">
<value>Constraints</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Contracts" xml:space="preserve">
<value>Contracts</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Credentials" xml:space="preserve">
<value>Credentials</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ErrorMessages" xml:space="preserve">
<value>Error Messages</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerRoleMembership" xml:space="preserve">
<value>Server Role Membership</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DatabaseOptions" xml:space="preserve">
<value>Database Options</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DatabaseRoles" xml:space="preserve">
<value>Database Roles</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_RoleMemberships" xml:space="preserve">
<value>Role Memberships</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DatabaseTriggers" xml:space="preserve">
<value>Database Triggers</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DefaultConstraints" xml:space="preserve">
<value>Default Constraints</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Defaults" xml:space="preserve">
<value>Defaults</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Sequences" xml:space="preserve">
<value>Sequences</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Endpoints" xml:space="preserve">
<value>Endpoints</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_EventNotifications" xml:space="preserve">
<value>Event Notifications</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerEventNotifications" xml:space="preserve">
<value>Server Event Notifications</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ExtendedProperties" xml:space="preserve">
<value>Extended Properties</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_FileGroups" xml:space="preserve">
<value>Filegroups</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ForeignKeys" xml:space="preserve">
<value>Foreign Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_FullTextCatalogs" xml:space="preserve">
<value>Full-Text Catalogs</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_FullTextIndexes" xml:space="preserve">
<value>Full-Text Indexes</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Functions" xml:space="preserve">
<value>Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Indexes" xml:space="preserve">
<value>Indexes</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_InlineFunctions" xml:space="preserve">
<value>Inline Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Keys" xml:space="preserve">
<value>Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_LinkedServers" xml:space="preserve">
<value>Linked Servers</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Logins" xml:space="preserve">
<value>Logins</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_MasterKey" xml:space="preserve">
<value>Master Key</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_MasterKeys" xml:space="preserve">
<value>Master Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_MessageTypes" xml:space="preserve">
<value>Message Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_MultiSelectFunctions" xml:space="preserve">
<value>Table-Valued Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Parameters" xml:space="preserve">
<value>Parameters</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_PartitionFunctions" xml:space="preserve">
<value>Partition Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_PartitionSchemes" xml:space="preserve">
<value>Partition Schemes</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Permissions" xml:space="preserve">
<value>Permissions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_PrimaryKeys" xml:space="preserve">
<value>Primary Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Programmability" xml:space="preserve">
<value>Programmability</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Queues" xml:space="preserve">
<value>Queues</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_RemoteServiceBindings" xml:space="preserve">
<value>Remote Service Bindings</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ReturnedColumns" xml:space="preserve">
<value>Returned Columns</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Roles" xml:space="preserve">
<value>Roles</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Routes" xml:space="preserve">
<value>Routes</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Rules" xml:space="preserve">
<value>Rules</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Schemas" xml:space="preserve">
<value>Schemas</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_BuiltInSchema" xml:space="preserve">
<value>Built-in Schemas</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Security" xml:space="preserve">
<value>Security</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerObjects" xml:space="preserve">
<value>Server Objects</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Management" xml:space="preserve">
<value>Management</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerTriggers" xml:space="preserve">
<value>Triggers</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServiceBroker" xml:space="preserve">
<value>Service Broker</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Services" xml:space="preserve">
<value>Services</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Signatures" xml:space="preserve">
<value>Signatures</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_LogFiles" xml:space="preserve">
<value>Log Files</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Statistics" xml:space="preserve">
<value>Statistics</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Storage" xml:space="preserve">
<value>Storage</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_StoredProcedures" xml:space="preserve">
<value>Stored Procedures</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SymmetricKeys" xml:space="preserve">
<value>Symmetric Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Synonyms" xml:space="preserve">
<value>Synonyms</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Tables" xml:space="preserve">
<value>Tables</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Triggers" xml:space="preserve">
<value>Triggers</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Types" xml:space="preserve">
<value>Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_UniqueKeys" xml:space="preserve">
<value>Unique Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_UserDefinedDataTypes" xml:space="preserve">
<value>User-Defined Data Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_UserDefinedTypes" xml:space="preserve">
<value>User-Defined Types (CLR)</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Users" xml:space="preserve">
<value>Users</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Views" xml:space="preserve">
<value>Views</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_XmlIndexes" xml:space="preserve">
<value>XML Indexes</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_XMLSchemaCollections" xml:space="preserve">
<value>XML Schema Collections</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_UserDefinedTableTypes" xml:space="preserve">
<value>User-Defined Table Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_FilegroupFiles" xml:space="preserve">
<value>Files</value>
<comment></comment>
</data>
<data name="MissingCaption" xml:space="preserve">
<value>Missing Caption</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_BrokerPriorities" xml:space="preserve">
<value>Broker Priorities</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_CryptographicProviders" xml:space="preserve">
<value>Cryptographic Providers</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DatabaseAuditSpecifications" xml:space="preserve">
<value>Database Audit Specifications</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DatabaseEncryptionKeys" xml:space="preserve">
<value>Database Encryption Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_EventSessions" xml:space="preserve">
<value>Event Sessions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_FullTextStopLists" xml:space="preserve">
<value>Full Text Stoplists</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ResourcePools" xml:space="preserve">
<value>Resource Pools</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerAudits" xml:space="preserve">
<value>Audits</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerAuditSpecifications" xml:space="preserve">
<value>Server Audit Specifications</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SpatialIndexes" xml:space="preserve">
<value>Spatial Indexes</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_WorkloadGroups" xml:space="preserve">
<value>Workload Groups</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SqlFiles" xml:space="preserve">
<value>SQL Files</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerFunctions" xml:space="preserve">
<value>Server Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SqlType" xml:space="preserve">
<value>SQL Type</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerOptions" xml:space="preserve">
<value>Server Options</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DatabaseDiagrams" xml:space="preserve">
<value>Database Diagrams</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemTables" xml:space="preserve">
<value>System Tables</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Databases" xml:space="preserve">
<value>Databases</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemContracts" xml:space="preserve">
<value>System Contracts</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemDatabases" xml:space="preserve">
<value>System Databases</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemMessageTypes" xml:space="preserve">
<value>System Message Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemQueues" xml:space="preserve">
<value>System Queues</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemServices" xml:space="preserve">
<value>System Services</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemStoredProcedures" xml:space="preserve">
<value>System Stored Procedures</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemViews" xml:space="preserve">
<value>System Views</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DataTierApplications" xml:space="preserve">
<value>Data-tier Applications</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ExtendedStoredProcedures" xml:space="preserve">
<value>Extended Stored Procedures</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemAggregateFunctions" xml:space="preserve">
<value>Aggregate Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemApproximateNumerics" xml:space="preserve">
<value>Approximate Numerics</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemBinaryStrings" xml:space="preserve">
<value>Binary Strings</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemCharacterStrings" xml:space="preserve">
<value>Character Strings</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemCLRDataTypes" xml:space="preserve">
<value>CLR Data Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemConfigurationFunctions" xml:space="preserve">
<value>Configuration Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemCursorFunctions" xml:space="preserve">
<value>Cursor Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemDataTypes" xml:space="preserve">
<value>System Data Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemDateAndTime" xml:space="preserve">
<value>Date and Time</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemDateAndTimeFunctions" xml:space="preserve">
<value>Date and Time Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemExactNumerics" xml:space="preserve">
<value>Exact Numerics</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemFunctions" xml:space="preserve">
<value>System Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemHierarchyIdFunctions" xml:space="preserve">
<value>Hierarchy Id Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemMathematicalFunctions" xml:space="preserve">
<value>Mathematical Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemMetadataFunctions" xml:space="preserve">
<value>Metadata Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemOtherDataTypes" xml:space="preserve">
<value>Other Data Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemOtherFunctions" xml:space="preserve">
<value>Other Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemRowsetFunctions" xml:space="preserve">
<value>Rowset Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemSecurityFunctions" xml:space="preserve">
<value>Security Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemSpatialDataTypes" xml:space="preserve">
<value>Spatial Data Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemStringFunctions" xml:space="preserve">
<value>String Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemSystemStatisticalFunctions" xml:space="preserve">
<value>System Statistical Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemTextAndImageFunctions" xml:space="preserve">
<value>Text and Image Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemUnicodeCharacterStrings" xml:space="preserve">
<value>Unicode Character Strings</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_AggregateFunctions" xml:space="preserve">
<value>Aggregate Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ScalarValuedFunctions" xml:space="preserve">
<value>Scalar-valued Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_TableValuedFunctions" xml:space="preserve">
<value>Table-valued Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemExtendedStoredProcedures" xml:space="preserve">
<value>System Extended Stored Procedures</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_BuiltInType" xml:space="preserve">
<value>Built-in Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_BuiltInServerRole" xml:space="preserve">
<value>Built-in Server Roles</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_UserWithPassword" xml:space="preserve">
<value>User with Password</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SearchPropertyList" xml:space="preserve">
<value>Search Property List</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SecurityPolicies" xml:space="preserve">
<value>Security Policies</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SecurityPredicates" xml:space="preserve">
<value>Security Predicates</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerRole" xml:space="preserve">
<value>Server Role</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SearchPropertyLists" xml:space="preserve">
<value>Search Property Lists</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ColumnStoreIndexes" xml:space="preserve">
<value>Column Store Indexes</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_TableTypeIndexes" xml:space="preserve">
<value>Table Type Indexes</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Server" xml:space="preserve">
<value>Server</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SelectiveXmlIndexes" xml:space="preserve">
<value>Selective XML Indexes</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_XmlNamespaces" xml:space="preserve">
<value>XML Namespaces</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_XmlTypedPromotedPaths" xml:space="preserve">
<value>XML Typed Promoted Paths</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SqlTypedPromotedPaths" xml:space="preserve">
<value>T-SQL Typed Promoted Paths</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DatabaseScopedCredentials" xml:space="preserve">
<value>Database Scoped Credentials</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ExternalDataSources" xml:space="preserve">
<value>External Data Sources</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ExternalFileFormats" xml:space="preserve">
<value>External File Formats</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ExternalResources" xml:space="preserve">
<value>External Resources</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ExternalTables" xml:space="preserve">
<value>External Tables</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DroppedLedgerColumns" xml:space="preserve">
<value>Dropped Ledger Columns</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DroppedLedgerTables" xml:space="preserve">
<value>Dropped Ledger Tables</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DroppedLedgerViews" xml:space="preserve">
<value>Dropped Ledger Views</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_AlwaysEncryptedKeys" xml:space="preserve">
<value>Always Encrypted Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ColumnMasterKeys" xml:space="preserve">
<value>Column Master Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ColumnEncryptionKeys" xml:space="preserve">
<value>Column Encryption Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SubroutineParameterLabelFormatString" xml:space="preserve">
<value>{0} ({1}, {2}, {3})</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SubroutineParameterNoDefaultLabel" xml:space="preserve">
<value>No default</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SubroutineParameterInputLabel" xml:space="preserve">
<value>Input</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SubroutineParameterInputOutputLabel" xml:space="preserve">
<value>Input/Output</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SubroutineParameterInputReadOnlyLabel" xml:space="preserve">
<value>Input/ReadOnly</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SubroutineParameterInputOutputReadOnlyLabel" xml:space="preserve">
<value>Input/Output/ReadOnly</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SubroutineParameterDefaultLabel" xml:space="preserve">
<value>Default</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_NullColumn_Label" xml:space="preserve">
<value>null</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_NotNullColumn_Label" xml:space="preserve">
<value>not null</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_UDDTLabelWithType" xml:space="preserve">
<value>{0} ({1}, {2})</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_UDDTLabelWithoutType" xml:space="preserve">
<value>{0} ({1})</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ComputedColumnLabelWithType" xml:space="preserve">
<value>{0} ({1}Computed, {2}, {3})</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ComputedColumnLabelWithoutType" xml:space="preserve">
<value>{0} ({1}Computed)</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ColumnSetLabelWithoutType" xml:space="preserve">
<value>{0} (Column Set, {1})</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ColumnSetLabelWithType" xml:space="preserve">
<value>{0} (Column Set, {1}{2}, {3})</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ColumnSetLabelWithTypeAndKeyString" xml:space="preserve">
<value>{0} (Column Set, {1}, {2}, {3})</value>
<comment></comment>
</data>
<data name="UniqueIndex_LabelPart" xml:space="preserve">
<value>Unique</value>
<comment></comment>
</data>
<data name="NonUniqueIndex_LabelPart" xml:space="preserve">
<value>Non-Unique</value>
<comment></comment>
</data>
<data name="ClusteredIndex_LabelPart" xml:space="preserve">
<value>Clustered</value>
<comment></comment>
</data>
<data name="NonClusteredIndex_LabelPart" xml:space="preserve">
<value>Non-Clustered</value>
<comment></comment>
</data>
<data name="History_LabelPart" xml:space="preserve">
<value>History</value>
<comment></comment>
</data>
<data name="SystemVersioned_LabelPart" xml:space="preserve">
<value>System-Versioned</value>
<comment></comment>
</data>
<data name="UpdatableLedger_LabelPart" xml:space="preserve">
<value>Updatable Ledger</value>
<comment></comment>
</data>
<data name="AppendOnlyLedger_LabelPart" xml:space="preserve">
<value>Append-Only Ledger</value>
<comment></comment>
</data>
<data name="Ledger_LabelPart" xml:space="preserve">
<value>Ledger</value>
<comment></comment>
</data>
<data name="External_LabelPart" xml:space="preserve">
<value>External</value>
<comment></comment>
</data>
<data name="FileTable_LabelPart" xml:space="preserve">
<value>File Table</value>
<comment></comment>
</data>
<data name="DatabaseNotAccessible" xml:space="preserve">
<value>The database {0} is not accessible.</value>
<comment></comment>
</data>
<data name="FilterName" xml:space="preserve">
<value>Name</value>
<comment></comment>
</data>
<data name="FilterNameDescription" xml:space="preserve">
<value>Include or exclude objects based on the name or part of a name.</value>
<comment></comment>
</data>
<data name="FilterSchema" xml:space="preserve">
<value>Schema</value>
<comment></comment>
</data>
<data name="FilterSchemaDescription" xml:space="preserve">
<value> Include or exclude objects based on the schema or part of a schema name.</value>
<comment></comment>
</data>
<data name="FilterOwner" xml:space="preserve">
<value>Owner</value>
<comment></comment>
</data>
<data name="FilterOwnerDescription" xml:space="preserve">
<value>Include or exclude objects based on the owner or part of an owner name.</value>
<comment></comment>
</data>
<data name="FilterDurabilityType" xml:space="preserve">
<value>Durability Type</value>
<comment></comment>
</data>
<data name="FilterDurabilityTypeDescription" xml:space="preserve">
<value>Include or exclude objects based on the durability type.</value>
<comment></comment>
</data>
<data name="FilterDurabilitySchemaOnly" xml:space="preserve">
<value>Schema Only</value>
<comment></comment>
</data>
<data name="FilterDurabilitySchemaAndData" xml:space="preserve">
<value>Schema and Data</value>
<comment></comment>
</data>
<data name="FilterIsMemoryOptimized" xml:space="preserve">
<value>Is Memory Optimized</value>
<comment></comment>
</data>
<data name="FilterIsMemoryOptimizedDescription" xml:space="preserve">
<value>Include or exclude objects based on whether the object is memory optimized.</value>
<comment></comment>
</data>
<data name="FilterCreateDate" xml:space="preserve">
<value>Create Date</value>
<comment></comment>
</data>
<data name="FilterCreateDateDescription" xml:space="preserve">
<value>Include or exclude objects based on their creation date.</value>
<comment></comment>
</data>
<data name="FilterIsNativelyCompiled" xml:space="preserve">
<value>Is Natively Compiled</value>
<comment></comment>
</data>
<data name="FilterIsNativelyCompiledDescription" xml:space="preserve">
<value>Include or exclude objects based on whether the object is natively compiled.</value>
<comment></comment>
</data>
<data name="FilterInPrimaryKey" xml:space="preserve">
<value>In Primary Key</value>
<comment></comment>
</data>
<data name="FilterInPrimaryKeyDescription" xml:space="preserve">
<value>Include or exclude objects based on whether the column is in a primary key.</value>
<comment></comment>
</data>
<data name="ScriptingParams_ConnectionString_Property_Invalid" xml:space="preserve">
<value>Error parsing ScriptingParams.ConnectionString property.</value>
<comment></comment>

View File

@@ -327,416 +327,6 @@ SqlScriptFormatterLengthTypeMissingSize = Column with length is missing size
SqlScriptFormatterScalarTypeMissingScale = Scalar column missing scale
############################################################################
# Object Explorer Service
TreeNodeError = Error expanding: {0}
ServerNodeConnectionError = Error connecting to {0}
SchemaHierarchy_Aggregates = Aggregates
SchemaHierarchy_ServerRoles = Server Roles
SchemaHierarchy_ApplicationRoles = Application Roles
SchemaHierarchy_Assemblies = Assemblies
SchemaHierarchy_AssemblyFiles = Assembly Files
SchemaHierarchy_AsymmetricKeys = Asymmetric Keys
SchemaHierarchy_DatabaseAsymmetricKeys = Asymmetric Keys
SchemaHierarchy_DataCompressionOptions = Data Compression Options
SchemaHierarchy_Certificates = Certificates
SchemaHierarchy_FileTables = FileTables
SchemaHierarchy_DatabaseCertificates = Certificates
SchemaHierarchy_CheckConstraints = Check Constraints
SchemaHierarchy_Columns = Columns
SchemaHierarchy_Constraints = Constraints
SchemaHierarchy_Contracts = Contracts
SchemaHierarchy_Credentials = Credentials
SchemaHierarchy_ErrorMessages = Error Messages
SchemaHierarchy_ServerRoleMembership = Server Role Membership
SchemaHierarchy_DatabaseOptions = Database Options
SchemaHierarchy_DatabaseRoles = Database Roles
SchemaHierarchy_RoleMemberships = Role Memberships
SchemaHierarchy_DatabaseTriggers = Database Triggers
SchemaHierarchy_DefaultConstraints = Default Constraints
SchemaHierarchy_Defaults = Defaults
SchemaHierarchy_Sequences = Sequences
SchemaHierarchy_Endpoints = Endpoints
SchemaHierarchy_EventNotifications = Event Notifications
SchemaHierarchy_ServerEventNotifications = Server Event Notifications
SchemaHierarchy_ExtendedProperties = Extended Properties
SchemaHierarchy_FileGroups = Filegroups
SchemaHierarchy_ForeignKeys = Foreign Keys
SchemaHierarchy_FullTextCatalogs = Full-Text Catalogs
SchemaHierarchy_FullTextIndexes = Full-Text Indexes
SchemaHierarchy_Functions = Functions
SchemaHierarchy_Indexes = Indexes
SchemaHierarchy_InlineFunctions = Inline Functions
SchemaHierarchy_Keys = Keys
SchemaHierarchy_LinkedServers = Linked Servers
SchemaHierarchy_Logins = Logins
SchemaHierarchy_MasterKey = Master Key
SchemaHierarchy_MasterKeys = Master Keys
SchemaHierarchy_MessageTypes = Message Types
SchemaHierarchy_MultiSelectFunctions = Table-Valued Functions
SchemaHierarchy_Parameters = Parameters
SchemaHierarchy_PartitionFunctions = Partition Functions
SchemaHierarchy_PartitionSchemes = Partition Schemes
SchemaHierarchy_Permissions = Permissions
SchemaHierarchy_PrimaryKeys = Primary Keys
SchemaHierarchy_Programmability = Programmability
SchemaHierarchy_Queues = Queues
SchemaHierarchy_RemoteServiceBindings = Remote Service Bindings
SchemaHierarchy_ReturnedColumns = Returned Columns
SchemaHierarchy_Roles = Roles
SchemaHierarchy_Routes = Routes
SchemaHierarchy_Rules = Rules
SchemaHierarchy_Schemas = Schemas
SchemaHierarchy_BuiltInSchema = Built-in Schemas
SchemaHierarchy_Security = Security
SchemaHierarchy_ServerObjects = Server Objects
SchemaHierarchy_Management = Management
SchemaHierarchy_ServerTriggers = Triggers
SchemaHierarchy_ServiceBroker = Service Broker
SchemaHierarchy_Services = Services
SchemaHierarchy_Signatures = Signatures
SchemaHierarchy_LogFiles = Log Files
SchemaHierarchy_Statistics = Statistics
SchemaHierarchy_Storage = Storage
SchemaHierarchy_StoredProcedures = Stored Procedures
SchemaHierarchy_SymmetricKeys = Symmetric Keys
SchemaHierarchy_Synonyms = Synonyms
SchemaHierarchy_Tables = Tables
SchemaHierarchy_Triggers = Triggers
SchemaHierarchy_Types = Types
SchemaHierarchy_UniqueKeys = Unique Keys
SchemaHierarchy_UserDefinedDataTypes = User-Defined Data Types
SchemaHierarchy_UserDefinedTypes = User-Defined Types (CLR)
SchemaHierarchy_Users = Users
SchemaHierarchy_Views = Views
SchemaHierarchy_XmlIndexes = XML Indexes
SchemaHierarchy_XMLSchemaCollections = XML Schema Collections
SchemaHierarchy_UserDefinedTableTypes = User-Defined Table Types
SchemaHierarchy_FilegroupFiles = Files
MissingCaption = Missing Caption
SchemaHierarchy_BrokerPriorities = Broker Priorities
SchemaHierarchy_CryptographicProviders = Cryptographic Providers
SchemaHierarchy_DatabaseAuditSpecifications = Database Audit Specifications
SchemaHierarchy_DatabaseEncryptionKeys = Database Encryption Keys
SchemaHierarchy_EventSessions = Event Sessions
SchemaHierarchy_FullTextStopLists = Full Text Stoplists
SchemaHierarchy_ResourcePools = Resource Pools
SchemaHierarchy_ServerAudits = Audits
SchemaHierarchy_ServerAuditSpecifications = Server Audit Specifications
SchemaHierarchy_SpatialIndexes = Spatial Indexes
SchemaHierarchy_WorkloadGroups = Workload Groups
SchemaHierarchy_SqlFiles = SQL Files
SchemaHierarchy_ServerFunctions = Server Functions
SchemaHierarchy_SqlType = SQL Type
SchemaHierarchy_ServerOptions = Server Options
SchemaHierarchy_DatabaseDiagrams = Database Diagrams
SchemaHierarchy_SystemTables = System Tables
SchemaHierarchy_Databases = Databases
SchemaHierarchy_SystemContracts = System Contracts
SchemaHierarchy_SystemDatabases = System Databases
SchemaHierarchy_SystemMessageTypes = System Message Types
SchemaHierarchy_SystemQueues = System Queues
SchemaHierarchy_SystemServices = System Services
SchemaHierarchy_SystemStoredProcedures = System Stored Procedures
SchemaHierarchy_SystemViews = System Views
SchemaHierarchy_DataTierApplications = Data-tier Applications
SchemaHierarchy_ExtendedStoredProcedures = Extended Stored Procedures
SchemaHierarchy_SystemAggregateFunctions = Aggregate Functions
SchemaHierarchy_SystemApproximateNumerics = Approximate Numerics
SchemaHierarchy_SystemBinaryStrings = Binary Strings
SchemaHierarchy_SystemCharacterStrings = Character Strings
SchemaHierarchy_SystemCLRDataTypes = CLR Data Types
SchemaHierarchy_SystemConfigurationFunctions = Configuration Functions
SchemaHierarchy_SystemCursorFunctions = Cursor Functions
SchemaHierarchy_SystemDataTypes = System Data Types
SchemaHierarchy_SystemDateAndTime = Date and Time
SchemaHierarchy_SystemDateAndTimeFunctions = Date and Time Functions
SchemaHierarchy_SystemExactNumerics = Exact Numerics
SchemaHierarchy_SystemFunctions = System Functions
SchemaHierarchy_SystemHierarchyIdFunctions = Hierarchy Id Functions
SchemaHierarchy_SystemMathematicalFunctions = Mathematical Functions
SchemaHierarchy_SystemMetadataFunctions = Metadata Functions
SchemaHierarchy_SystemOtherDataTypes = Other Data Types
SchemaHierarchy_SystemOtherFunctions = Other Functions
SchemaHierarchy_SystemRowsetFunctions = Rowset Functions
SchemaHierarchy_SystemSecurityFunctions = Security Functions
SchemaHierarchy_SystemSpatialDataTypes = Spatial Data Types
SchemaHierarchy_SystemStringFunctions = String Functions
SchemaHierarchy_SystemSystemStatisticalFunctions = System Statistical Functions
SchemaHierarchy_SystemTextAndImageFunctions = Text and Image Functions
SchemaHierarchy_SystemUnicodeCharacterStrings = Unicode Character Strings
SchemaHierarchy_AggregateFunctions = Aggregate Functions
SchemaHierarchy_ScalarValuedFunctions = Scalar-valued Functions
SchemaHierarchy_TableValuedFunctions = Table-valued Functions
SchemaHierarchy_SystemExtendedStoredProcedures = System Extended Stored Procedures
SchemaHierarchy_BuiltInType = Built-in Types
SchemaHierarchy_BuiltInServerRole = Built-in Server Roles
SchemaHierarchy_UserWithPassword = User with Password
SchemaHierarchy_SearchPropertyList = Search Property List
SchemaHierarchy_SecurityPolicies = Security Policies
SchemaHierarchy_SecurityPredicates = Security Predicates
SchemaHierarchy_ServerRole = Server Role
SchemaHierarchy_SearchPropertyLists = Search Property Lists
SchemaHierarchy_ColumnStoreIndexes = Column Store Indexes
SchemaHierarchy_TableTypeIndexes = Table Type Indexes
SchemaHierarchy_Server = Server
SchemaHierarchy_SelectiveXmlIndexes = Selective XML Indexes
SchemaHierarchy_XmlNamespaces = XML Namespaces
SchemaHierarchy_XmlTypedPromotedPaths = XML Typed Promoted Paths
SchemaHierarchy_SqlTypedPromotedPaths = T-SQL Typed Promoted Paths
SchemaHierarchy_DatabaseScopedCredentials = Database Scoped Credentials
SchemaHierarchy_ExternalDataSources = External Data Sources
SchemaHierarchy_ExternalFileFormats = External File Formats
SchemaHierarchy_ExternalResources = External Resources
SchemaHierarchy_ExternalTables = External Tables
SchemaHierarchy_DroppedLedgerColumns = Dropped Ledger Columns
SchemaHierarchy_DroppedLedgerTables = Dropped Ledger Tables
SchemaHierarchy_DroppedLedgerViews = Dropped Ledger Views
SchemaHierarchy_AlwaysEncryptedKeys = Always Encrypted Keys
SchemaHierarchy_ColumnMasterKeys = Column Master Keys
SchemaHierarchy_ColumnEncryptionKeys = Column Encryption Keys
SchemaHierarchy_SubroutineParameterLabelFormatString = {0} ({1}, {2}, {3})
SchemaHierarchy_SubroutineParameterNoDefaultLabel = No default
SchemaHierarchy_SubroutineParameterInputLabel = Input
SchemaHierarchy_SubroutineParameterInputOutputLabel = Input/Output
SchemaHierarchy_SubroutineParameterInputReadOnlyLabel = Input/ReadOnly
SchemaHierarchy_SubroutineParameterInputOutputReadOnlyLabel = Input/Output/ReadOnly
SchemaHierarchy_SubroutineParameterDefaultLabel = Default
SchemaHierarchy_NullColumn_Label = null
SchemaHierarchy_NotNullColumn_Label = not null
SchemaHierarchy_UDDTLabelWithType = {0} ({1}, {2})
SchemaHierarchy_UDDTLabelWithoutType = {0} ({1})
SchemaHierarchy_ComputedColumnLabelWithType = {0} ({1}Computed, {2}, {3})
SchemaHierarchy_ComputedColumnLabelWithoutType = {0} ({1}Computed)
SchemaHierarchy_ColumnSetLabelWithoutType = {0} (Column Set, {1})
SchemaHierarchy_ColumnSetLabelWithType = {0} (Column Set, {1}{2}, {3})
SchemaHierarchy_ColumnSetLabelWithTypeAndKeyString = {0} (Column Set, {1}, {2}, {3})
UniqueIndex_LabelPart = Unique
NonUniqueIndex_LabelPart = Non-Unique
ClusteredIndex_LabelPart = Clustered
NonClusteredIndex_LabelPart = Non-Clustered
History_LabelPart = History
SystemVersioned_LabelPart = System-Versioned
UpdatableLedger_LabelPart = Updatable Ledger
AppendOnlyLedger_LabelPart = Append-Only Ledger
Ledger_LabelPart = Ledger
External_LabelPart = External
FileTable_LabelPart = File Table
DatabaseNotAccessible = The database {0} is not accessible.
FilterName = Name
FilterNameDescription = Include or exclude objects based on the name or part of a name.
FilterSchema = Schema
FilterSchemaDescription = Include or exclude objects based on the schema or part of a schema name.
FilterOwner = Owner
FilterOwnerDescription = Include or exclude objects based on the owner or part of an owner name.
FilterDurabilityType = Durability Type
FilterDurabilityTypeDescription = Include or exclude objects based on the durability type.
FilterDurabilitySchemaOnly = Schema Only
FilterDurabilitySchemaAndData = Schema and Data
FilterIsMemoryOptimized = Is Memory Optimized
FilterIsMemoryOptimizedDescription = Include or exclude objects based on whether the object is memory optimized.
FilterCreateDate = Create Date
FilterCreateDateDescription = Include or exclude objects based on their creation date.
FilterIsNativelyCompiled = Is Natively Compiled
FilterIsNativelyCompiledDescription = Include or exclude objects based on whether the object is natively compiled.
FilterInPrimaryKey = In Primary Key
FilterInPrimaryKeyDescription = Include or exclude objects based on whether the column is in a primary key.
############################################################################
# Scripting Service

File diff suppressed because it is too large Load Diff

View File

@@ -8,9 +8,9 @@
using System;
using Microsoft.Data.SqlClient;
using System.Globalization;
using System.Text;
using Microsoft.SqlServer.Management.Common;
using SMO = Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.SqlCore.Utility;
namespace Microsoft.SqlTools.ServiceLayer.Management
{
@@ -173,7 +173,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Management
{
string query = string.Format(CultureInfo.InvariantCulture,
"select top 1 1 from [{0}].sys.filegroups where type = 'FX'",
CUtils.EscapeString(dbName, ']'));
StringUtils.EscapeString(dbName, ']'));
if (server.ConnectionContext.ExecuteScalar(query) != null)
{
hasMemoryOptimizedFileGroup = true;
@@ -552,101 +552,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Management
return sqlerror.Number;
}
/// <summary>
/// Function doubles up specified character in a string
/// </summary>
/// <param name="s"></param>
/// <param name="cEsc"></param>
/// <returns></returns>
public static String EscapeString(string s, char cEsc)
{
if (string.IsNullOrWhiteSpace(s))
{
return s;
}
StringBuilder sb = new StringBuilder(s.Length * 2);
foreach (char c in s)
{
sb.Append(c);
if (cEsc == c)
sb.Append(c);
}
return sb.ToString();
}
/// <summary>
/// Function doubles up ']' character in a string
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static String EscapeStringCBracket(string s)
{
return CUtils.EscapeString(s, ']');
}
/// <summary>
/// Function doubles up '\'' character in a string
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static String EscapeStringSQuote(string s)
{
return CUtils.EscapeString(s, '\'');
}
/// <summary>
/// Function removes doubled up specified character from a string
/// </summary>
/// <param name="s"></param>
/// <param name="cEsc"></param>
/// <returns></returns>
public static String UnEscapeString(string s, char cEsc)
{
StringBuilder sb = new StringBuilder(s.Length);
bool foundBefore = false;
foreach (char c in s)
{
if (cEsc == c) // character to unescape
{
if (foundBefore) // skip second occurrence
{
foundBefore = false;
}
else // set the flag to skip next time around
{
sb.Append(c);
foundBefore = true;
}
}
else
{
sb.Append(c);
foundBefore = false;
}
}
return sb.ToString();
}
/// <summary>
/// Function removes doubled up ']' character from a string
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static String UnEscapeStringCBracket(string s)
{
return CUtils.UnEscapeString(s, ']');
}
/// <summary>
/// Function removes doubled up '\'' character from a string
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static String UnEscapeStringSQuote(string s)
{
return CUtils.UnEscapeString(s, '\'');
}
/// <summary>
/// Get the windows login name with the domain portion in all-caps

View File

@@ -6,6 +6,7 @@
#nullable disable
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
using Microsoft.SqlTools.SqlCore.Metadata;
namespace Microsoft.SqlTools.ServiceLayer.Metadata.Contracts
{

View File

@@ -14,6 +14,7 @@ using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Hosting;
using Microsoft.SqlTools.ServiceLayer.Metadata.Contracts;
using Microsoft.SqlTools.ServiceLayer.Utility;
using Microsoft.SqlTools.SqlCore.Metadata;
namespace Microsoft.SqlTools.ServiceLayer.Metadata
{

View File

@@ -11,9 +11,9 @@ using System.Data.Common;
using Microsoft.Data.SqlClient;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection;
using Microsoft.SqlTools.ServiceLayer.Utility.SqlScriptFormatters;
using Microsoft.SqlTools.SqlCore.Connection;
namespace Microsoft.SqlTools.ServiceLayer.Metadata
{

View File

@@ -60,13 +60,13 @@
<ProjectReference Include="../Microsoft.SqlTools.Hosting/Microsoft.SqlTools.Hosting.csproj" />
<ProjectReference Include="../Microsoft.SqlTools.Credentials/Microsoft.SqlTools.Credentials.csproj" />
<ProjectReference Include="../Microsoft.SqlTools.ManagedBatchParser/Microsoft.SqlTools.ManagedBatchParser.csproj" />
<ProjectReference Include="..\Microsoft.SqlTools.Authentication\Microsoft.SqlTools.Authentication.csproj" />
<ProjectReference Include="../Microsoft.SqlTools.Authentication/Microsoft.SqlTools.Authentication.csproj" />
<ProjectReference Include="../Microsoft.SqlTools.SqlCore/Microsoft.SqlTools.SqlCore.csproj" />
</ItemGroup>
<ItemGroup>
<Content Include="..\..\Notice.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<EmbeddedResource Include="ObjectExplorer\SmoModel\SmoTreeNodesDefinition.xml" />
<EmbeddedResource Include="Localization\*.resx" />
<None Include="Localization\sr.strings" />
</ItemGroup>

View File

@@ -5,9 +5,8 @@
#nullable disable
using Microsoft.SqlTools.ServiceLayer.Management;
using Microsoft.SqlTools.ServiceLayer.ModelManagement.Contracts;
using Microsoft.SqlTools.ServiceLayer.Utility;
using Microsoft.SqlTools.SqlCore.Utility;
using System;
using System.Collections.Generic;
using System.Data;
@@ -253,12 +252,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ModelManagement
private static string GetThreePartsTableName(string dbName, string tableName, string schemaName)
{
return $"[{CUtils.EscapeStringCBracket(dbName)}].[{CUtils.EscapeStringCBracket(schemaName)}].[{CUtils.EscapeStringCBracket(tableName)}]";
return $"[{StringUtils.EscapeStringCBracket(dbName)}].[{StringUtils.EscapeStringCBracket(schemaName)}].[{StringUtils.EscapeStringCBracket(tableName)}]";
}
private static string GetTwoPartsTableName(string tableName, string schemaName)
{
return $"[{CUtils.EscapeStringCBracket(schemaName)}].[{CUtils.EscapeStringCBracket(tableName)}]";
return $"[{StringUtils.EscapeStringCBracket(schemaName)}].[{StringUtils.EscapeStringCBracket(tableName)}]";
}
private static string GetSelectModelsQuery(string dbName, string tableName, string schemaName)
@@ -272,24 +271,24 @@ namespace Microsoft.SqlTools.ServiceLayer.ModelManagement
private static string GetConfigTableVerificationQuery(string dbName, string tableName, string schemaName)
{
string twoPartsTableName = GetTwoPartsTableName(CUtils.EscapeStringSQuote(tableName), CUtils.EscapeStringSQuote(schemaName));
string twoPartsTableName = GetTwoPartsTableName(StringUtils.EscapeStringSQuote(tableName), StringUtils.EscapeStringSQuote(schemaName));
return $@"
IF NOT EXISTS (
SELECT name
FROM sys.databases
WHERE name = N'{CUtils.EscapeStringSQuote(dbName)}'
WHERE name = N'{StringUtils.EscapeStringSQuote(dbName)}'
)
BEGIN
SELECT 0
END
ELSE
BEGIN
USE [{CUtils.EscapeStringCBracket(dbName)}]
USE [{StringUtils.EscapeStringCBracket(dbName)}]
IF EXISTS
( SELECT t.name, s.name
FROM sys.tables t join sys.schemas s on t.schema_id=t.schema_id
WHERE t.name = '{CUtils.EscapeStringSQuote(tableName)}'
AND s.name = '{CUtils.EscapeStringSQuote(schemaName)}'
WHERE t.name = '{StringUtils.EscapeStringSQuote(tableName)}'
AND s.name = '{StringUtils.EscapeStringSQuote(schemaName)}'
)
BEGIN
IF EXISTS (SELECT * FROM syscolumns WHERE ID=OBJECT_ID('{twoPartsTableName}') AND NAME='model_name')
@@ -323,8 +322,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ModelManagement
IF NOT EXISTS
( SELECT t.name, s.name
FROM sys.tables t join sys.schemas s on t.schema_id=t.schema_id
WHERE t.name = '{CUtils.EscapeStringSQuote(tableName)}'
AND s.name = '{CUtils.EscapeStringSQuote(schemaName)}'
WHERE t.name = '{StringUtils.EscapeStringSQuote(tableName)}'
AND s.name = '{StringUtils.EscapeStringSQuote(schemaName)}'
)
BEGIN
CREATE TABLE {GetTwoPartsTableName(tableName, schemaName)} (
@@ -339,12 +338,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ModelManagement
[deployed_by] [int] NULL,
[model_description] [varchar](256) NULL,
[run_id] [varchar](256) NULL,
CONSTRAINT [{CUtils.EscapeStringCBracket(tableName)}_models_pk] PRIMARY KEY CLUSTERED
CONSTRAINT [{StringUtils.EscapeStringCBracket(tableName)}_models_pk] PRIMARY KEY CLUSTERED
(
[model_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
ALTER TABLE {GetTwoPartsTableName(tableName, schemaName)} ADD CONSTRAINT [{CUtils.EscapeStringCBracket(tableName)}_deployment_time] DEFAULT (getdate()) FOR [model_deployment_time]
ALTER TABLE {GetTwoPartsTableName(tableName, schemaName)} ADD CONSTRAINT [{StringUtils.EscapeStringCBracket(tableName)}_deployment_time] DEFAULT (getdate()) FOR [model_deployment_time]
END
";
}
@@ -357,14 +356,14 @@ namespace Microsoft.SqlTools.ServiceLayer.ModelManagement
INSERT INTO {twoPartsTableName}
(model_name, model, model_version, model_description, model_creation_time, model_framework, model_framework_version, run_id, deployed_by)
VALUES (
{DatabaseUtils.AddStringParameterForInsert(model.ModelName ?? "")},
{DatabaseUtils.AddByteArrayParameterForInsert("Content", model.FilePath ?? "", parameters)},
{DatabaseUtils.AddStringParameterForInsert(model.Version ?? "")},
{DatabaseUtils.AddStringParameterForInsert(model.Description ?? "")},
{DatabaseUtils.AddStringParameterForInsert(model.Created)},
{DatabaseUtils.AddStringParameterForInsert(model.Framework ?? "")},
{DatabaseUtils.AddStringParameterForInsert(model.FrameworkVersion ?? "")},
{DatabaseUtils.AddStringParameterForInsert(model.RunId ?? "")},
{Utility.DatabaseUtils.AddStringParameterForInsert(model.ModelName ?? "")},
{Utility.DatabaseUtils.AddByteArrayParameterForInsert("Content", model.FilePath ?? "", parameters)},
{Utility.DatabaseUtils.AddStringParameterForInsert(model.Version ?? "")},
{Utility.DatabaseUtils.AddStringParameterForInsert(model.Description ?? "")},
{Utility.DatabaseUtils.AddStringParameterForInsert(model.Created)},
{Utility.DatabaseUtils.AddStringParameterForInsert(model.Framework ?? "")},
{Utility.DatabaseUtils.AddStringParameterForInsert(model.FrameworkVersion ?? "")},
{Utility.DatabaseUtils.AddStringParameterForInsert(model.RunId ?? "")},
USER_ID (Current_User)
)
";
@@ -378,13 +377,13 @@ namespace Microsoft.SqlTools.ServiceLayer.ModelManagement
return $@"
UPDATE {twoPartsTableName}
SET
{DatabaseUtils.AddStringParameterForUpdate("model_name", model.ModelName ?? "")},
{DatabaseUtils.AddStringParameterForUpdate("model_version", model.Version ?? "")},
{DatabaseUtils.AddStringParameterForUpdate("model_description", model.Description ?? "")},
{DatabaseUtils.AddStringParameterForUpdate("model_creation_time", model.Created)},
{DatabaseUtils.AddStringParameterForUpdate("model_framework", model.Framework ?? "")},
{DatabaseUtils.AddStringParameterForUpdate("model_framework_version", model.FrameworkVersion ?? "")},
{DatabaseUtils.AddStringParameterForUpdate("run_id", model.RunId ?? "")}
{Utility.DatabaseUtils.AddStringParameterForUpdate("model_name", model.ModelName ?? "")},
{Utility.DatabaseUtils.AddStringParameterForUpdate("model_version", model.Version ?? "")},
{Utility.DatabaseUtils.AddStringParameterForUpdate("model_description", model.Description ?? "")},
{Utility.DatabaseUtils.AddStringParameterForUpdate("model_creation_time", model.Created)},
{Utility.DatabaseUtils.AddStringParameterForUpdate("model_framework", model.Framework ?? "")},
{Utility.DatabaseUtils.AddStringParameterForUpdate("model_framework_version", model.FrameworkVersion ?? "")},
{Utility.DatabaseUtils.AddStringParameterForUpdate("run_id", model.RunId ?? "")}
WHERE model_id = @{ModelIdParameterName}
";

View File

@@ -6,7 +6,7 @@
#nullable disable
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
using Microsoft.SqlTools.SqlCore.Connection;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts
{

View File

@@ -5,7 +5,10 @@
#nullable disable
using Microsoft.SqlTools.ServiceLayer.Metadata.Contracts;
using System;
using System.Collections.Generic;
using Microsoft.SqlTools.SqlCore.Metadata;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
using Newtonsoft.Json.Linq;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts
@@ -76,6 +79,25 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts
/// Filterable properties that this node supports
/// </summary>
public NodeFilterProperty[] FilterableProperties { get; set; }
public NodeInfo()
{
}
public NodeInfo(TreeNode treeNode)
{
IsLeaf = treeNode.IsAlwaysLeaf;
Label = treeNode.Label;
NodePath = treeNode.GetNodePath();
ParentNodePath = treeNode.Parent?.GetNodePath() ?? string.Empty;
NodeType = treeNode.NodeType;
Metadata = treeNode.ObjectMetadata;
NodeStatus = treeNode.NodeStatus;
NodeSubType = treeNode.NodeSubType;
ErrorMessage = treeNode.ErrorMessage;
ObjectType = treeNode.NodeTypeId.ToString();
FilterableProperties = treeNode.FilterProperties;
}
}
/// <summary>
@@ -103,45 +125,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts
}
}
/// <summary>
/// The filterable properties that a node supports
/// </summary>
public class NodeFilterProperty
{
/// <summary>
/// The name of the filter property
/// </summary>
public string Name { get; set; }
/// <summary>
/// The name of the filter property displayed to the user
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// The description of the filter property
/// </summary>
public string Description { get; set; }
/// <summary>
/// The data type of the filter property
/// </summary>
public NodeFilterPropertyDataType Type { get; set; }
/// <summary>
/// The list of choices for the filter property if the type is choice
/// </summary>
public NodeFilterPropertyChoice[] Choices { get; set; }
}
/// <summary>
/// The data type of the filter property. Matches NodeFilterPropertyDataType enum in ADS : https://github.com/microsoft/azuredatastudio/blob/main/src/sql/azdata.proposed.d.ts#L1847-L1853
/// </summary>
public enum NodeFilterPropertyDataType
{
String = 0,
Number = 1,
Boolean = 2,
Date = 3,
Choice = 4
}
/// <summary>
/// The operator of the filter property. Matches NodeFilterOperator enum in ADS: https://github.com/microsoft/azuredatastudio/blob/main/src/sql/azdata.proposed.d.ts#L1855-L1868
/// </summary>
@@ -182,22 +165,109 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts
/// The applied values of the filter property
/// </summary>
public JToken Value { get; set; }
}
/// <summary>
/// The choice for the filter property if the type is choice
/// </summary>
public class NodeFilterPropertyChoice
{
/// <summary>
/// The dropdown display value for the choice
/// </summary>
/// <value></value>
public string DisplayName { get; set; }
public INodeFilter ToINodeFilter(NodeFilterProperty filterProperty)
{
Type type = typeof(string);
/// <summary>
/// The value of the choice
/// </summary>
public string Value { get; set; }
var IsDateTime = filterProperty.Type == NodeFilterPropertyDataType.Date;
FilterType filterType = FilterType.EQUALS;
bool isNotFilter = false;
object filterValue = null;
switch (filterProperty.Type)
{
case NodeFilterPropertyDataType.String:
case NodeFilterPropertyDataType.Date:
case NodeFilterPropertyDataType.Choice:
type = typeof(string);
filterValue = this.Value.ToString();
break;
case NodeFilterPropertyDataType.Number:
type = typeof(int);
filterValue = this.Value.ToObject<int>();
break;
case NodeFilterPropertyDataType.Boolean:
type = typeof(bool);
filterValue = this.Value.ToObject<bool>() ? 1 : 0;
break;
}
switch (this.Operator)
{
case NodeFilterOperator.Equals:
filterType = FilterType.EQUALS;
break;
case NodeFilterOperator.NotEquals:
filterType = FilterType.EQUALS;
isNotFilter = true;
break;
case NodeFilterOperator.LessThan:
filterType = FilterType.LESSTHAN;
break;
case NodeFilterOperator.LessThanOrEquals:
filterType = FilterType.LESSTHANOREQUAL;
break;
case NodeFilterOperator.GreaterThan:
filterType = FilterType.GREATERTHAN;
break;
case NodeFilterOperator.GreaterThanOrEquals:
filterType = FilterType.GREATERTHANOREQUAL;
break;
case NodeFilterOperator.Between:
filterType = FilterType.BETWEEN;
break;
case NodeFilterOperator.NotBetween:
filterType = FilterType.NOTBETWEEN;
isNotFilter = true;
break;
case NodeFilterOperator.Contains:
filterType = FilterType.CONTAINS;
break;
case NodeFilterOperator.NotContains:
filterType = FilterType.CONTAINS;
isNotFilter = true;
break;
case NodeFilterOperator.StartsWith:
filterType = FilterType.STARTSWITH;
break;
case NodeFilterOperator.NotStartsWith:
filterType = FilterType.STARTSWITH;
isNotFilter = true;
break;
case NodeFilterOperator.EndsWith:
filterType = FilterType.ENDSWITH;
break;
case NodeFilterOperator.NotEndsWith:
filterType = FilterType.ENDSWITH;
isNotFilter = true;
break;
}
if (this.Operator == NodeFilterOperator.Between || this.Operator == NodeFilterOperator.NotBetween)
{
if (filterProperty.Type == NodeFilterPropertyDataType.Number)
{
filterValue = this.Value.ToObject<int[]>();
}
else if (filterProperty.Type == NodeFilterPropertyDataType.Date)
{
filterValue = this.Value.ToObject<string[]>();
}
}
return new NodePropertyFilter
{
Property = filterProperty.Name,
Type = type,
Values = new List<object> { filterValue },
IsNotFilter = isNotFilter,
FilterType = filterType,
IsDateTime = IsDateTime
};
}
}
}

View File

@@ -23,12 +23,14 @@ using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel;
using Microsoft.SqlTools.ServiceLayer.SqlContext;
using Microsoft.SqlTools.ServiceLayer.TableDesigner;
using Microsoft.SqlTools.ServiceLayer.Utility;
using Microsoft.SqlTools.ServiceLayer.Workspace;
using Microsoft.SqlTools.SqlCore.Connection;
using Microsoft.SqlTools.SqlCore.ObjectExplorer;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel;
using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
@@ -46,7 +48,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
private ConnectionService connectionService;
private IProtocolEndpoint serviceHost;
private ConcurrentDictionary<string, ObjectExplorerSession> sessionMap;
private readonly Lazy<Dictionary<string, HashSet<ChildFactory>>> applicableNodeChildFactories;
private IMultiServiceProvider serviceProvider;
private ConnectedBindingQueue bindingQueue = new ConnectedBindingQueue(needsMetadata: false);
private string connectionName = "ObjectExplorer";
@@ -62,7 +63,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
public ObjectExplorerService()
{
sessionMap = new ConcurrentDictionary<string, ObjectExplorerSession>();
applicableNodeChildFactories = new Lazy<Dictionary<string, HashSet<ChildFactory>>>(PopulateFactories);
NodePathGenerator.Initialize();
}
@@ -78,14 +78,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
}
}
private Dictionary<string, HashSet<ChildFactory>> ApplicableNodeChildFactories
{
get
{
return applicableNodeChildFactories.Value;
}
}
/// <summary>
/// Returns the session ids
/// </summary>
@@ -286,7 +278,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
var foundNodes = FindNodes(findNodesParams.SessionId, findNodesParams.Type, findNodesParams.Schema, findNodesParams.Name, findNodesParams.Database, findNodesParams.ParentObjectNames);
foundNodes ??= new List<TreeNode>();
await context.SendResult(new FindNodesResponse { Nodes = foundNodes.Select(node => node.ToNodeInfo()).ToList() });
await context.SendResult(new FindNodesResponse { Nodes = foundNodes.Select(node => new NodeInfo(node)).ToList() });
}
internal void CloseSession(string uri)
@@ -365,7 +357,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
response = new SessionCreatedParameters
{
Success = true,
RootNode = session.Root.ToNodeInfo(),
RootNode = new NodeInfo(session.Root),
SessionId = uri,
ErrorNumber = session.ErrorNumber,
ErrorMessage = session.ErrorMessage
@@ -444,17 +436,30 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
securityToken = null;
}
var filterDefinitions = node.FilterProperties;
var appliedFilters = new List<INodeFilter>();
if (filters != null)
{
foreach (var f in filters)
{
NodeFilterProperty filterProperty = filterDefinitions.FirstOrDefault(x => x.Name == f.Name);
appliedFilters.Add(f.ToINodeFilter(filterProperty));
}
}
if (forceRefresh)
{
Logger.Verbose($"Forcing refresh for {nodePath}");
nodes = node.Refresh(cancelToken, securityToken?.Token, filters).Select(x => x.ToNodeInfo()).ToArray();
nodes = node.Refresh(cancelToken, securityToken?.Token, appliedFilters).Select(x => new NodeInfo(x)).ToArray();
}
else
{
Logger.Verbose($"Expanding {nodePath}");
try
{
nodes = node.Expand(cancelToken, securityToken?.Token, filters).Select(x => x.ToNodeInfo()).ToArray();
nodes = node.Expand(cancelToken, securityToken?.Token, appliedFilters).Select(x => new NodeInfo(x)).ToArray();
}
catch (ConnectionFailureException ex)
{
@@ -534,7 +539,10 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
waitForLockTimeout: timeout,
bindOperation: (bindingContext, cancelToken) =>
{
session = ObjectExplorerSession.CreateSession(connectionResult, serviceProvider, bindingContext.ServerConnection, isDefaultOrSystemDatabase);
session = ObjectExplorerSession.CreateSession(connectionResult, bindingContext.ServerConnection, isDefaultOrSystemDatabase, serviceProvider, () =>
{
return WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema;
});
session.ConnectionInfo = connectionInfo;
sessionMap.AddOrUpdate(uri, session, (key, oldSession) => session);
@@ -687,39 +695,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
return ConnectedBindingQueue.GetConnectionContextKey(details);
}
public IEnumerable<ChildFactory> GetApplicableChildFactories(TreeNode item)
{
if (ApplicableNodeChildFactories != null)
{
HashSet<ChildFactory> applicableFactories;
if (ApplicableNodeChildFactories.TryGetValue(item.NodeTypeId.ToString(), out applicableFactories))
{
return applicableFactories;
}
}
return null;
}
internal Dictionary<string, HashSet<ChildFactory>> PopulateFactories()
{
VerifyServicesInitialized();
var childFactories = new Dictionary<string, HashSet<ChildFactory>>();
// Create our list of all NodeType to ChildFactory objects so we can expand appropriately
foreach (var factory in serviceProvider.GetServices<ChildFactory>())
{
var parents = factory.ApplicableParents();
if (parents != null)
{
foreach (var parent in parents)
{
AddToApplicableChildFactories(childFactories, factory, parent);
}
}
}
return childFactories;
}
private void VerifyServicesInitialized()
{
if (serviceProvider == null)
@@ -821,27 +796,21 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
return string.Empty;
}
internal class ObjectExplorerSession
internal class ObjectExplorerSession : IObjectExplorerSession
{
private ConnectionService connectionService;
private IMultiServiceProvider serviceProvider;
// TODO decide whether a cache is needed to handle lookups in elements with a large # children
//private const int Cachesize = 10000;
//private Cache<string, NodeMapping> cache;
public ObjectExplorerSession(string uri, TreeNode root, IMultiServiceProvider serviceProvider, ConnectionService connectionService)
public ObjectExplorerSession(string uri, TreeNode root)
{
Validate.IsNotNullOrEmptyString("uri", uri);
Validate.IsNotNull("root", root);
Uri = uri;
Root = root;
this.serviceProvider = serviceProvider;
this.connectionService = connectionService;
}
public string Uri { get; private set; }
public TreeNode Root { get; private set; }
public ConnectionInfo ConnectionInfo { get; set; }
@@ -849,10 +818,21 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
public string ErrorMessage { get; set; }
public static ObjectExplorerSession CreateSession(ConnectionCompleteParams response, IMultiServiceProvider serviceProvider, ServerConnection serverConnection, bool isDefaultOrSystemDatabase)
public static ObjectExplorerSession CreateSession(ConnectionCompleteParams response, ServerConnection serverConnection, bool isDefaultOrSystemDatabase, IMultiServiceProvider serviceProvider, Func<bool> groupBySchemaFlagGetter)
{
ServerNode rootNode = new ServerNode(response, serviceProvider, serverConnection);
var session = new ObjectExplorerSession(response.OwnerUri, rootNode, serviceProvider, serviceProvider.GetService<ConnectionService>());
ServerNode rootNode = new ServerNode(new ObjectExplorerServerInfo()
{
ServerName = response.ConnectionSummary.ServerName,
DatabaseName = response.ConnectionSummary.DatabaseName,
UserName = response.ConnectionSummary.UserName,
ServerVersion = response.ServerInfo.ServerVersion,
EngineEditionId = response.ServerInfo.EngineEditionId,
IsCloud = response.ServerInfo.IsCloud,
}, serverConnection, serviceProvider, () =>
{
return WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema;
});
var session = new ObjectExplorerSession(response.OwnerUri, rootNode);
if (!isDefaultOrSystemDatabase)
{
// Assuming the databases are in a folder under server node

View File

@@ -7,9 +7,7 @@
using System;
using System.Threading;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
using System.Collections.Generic;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
{
@@ -53,7 +51,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
/// determines whether to stop going further up the tree</param>
/// <param name="filter">Predicate function to filter the children when traversing</param>
/// <returns>A Tree Node that matches the condition, or null if no matching node could be found</returns>
public static TreeNode? FindNode(TreeNode node, Predicate<TreeNode> condition, Predicate<TreeNode> filter, bool expandIfNeeded = false)
public static TreeNode? FindNode(TreeNode node, Predicate<TreeNode> condition, Predicate<TreeNode> filter, bool expandIfNeeded = false, CancellationToken cancellationToken = new CancellationToken())
{
if (node == null)
{
@@ -64,7 +62,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
{
return node;
}
var children = expandIfNeeded && !node.IsAlwaysLeaf ? node.Expand(new CancellationToken()) : node.GetChildren();
var children = expandIfNeeded && !node.IsAlwaysLeaf ? node.Expand(cancellationToken) : node.GetChildren();
foreach (var child in children)
{
if (filter != null && filter(child))
@@ -78,108 +76,5 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
}
return null;
}
public static INodeFilter ConvertExpandNodeFilterToNodeFilter(NodeFilter filter, NodeFilterProperty filterProperty)
{
Type type = typeof(string);
var IsDateTime = filterProperty.Type == NodeFilterPropertyDataType.Date;
FilterType filterType = FilterType.EQUALS;
bool isNotFilter = false;
object filterValue = null;
switch (filterProperty.Type)
{
case NodeFilterPropertyDataType.String:
case NodeFilterPropertyDataType.Date:
case NodeFilterPropertyDataType.Choice:
type = typeof(string);
filterValue = filter.Value.ToString();
break;
case NodeFilterPropertyDataType.Number:
type = typeof(int);
filterValue = filter.Value.ToObject<int>();
break;
case NodeFilterPropertyDataType.Boolean:
type = typeof(bool);
filterValue = filter.Value.ToObject<bool>() ? 1 : 0;
break;
}
switch (filter.Operator)
{
case NodeFilterOperator.Equals:
filterType = FilterType.EQUALS;
break;
case NodeFilterOperator.NotEquals:
filterType = FilterType.EQUALS;
isNotFilter = true;
break;
case NodeFilterOperator.LessThan:
filterType = FilterType.LESSTHAN;
break;
case NodeFilterOperator.LessThanOrEquals:
filterType = FilterType.LESSTHANOREQUAL;
break;
case NodeFilterOperator.GreaterThan:
filterType = FilterType.GREATERTHAN;
break;
case NodeFilterOperator.GreaterThanOrEquals:
filterType = FilterType.GREATERTHANOREQUAL;
break;
case NodeFilterOperator.Between:
filterType = FilterType.BETWEEN;
break;
case NodeFilterOperator.NotBetween:
filterType = FilterType.NOTBETWEEN;
isNotFilter = true;
break;
case NodeFilterOperator.Contains:
filterType = FilterType.CONTAINS;
break;
case NodeFilterOperator.NotContains:
filterType = FilterType.CONTAINS;
isNotFilter = true;
break;
case NodeFilterOperator.StartsWith:
filterType = FilterType.STARTSWITH;
break;
case NodeFilterOperator.NotStartsWith:
filterType = FilterType.STARTSWITH;
isNotFilter = true;
break;
case NodeFilterOperator.EndsWith:
filterType = FilterType.ENDSWITH;
break;
case NodeFilterOperator.NotEndsWith:
filterType = FilterType.ENDSWITH;
isNotFilter = true;
break;
}
if (filter.Operator == NodeFilterOperator.Between || filter.Operator == NodeFilterOperator.NotBetween)
{
if (filterProperty.Type == NodeFilterPropertyDataType.Number)
{
filterValue = filter.Value.ToObject<int[]>();
}
else if (filterProperty.Type == NodeFilterPropertyDataType.Date)
{
filterValue = filter.Value.ToObject<string[]>();
}
}
return new NodePropertyFilter
{
Property = filterProperty.Name,
Type = type,
Values = new List<object> { filterValue },
IsNotFilter = isNotFilter,
FilterType = filterType,
IsDateTime = IsDateTime
};
}
}
}

View File

@@ -20,6 +20,7 @@ using Microsoft.SqlTools.Utility;
using System.Text;
using System.IO;
using Microsoft.SqlTools.ServiceLayer.Utility.SqlScriptFormatters;
using Microsoft.SqlTools.SqlCore.Utility;
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
@@ -529,7 +530,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
// Update database file names now that we have a database name
if (viewParams.IsNewObject && !prototype.HideFileSettings)
{
var sanitizedName = DatabaseUtils.SanitizeDatabaseFileName(prototype.Name);
var sanitizedName = Utility.DatabaseUtils.SanitizeDatabaseFileName(prototype.Name);
var dataFile = prototype.Files[0];
if (dataFile.DatabaseFileType != FileType.Data)

View File

@@ -7,18 +7,18 @@
using System;
using System.Collections.Generic;
using Microsoft.Data.SqlClient;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Scripting.Contracts;
using Microsoft.SqlTools.Utility;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
using System.Collections.Specialized;
using System.Text;
using System.Globalization;
using Microsoft.SqlServer.Management.SqlScriptPublish;
using Microsoft.SqlTools.ServiceLayer.Utility;
using System.Text;
using Microsoft.Data.SqlClient;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Sdk.Sfc;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.SqlScriptPublish;
using Microsoft.SqlTools.ServiceLayer.Scripting.Contracts;
using Microsoft.SqlTools.SqlCore.Connection;
using Microsoft.SqlTools.SqlCore.Utility;
using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.Scripting
{

View File

@@ -5,14 +5,14 @@
#nullable disable
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Scripting.Contracts;
using Microsoft.SqlTools.Utility;
using System;
using Microsoft.Data.SqlClient;
using System.IO;
using System.Reflection;
using Microsoft.Data.SqlClient;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlTools.ServiceLayer.Scripting.Contracts;
using Microsoft.SqlTools.SqlCore.Connection;
using Microsoft.SqlTools.Utility;
using static Microsoft.SqlServer.Management.SqlScriptPublish.SqlScriptOptions;
namespace Microsoft.SqlTools.ServiceLayer.Scripting

View File

@@ -9,9 +9,9 @@ using System;
using System.Globalization;
using System.Text;
using System.Threading;
using Microsoft.SqlTools.ServiceLayer.Management;
using Microsoft.SqlTools.ServiceLayer.SqlAssessment.Contracts;
using Microsoft.SqlTools.ServiceLayer.TaskServices;
using Microsoft.SqlTools.SqlCore.Utility;
using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.SqlAssessment
@@ -129,7 +129,7 @@ INSERT INTO [dbo].[AssessmentResult] ([CheckName],[CheckId],[RulesetName],[Rules
{
sb.Append(
$@"
('{CUtils.EscapeStringSQuote(item.DisplayName)}','{CUtils.EscapeStringSQuote(item.CheckId)}','{CUtils.EscapeStringSQuote(item.RulesetName)}','{item.RulesetVersion}','{item.Level}','{CUtils.EscapeStringSQuote(item.Message)}','{CUtils.EscapeStringSQuote(item.TargetName)}','{item.TargetType}','{CUtils.EscapeStringSQuote(item.HelpLink)}','{item.Timestamp:yyyy-MM-dd hh:mm:ss.fff zzz}'),");
('{StringUtils.EscapeStringSQuote(item.DisplayName)}','{StringUtils.EscapeStringSQuote(item.CheckId)}','{StringUtils.EscapeStringSQuote(item.RulesetName)}','{item.RulesetVersion}','{item.Level}','{StringUtils.EscapeStringSQuote(item.Message)}','{StringUtils.EscapeStringSQuote(item.TargetName)}','{item.TargetType}','{StringUtils.EscapeStringSQuote(item.HelpLink)}','{item.Timestamp:yyyy-MM-dd hh:mm:ss.fff zzz}'),");
}
}

View File

@@ -10,6 +10,7 @@ using Microsoft.SqlServer.Management.Dmf;
using Microsoft.SqlServer.Management.Sdk.Sfc;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.Management;
using Microsoft.SqlTools.SqlCore.Utility;
using System;
using System.Collections.Generic;
using System.Data;
@@ -37,13 +38,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility
public static string AddStringParameterForInsert(string paramValue)
{
string value = string.IsNullOrWhiteSpace(paramValue) ? paramValue : CUtils.EscapeStringSQuote(paramValue);
string value = string.IsNullOrWhiteSpace(paramValue) ? paramValue : StringUtils.EscapeStringSQuote(paramValue);
return $"'{value}'";
}
public static string AddStringParameterForUpdate(string columnName, string paramValue)
{
string value = string.IsNullOrWhiteSpace(paramValue) ? paramValue : CUtils.EscapeStringSQuote(paramValue);
string value = string.IsNullOrWhiteSpace(paramValue) ? paramValue : StringUtils.EscapeStringSQuote(paramValue);
return $"{columnName} = N'{value}'";
}

View File

@@ -0,0 +1,32 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using Microsoft.SqlServer.Management.Common;
namespace Microsoft.SqlTools.SqlCore.Connection
{
public class AzureAccessToken : IRenewableToken
{
public DateTimeOffset TokenExpiry { get; set; }
public string Resource { get; set; }
public string Tenant { get; set; }
public string UserId { get; set; }
private string accessToken;
public AzureAccessToken(string accessToken)
{
this.accessToken = accessToken;
}
public string GetAccessToken()
{
return this.accessToken;
}
}
}

View File

@@ -3,9 +3,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
namespace Microsoft.SqlTools.ServiceLayer.Connection.Contracts
namespace Microsoft.SqlTools.SqlCore.Connection
{
public class SecurityToken
{

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,968 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype=">text/microsoft-resx</resheader>
<resheader name="version=">2.0</resheader>
<resheader name="reader=">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer=">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1="><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing=">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64=">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64=">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata=">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true=">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="TreeNodeError" xml:space="preserve">
<value>Error expanding: {0}</value>
<comment></comment>
</data>
<data name="ServerNodeConnectionError" xml:space="preserve">
<value>Error connecting to {0}</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Aggregates" xml:space="preserve">
<value>Aggregates</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerRoles" xml:space="preserve">
<value>Server Roles</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ApplicationRoles" xml:space="preserve">
<value>Application Roles</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Assemblies" xml:space="preserve">
<value>Assemblies</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_AssemblyFiles" xml:space="preserve">
<value>Assembly Files</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_AsymmetricKeys" xml:space="preserve">
<value>Asymmetric Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DatabaseAsymmetricKeys" xml:space="preserve">
<value>Asymmetric Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DataCompressionOptions" xml:space="preserve">
<value>Data Compression Options</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Certificates" xml:space="preserve">
<value>Certificates</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_FileTables" xml:space="preserve">
<value>FileTables</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DatabaseCertificates" xml:space="preserve">
<value>Certificates</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_CheckConstraints" xml:space="preserve">
<value>Check Constraints</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Columns" xml:space="preserve">
<value>Columns</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Constraints" xml:space="preserve">
<value>Constraints</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Contracts" xml:space="preserve">
<value>Contracts</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Credentials" xml:space="preserve">
<value>Credentials</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ErrorMessages" xml:space="preserve">
<value>Error Messages</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerRoleMembership" xml:space="preserve">
<value>Server Role Membership</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DatabaseOptions" xml:space="preserve">
<value>Database Options</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DatabaseRoles" xml:space="preserve">
<value>Database Roles</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_RoleMemberships" xml:space="preserve">
<value>Role Memberships</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DatabaseTriggers" xml:space="preserve">
<value>Database Triggers</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DefaultConstraints" xml:space="preserve">
<value>Default Constraints</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Defaults" xml:space="preserve">
<value>Defaults</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Sequences" xml:space="preserve">
<value>Sequences</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Endpoints" xml:space="preserve">
<value>Endpoints</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_EventNotifications" xml:space="preserve">
<value>Event Notifications</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerEventNotifications" xml:space="preserve">
<value>Server Event Notifications</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ExtendedProperties" xml:space="preserve">
<value>Extended Properties</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_FileGroups" xml:space="preserve">
<value>Filegroups</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ForeignKeys" xml:space="preserve">
<value>Foreign Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_FullTextCatalogs" xml:space="preserve">
<value>Full-Text Catalogs</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_FullTextIndexes" xml:space="preserve">
<value>Full-Text Indexes</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Functions" xml:space="preserve">
<value>Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Indexes" xml:space="preserve">
<value>Indexes</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_InlineFunctions" xml:space="preserve">
<value>Inline Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Keys" xml:space="preserve">
<value>Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_LinkedServers" xml:space="preserve">
<value>Linked Servers</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Logins" xml:space="preserve">
<value>Logins</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_MasterKey" xml:space="preserve">
<value>Master Key</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_MasterKeys" xml:space="preserve">
<value>Master Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_MessageTypes" xml:space="preserve">
<value>Message Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_MultiSelectFunctions" xml:space="preserve">
<value>Table-Valued Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Parameters" xml:space="preserve">
<value>Parameters</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_PartitionFunctions" xml:space="preserve">
<value>Partition Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_PartitionSchemes" xml:space="preserve">
<value>Partition Schemes</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Permissions" xml:space="preserve">
<value>Permissions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_PrimaryKeys" xml:space="preserve">
<value>Primary Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Programmability" xml:space="preserve">
<value>Programmability</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Queues" xml:space="preserve">
<value>Queues</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_RemoteServiceBindings" xml:space="preserve">
<value>Remote Service Bindings</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ReturnedColumns" xml:space="preserve">
<value>Returned Columns</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Roles" xml:space="preserve">
<value>Roles</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Routes" xml:space="preserve">
<value>Routes</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Rules" xml:space="preserve">
<value>Rules</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Schemas" xml:space="preserve">
<value>Schemas</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_BuiltInSchema" xml:space="preserve">
<value>Built-in Schemas</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Security" xml:space="preserve">
<value>Security</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerObjects" xml:space="preserve">
<value>Server Objects</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Management" xml:space="preserve">
<value>Management</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerTriggers" xml:space="preserve">
<value>Triggers</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServiceBroker" xml:space="preserve">
<value>Service Broker</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Services" xml:space="preserve">
<value>Services</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Signatures" xml:space="preserve">
<value>Signatures</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_LogFiles" xml:space="preserve">
<value>Log Files</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Statistics" xml:space="preserve">
<value>Statistics</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Storage" xml:space="preserve">
<value>Storage</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_StoredProcedures" xml:space="preserve">
<value>Stored Procedures</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SymmetricKeys" xml:space="preserve">
<value>Symmetric Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Synonyms" xml:space="preserve">
<value>Synonyms</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Tables" xml:space="preserve">
<value>Tables</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Triggers" xml:space="preserve">
<value>Triggers</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Types" xml:space="preserve">
<value>Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_UniqueKeys" xml:space="preserve">
<value>Unique Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_UserDefinedDataTypes" xml:space="preserve">
<value>User-Defined Data Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_UserDefinedTypes" xml:space="preserve">
<value>User-Defined Types (CLR)</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Users" xml:space="preserve">
<value>Users</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Views" xml:space="preserve">
<value>Views</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_XmlIndexes" xml:space="preserve">
<value>XML Indexes</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_XMLSchemaCollections" xml:space="preserve">
<value>XML Schema Collections</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_UserDefinedTableTypes" xml:space="preserve">
<value>User-Defined Table Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_FilegroupFiles" xml:space="preserve">
<value>Files</value>
<comment></comment>
</data>
<data name="MissingCaption" xml:space="preserve">
<value>Missing Caption</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_BrokerPriorities" xml:space="preserve">
<value>Broker Priorities</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_CryptographicProviders" xml:space="preserve">
<value>Cryptographic Providers</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DatabaseAuditSpecifications" xml:space="preserve">
<value>Database Audit Specifications</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DatabaseEncryptionKeys" xml:space="preserve">
<value>Database Encryption Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_EventSessions" xml:space="preserve">
<value>Event Sessions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_FullTextStopLists" xml:space="preserve">
<value>Full Text Stoplists</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ResourcePools" xml:space="preserve">
<value>Resource Pools</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerAudits" xml:space="preserve">
<value>Audits</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerAuditSpecifications" xml:space="preserve">
<value>Server Audit Specifications</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SpatialIndexes" xml:space="preserve">
<value>Spatial Indexes</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_WorkloadGroups" xml:space="preserve">
<value>Workload Groups</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SqlFiles" xml:space="preserve">
<value>SQL Files</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerFunctions" xml:space="preserve">
<value>Server Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SqlType" xml:space="preserve">
<value>SQL Type</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerOptions" xml:space="preserve">
<value>Server Options</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DatabaseDiagrams" xml:space="preserve">
<value>Database Diagrams</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemTables" xml:space="preserve">
<value>System Tables</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Databases" xml:space="preserve">
<value>Databases</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemContracts" xml:space="preserve">
<value>System Contracts</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemDatabases" xml:space="preserve">
<value>System Databases</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemMessageTypes" xml:space="preserve">
<value>System Message Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemQueues" xml:space="preserve">
<value>System Queues</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemServices" xml:space="preserve">
<value>System Services</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemStoredProcedures" xml:space="preserve">
<value>System Stored Procedures</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemViews" xml:space="preserve">
<value>System Views</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DataTierApplications" xml:space="preserve">
<value>Data-tier Applications</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ExtendedStoredProcedures" xml:space="preserve">
<value>Extended Stored Procedures</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemAggregateFunctions" xml:space="preserve">
<value>Aggregate Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemApproximateNumerics" xml:space="preserve">
<value>Approximate Numerics</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemBinaryStrings" xml:space="preserve">
<value>Binary Strings</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemCharacterStrings" xml:space="preserve">
<value>Character Strings</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemCLRDataTypes" xml:space="preserve">
<value>CLR Data Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemConfigurationFunctions" xml:space="preserve">
<value>Configuration Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemCursorFunctions" xml:space="preserve">
<value>Cursor Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemDataTypes" xml:space="preserve">
<value>System Data Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemDateAndTime" xml:space="preserve">
<value>Date and Time</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemDateAndTimeFunctions" xml:space="preserve">
<value>Date and Time Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemExactNumerics" xml:space="preserve">
<value>Exact Numerics</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemFunctions" xml:space="preserve">
<value>System Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemHierarchyIdFunctions" xml:space="preserve">
<value>Hierarchy Id Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemMathematicalFunctions" xml:space="preserve">
<value>Mathematical Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemMetadataFunctions" xml:space="preserve">
<value>Metadata Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemOtherDataTypes" xml:space="preserve">
<value>Other Data Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemOtherFunctions" xml:space="preserve">
<value>Other Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemRowsetFunctions" xml:space="preserve">
<value>Rowset Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemSecurityFunctions" xml:space="preserve">
<value>Security Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemSpatialDataTypes" xml:space="preserve">
<value>Spatial Data Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemStringFunctions" xml:space="preserve">
<value>String Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemSystemStatisticalFunctions" xml:space="preserve">
<value>System Statistical Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemTextAndImageFunctions" xml:space="preserve">
<value>Text and Image Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemUnicodeCharacterStrings" xml:space="preserve">
<value>Unicode Character Strings</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_AggregateFunctions" xml:space="preserve">
<value>Aggregate Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ScalarValuedFunctions" xml:space="preserve">
<value>Scalar-valued Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_TableValuedFunctions" xml:space="preserve">
<value>Table-valued Functions</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SystemExtendedStoredProcedures" xml:space="preserve">
<value>System Extended Stored Procedures</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_BuiltInType" xml:space="preserve">
<value>Built-in Types</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_BuiltInServerRole" xml:space="preserve">
<value>Built-in Server Roles</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_UserWithPassword" xml:space="preserve">
<value>User with Password</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SearchPropertyList" xml:space="preserve">
<value>Search Property List</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SecurityPolicies" xml:space="preserve">
<value>Security Policies</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SecurityPredicates" xml:space="preserve">
<value>Security Predicates</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ServerRole" xml:space="preserve">
<value>Server Role</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SearchPropertyLists" xml:space="preserve">
<value>Search Property Lists</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ColumnStoreIndexes" xml:space="preserve">
<value>Column Store Indexes</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_TableTypeIndexes" xml:space="preserve">
<value>Table Type Indexes</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_Server" xml:space="preserve">
<value>Server</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SelectiveXmlIndexes" xml:space="preserve">
<value>Selective XML Indexes</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_XmlNamespaces" xml:space="preserve">
<value>XML Namespaces</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_XmlTypedPromotedPaths" xml:space="preserve">
<value>XML Typed Promoted Paths</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SqlTypedPromotedPaths" xml:space="preserve">
<value>T-SQL Typed Promoted Paths</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DatabaseScopedCredentials" xml:space="preserve">
<value>Database Scoped Credentials</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ExternalDataSources" xml:space="preserve">
<value>External Data Sources</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ExternalFileFormats" xml:space="preserve">
<value>External File Formats</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ExternalResources" xml:space="preserve">
<value>External Resources</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ExternalTables" xml:space="preserve">
<value>External Tables</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DroppedLedgerColumns" xml:space="preserve">
<value>Dropped Ledger Columns</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DroppedLedgerTables" xml:space="preserve">
<value>Dropped Ledger Tables</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_DroppedLedgerViews" xml:space="preserve">
<value>Dropped Ledger Views</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_AlwaysEncryptedKeys" xml:space="preserve">
<value>Always Encrypted Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ColumnMasterKeys" xml:space="preserve">
<value>Column Master Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ColumnEncryptionKeys" xml:space="preserve">
<value>Column Encryption Keys</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SubroutineParameterLabelFormatString" xml:space="preserve">
<value>{0} ({1}, {2}, {3})</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SubroutineParameterNoDefaultLabel" xml:space="preserve">
<value>No default</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SubroutineParameterInputLabel" xml:space="preserve">
<value>Input</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SubroutineParameterInputOutputLabel" xml:space="preserve">
<value>Input/Output</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SubroutineParameterInputReadOnlyLabel" xml:space="preserve">
<value>Input/ReadOnly</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SubroutineParameterInputOutputReadOnlyLabel" xml:space="preserve">
<value>Input/Output/ReadOnly</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_SubroutineParameterDefaultLabel" xml:space="preserve">
<value>Default</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_NullColumn_Label" xml:space="preserve">
<value>null</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_NotNullColumn_Label" xml:space="preserve">
<value>not null</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_UDDTLabelWithType" xml:space="preserve">
<value>{0} ({1}, {2})</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_UDDTLabelWithoutType" xml:space="preserve">
<value>{0} ({1})</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ComputedColumnLabelWithType" xml:space="preserve">
<value>{0} ({1}Computed, {2}, {3})</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ComputedColumnLabelWithoutType" xml:space="preserve">
<value>{0} ({1}Computed)</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ColumnSetLabelWithoutType" xml:space="preserve">
<value>{0} (Column Set, {1})</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ColumnSetLabelWithType" xml:space="preserve">
<value>{0} (Column Set, {1}{2}, {3})</value>
<comment></comment>
</data>
<data name="SchemaHierarchy_ColumnSetLabelWithTypeAndKeyString" xml:space="preserve">
<value>{0} (Column Set, {1}, {2}, {3})</value>
<comment></comment>
</data>
<data name="UniqueIndex_LabelPart" xml:space="preserve">
<value>Unique</value>
<comment></comment>
</data>
<data name="NonUniqueIndex_LabelPart" xml:space="preserve">
<value>Non-Unique</value>
<comment></comment>
</data>
<data name="ClusteredIndex_LabelPart" xml:space="preserve">
<value>Clustered</value>
<comment></comment>
</data>
<data name="NonClusteredIndex_LabelPart" xml:space="preserve">
<value>Non-Clustered</value>
<comment></comment>
</data>
<data name="History_LabelPart" xml:space="preserve">
<value>History</value>
<comment></comment>
</data>
<data name="SystemVersioned_LabelPart" xml:space="preserve">
<value>System-Versioned</value>
<comment></comment>
</data>
<data name="UpdatableLedger_LabelPart" xml:space="preserve">
<value>Updatable Ledger</value>
<comment></comment>
</data>
<data name="AppendOnlyLedger_LabelPart" xml:space="preserve">
<value>Append-Only Ledger</value>
<comment></comment>
</data>
<data name="Ledger_LabelPart" xml:space="preserve">
<value>Ledger</value>
<comment></comment>
</data>
<data name="External_LabelPart" xml:space="preserve">
<value>External</value>
<comment></comment>
</data>
<data name="FileTable_LabelPart" xml:space="preserve">
<value>File Table</value>
<comment></comment>
</data>
<data name="DatabaseNotAccessible" xml:space="preserve">
<value>The database {0} is not accessible.</value>
<comment></comment>
</data>
<data name="FilterName" xml:space="preserve">
<value>Name</value>
<comment></comment>
</data>
<data name="FilterNameDescription" xml:space="preserve">
<value>Include or exclude objects based on the name or part of a name.</value>
<comment></comment>
</data>
<data name="FilterSchema" xml:space="preserve">
<value>Schema</value>
<comment></comment>
</data>
<data name="FilterSchemaDescription" xml:space="preserve">
<value> Include or exclude objects based on the schema or part of a schema name.</value>
<comment></comment>
</data>
<data name="FilterOwner" xml:space="preserve">
<value>Owner</value>
<comment></comment>
</data>
<data name="FilterOwnerDescription" xml:space="preserve">
<value>Include or exclude objects based on the owner or part of an owner name.</value>
<comment></comment>
</data>
<data name="FilterDurabilityType" xml:space="preserve">
<value>Durability Type</value>
<comment></comment>
</data>
<data name="FilterDurabilityTypeDescription" xml:space="preserve">
<value>Include or exclude objects based on the durability type.</value>
<comment></comment>
</data>
<data name="FilterDurabilitySchemaOnly" xml:space="preserve">
<value>Schema Only</value>
<comment></comment>
</data>
<data name="FilterDurabilitySchemaAndData" xml:space="preserve">
<value>Schema and Data</value>
<comment></comment>
</data>
<data name="FilterIsMemoryOptimized" xml:space="preserve">
<value>Is Memory Optimized</value>
<comment></comment>
</data>
<data name="FilterIsMemoryOptimizedDescription" xml:space="preserve">
<value>Include or exclude objects based on whether the object is memory optimized.</value>
<comment></comment>
</data>
<data name="FilterCreateDate" xml:space="preserve">
<value>Create Date</value>
<comment></comment>
</data>
<data name="FilterCreateDateDescription" xml:space="preserve">
<value>Include or exclude objects based on their creation date.</value>
<comment></comment>
</data>
<data name="FilterIsNativelyCompiled" xml:space="preserve">
<value>Is Natively Compiled</value>
<comment></comment>
</data>
<data name="FilterIsNativelyCompiledDescription" xml:space="preserve">
<value>Include or exclude objects based on whether the object is natively compiled.</value>
<comment></comment>
</data>
<data name="FilterInPrimaryKey" xml:space="preserve">
<value>In Primary Key</value>
<comment></comment>
</data>
<data name="FilterInPrimaryKeyDescription" xml:space="preserve">
<value>Include or exclude objects based on whether the column is in a primary key.</value>
<comment></comment>
</data>
</root>

View File

@@ -0,0 +1,432 @@
# String resource file
#
# When processed by the String Resource Tool, this file generates
# both a .CS and a .RESX file with the same name as the file.
# The .CS file contains a class which can be used to access these
# string resources, including the ability to format in
# parameters, which are identified with the .NET {x} format
# (see String.Format help).
#
# Comments below assume the file name is SR.strings.
#
# Lines starting with a semicolon ";" are also treated as comments, but
# in a future version they will be extracted and made available in LocStudio
# Put your comments to localizers _before_ the string they apply to.
#
# SMO build specific comment
# after generating the .resx file, run srgen on it and get the .resx file
# please remember to also check that .resx in, along with the
# .strings and .cs files
[strings]
############################################################################
# Object Explorer Service
TreeNodeError = Error expanding: {0}
ServerNodeConnectionError = Error connecting to {0}
SchemaHierarchy_Aggregates = Aggregates
SchemaHierarchy_ServerRoles = Server Roles
SchemaHierarchy_ApplicationRoles = Application Roles
SchemaHierarchy_Assemblies = Assemblies
SchemaHierarchy_AssemblyFiles = Assembly Files
SchemaHierarchy_AsymmetricKeys = Asymmetric Keys
SchemaHierarchy_DatabaseAsymmetricKeys = Asymmetric Keys
SchemaHierarchy_DataCompressionOptions = Data Compression Options
SchemaHierarchy_Certificates = Certificates
SchemaHierarchy_FileTables = FileTables
SchemaHierarchy_DatabaseCertificates = Certificates
SchemaHierarchy_CheckConstraints = Check Constraints
SchemaHierarchy_Columns = Columns
SchemaHierarchy_Constraints = Constraints
SchemaHierarchy_Contracts = Contracts
SchemaHierarchy_Credentials = Credentials
SchemaHierarchy_ErrorMessages = Error Messages
SchemaHierarchy_ServerRoleMembership = Server Role Membership
SchemaHierarchy_DatabaseOptions = Database Options
SchemaHierarchy_DatabaseRoles = Database Roles
SchemaHierarchy_RoleMemberships = Role Memberships
SchemaHierarchy_DatabaseTriggers = Database Triggers
SchemaHierarchy_DefaultConstraints = Default Constraints
SchemaHierarchy_Defaults = Defaults
SchemaHierarchy_Sequences = Sequences
SchemaHierarchy_Endpoints = Endpoints
SchemaHierarchy_EventNotifications = Event Notifications
SchemaHierarchy_ServerEventNotifications = Server Event Notifications
SchemaHierarchy_ExtendedProperties = Extended Properties
SchemaHierarchy_FileGroups = Filegroups
SchemaHierarchy_ForeignKeys = Foreign Keys
SchemaHierarchy_FullTextCatalogs = Full-Text Catalogs
SchemaHierarchy_FullTextIndexes = Full-Text Indexes
SchemaHierarchy_Functions = Functions
SchemaHierarchy_Indexes = Indexes
SchemaHierarchy_InlineFunctions = Inline Functions
SchemaHierarchy_Keys = Keys
SchemaHierarchy_LinkedServers = Linked Servers
SchemaHierarchy_Logins = Logins
SchemaHierarchy_MasterKey = Master Key
SchemaHierarchy_MasterKeys = Master Keys
SchemaHierarchy_MessageTypes = Message Types
SchemaHierarchy_MultiSelectFunctions = Table-Valued Functions
SchemaHierarchy_Parameters = Parameters
SchemaHierarchy_PartitionFunctions = Partition Functions
SchemaHierarchy_PartitionSchemes = Partition Schemes
SchemaHierarchy_Permissions = Permissions
SchemaHierarchy_PrimaryKeys = Primary Keys
SchemaHierarchy_Programmability = Programmability
SchemaHierarchy_Queues = Queues
SchemaHierarchy_RemoteServiceBindings = Remote Service Bindings
SchemaHierarchy_ReturnedColumns = Returned Columns
SchemaHierarchy_Roles = Roles
SchemaHierarchy_Routes = Routes
SchemaHierarchy_Rules = Rules
SchemaHierarchy_Schemas = Schemas
SchemaHierarchy_BuiltInSchema = Built-in Schemas
SchemaHierarchy_Security = Security
SchemaHierarchy_ServerObjects = Server Objects
SchemaHierarchy_Management = Management
SchemaHierarchy_ServerTriggers = Triggers
SchemaHierarchy_ServiceBroker = Service Broker
SchemaHierarchy_Services = Services
SchemaHierarchy_Signatures = Signatures
SchemaHierarchy_LogFiles = Log Files
SchemaHierarchy_Statistics = Statistics
SchemaHierarchy_Storage = Storage
SchemaHierarchy_StoredProcedures = Stored Procedures
SchemaHierarchy_SymmetricKeys = Symmetric Keys
SchemaHierarchy_Synonyms = Synonyms
SchemaHierarchy_Tables = Tables
SchemaHierarchy_Triggers = Triggers
SchemaHierarchy_Types = Types
SchemaHierarchy_UniqueKeys = Unique Keys
SchemaHierarchy_UserDefinedDataTypes = User-Defined Data Types
SchemaHierarchy_UserDefinedTypes = User-Defined Types (CLR)
SchemaHierarchy_Users = Users
SchemaHierarchy_Views = Views
SchemaHierarchy_XmlIndexes = XML Indexes
SchemaHierarchy_XMLSchemaCollections = XML Schema Collections
SchemaHierarchy_UserDefinedTableTypes = User-Defined Table Types
SchemaHierarchy_FilegroupFiles = Files
MissingCaption = Missing Caption
SchemaHierarchy_BrokerPriorities = Broker Priorities
SchemaHierarchy_CryptographicProviders = Cryptographic Providers
SchemaHierarchy_DatabaseAuditSpecifications = Database Audit Specifications
SchemaHierarchy_DatabaseEncryptionKeys = Database Encryption Keys
SchemaHierarchy_EventSessions = Event Sessions
SchemaHierarchy_FullTextStopLists = Full Text Stoplists
SchemaHierarchy_ResourcePools = Resource Pools
SchemaHierarchy_ServerAudits = Audits
SchemaHierarchy_ServerAuditSpecifications = Server Audit Specifications
SchemaHierarchy_SpatialIndexes = Spatial Indexes
SchemaHierarchy_WorkloadGroups = Workload Groups
SchemaHierarchy_SqlFiles = SQL Files
SchemaHierarchy_ServerFunctions = Server Functions
SchemaHierarchy_SqlType = SQL Type
SchemaHierarchy_ServerOptions = Server Options
SchemaHierarchy_DatabaseDiagrams = Database Diagrams
SchemaHierarchy_SystemTables = System Tables
SchemaHierarchy_Databases = Databases
SchemaHierarchy_SystemContracts = System Contracts
SchemaHierarchy_SystemDatabases = System Databases
SchemaHierarchy_SystemMessageTypes = System Message Types
SchemaHierarchy_SystemQueues = System Queues
SchemaHierarchy_SystemServices = System Services
SchemaHierarchy_SystemStoredProcedures = System Stored Procedures
SchemaHierarchy_SystemViews = System Views
SchemaHierarchy_DataTierApplications = Data-tier Applications
SchemaHierarchy_ExtendedStoredProcedures = Extended Stored Procedures
SchemaHierarchy_SystemAggregateFunctions = Aggregate Functions
SchemaHierarchy_SystemApproximateNumerics = Approximate Numerics
SchemaHierarchy_SystemBinaryStrings = Binary Strings
SchemaHierarchy_SystemCharacterStrings = Character Strings
SchemaHierarchy_SystemCLRDataTypes = CLR Data Types
SchemaHierarchy_SystemConfigurationFunctions = Configuration Functions
SchemaHierarchy_SystemCursorFunctions = Cursor Functions
SchemaHierarchy_SystemDataTypes = System Data Types
SchemaHierarchy_SystemDateAndTime = Date and Time
SchemaHierarchy_SystemDateAndTimeFunctions = Date and Time Functions
SchemaHierarchy_SystemExactNumerics = Exact Numerics
SchemaHierarchy_SystemFunctions = System Functions
SchemaHierarchy_SystemHierarchyIdFunctions = Hierarchy Id Functions
SchemaHierarchy_SystemMathematicalFunctions = Mathematical Functions
SchemaHierarchy_SystemMetadataFunctions = Metadata Functions
SchemaHierarchy_SystemOtherDataTypes = Other Data Types
SchemaHierarchy_SystemOtherFunctions = Other Functions
SchemaHierarchy_SystemRowsetFunctions = Rowset Functions
SchemaHierarchy_SystemSecurityFunctions = Security Functions
SchemaHierarchy_SystemSpatialDataTypes = Spatial Data Types
SchemaHierarchy_SystemStringFunctions = String Functions
SchemaHierarchy_SystemSystemStatisticalFunctions = System Statistical Functions
SchemaHierarchy_SystemTextAndImageFunctions = Text and Image Functions
SchemaHierarchy_SystemUnicodeCharacterStrings = Unicode Character Strings
SchemaHierarchy_AggregateFunctions = Aggregate Functions
SchemaHierarchy_ScalarValuedFunctions = Scalar-valued Functions
SchemaHierarchy_TableValuedFunctions = Table-valued Functions
SchemaHierarchy_SystemExtendedStoredProcedures = System Extended Stored Procedures
SchemaHierarchy_BuiltInType = Built-in Types
SchemaHierarchy_BuiltInServerRole = Built-in Server Roles
SchemaHierarchy_UserWithPassword = User with Password
SchemaHierarchy_SearchPropertyList = Search Property List
SchemaHierarchy_SecurityPolicies = Security Policies
SchemaHierarchy_SecurityPredicates = Security Predicates
SchemaHierarchy_ServerRole = Server Role
SchemaHierarchy_SearchPropertyLists = Search Property Lists
SchemaHierarchy_ColumnStoreIndexes = Column Store Indexes
SchemaHierarchy_TableTypeIndexes = Table Type Indexes
SchemaHierarchy_Server = Server
SchemaHierarchy_SelectiveXmlIndexes = Selective XML Indexes
SchemaHierarchy_XmlNamespaces = XML Namespaces
SchemaHierarchy_XmlTypedPromotedPaths = XML Typed Promoted Paths
SchemaHierarchy_SqlTypedPromotedPaths = T-SQL Typed Promoted Paths
SchemaHierarchy_DatabaseScopedCredentials = Database Scoped Credentials
SchemaHierarchy_ExternalDataSources = External Data Sources
SchemaHierarchy_ExternalFileFormats = External File Formats
SchemaHierarchy_ExternalResources = External Resources
SchemaHierarchy_ExternalTables = External Tables
SchemaHierarchy_DroppedLedgerColumns = Dropped Ledger Columns
SchemaHierarchy_DroppedLedgerTables = Dropped Ledger Tables
SchemaHierarchy_DroppedLedgerViews = Dropped Ledger Views
SchemaHierarchy_AlwaysEncryptedKeys = Always Encrypted Keys
SchemaHierarchy_ColumnMasterKeys = Column Master Keys
SchemaHierarchy_ColumnEncryptionKeys = Column Encryption Keys
SchemaHierarchy_SubroutineParameterLabelFormatString = {0} ({1}, {2}, {3})
SchemaHierarchy_SubroutineParameterNoDefaultLabel = No default
SchemaHierarchy_SubroutineParameterInputLabel = Input
SchemaHierarchy_SubroutineParameterInputOutputLabel = Input/Output
SchemaHierarchy_SubroutineParameterInputReadOnlyLabel = Input/ReadOnly
SchemaHierarchy_SubroutineParameterInputOutputReadOnlyLabel = Input/Output/ReadOnly
SchemaHierarchy_SubroutineParameterDefaultLabel = Default
SchemaHierarchy_NullColumn_Label = null
SchemaHierarchy_NotNullColumn_Label = not null
SchemaHierarchy_UDDTLabelWithType = {0} ({1}, {2})
SchemaHierarchy_UDDTLabelWithoutType = {0} ({1})
SchemaHierarchy_ComputedColumnLabelWithType = {0} ({1}Computed, {2}, {3})
SchemaHierarchy_ComputedColumnLabelWithoutType = {0} ({1}Computed)
SchemaHierarchy_ColumnSetLabelWithoutType = {0} (Column Set, {1})
SchemaHierarchy_ColumnSetLabelWithType = {0} (Column Set, {1}{2}, {3})
SchemaHierarchy_ColumnSetLabelWithTypeAndKeyString = {0} (Column Set, {1}, {2}, {3})
UniqueIndex_LabelPart = Unique
NonUniqueIndex_LabelPart = Non-Unique
ClusteredIndex_LabelPart = Clustered
NonClusteredIndex_LabelPart = Non-Clustered
History_LabelPart = History
SystemVersioned_LabelPart = System-Versioned
UpdatableLedger_LabelPart = Updatable Ledger
AppendOnlyLedger_LabelPart = Append-Only Ledger
Ledger_LabelPart = Ledger
External_LabelPart = External
FileTable_LabelPart = File Table
DatabaseNotAccessible = The database {0} is not accessible.
FilterName = Name
FilterNameDescription = Include or exclude objects based on the name or part of a name.
FilterSchema = Schema
FilterSchemaDescription = Include or exclude objects based on the schema or part of a schema name.
FilterOwner = Owner
FilterOwnerDescription = Include or exclude objects based on the owner or part of an owner name.
FilterDurabilityType = Durability Type
FilterDurabilityTypeDescription = Include or exclude objects based on the durability type.
FilterDurabilitySchemaOnly = Schema Only
FilterDurabilitySchemaAndData = Schema and Data
FilterIsMemoryOptimized = Is Memory Optimized
FilterIsMemoryOptimizedDescription = Include or exclude objects based on whether the object is memory optimized.
FilterCreateDate = Create Date
FilterCreateDateDescription = Include or exclude objects based on their creation date.
FilterIsNativelyCompiled = Is Natively Compiled
FilterIsNativelyCompiledDescription = Include or exclude objects based on whether the object is natively compiled.
FilterInPrimaryKey = In Primary Key
FilterInPrimaryKeyDescription = Include or exclude objects based on whether the column is in a primary key.

File diff suppressed because it is too large Load Diff

View File

@@ -3,9 +3,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
namespace Microsoft.SqlTools.ServiceLayer.Metadata.Contracts
namespace Microsoft.SqlTools.SqlCore.Metadata
{
/// <summary>
/// Metadata type enumeration

View File

@@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyName>MicrosoftSqlToolsSqlCore</AssemblyName>
<Nullable>disable</Nullable>
<EnableDefaultItems>false</EnableDefaultItems>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
<EmbeddedResourceUseDependentUponConvention>false</EmbeddedResourceUseDependentUponConvention>
<EnableDefaultNoneItems>false</EnableDefaultNoneItems>
<DefineConstants>$(DefineConstants);NETCOREAPP1_0;TRACE</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PreserveCompilationContext>true</PreserveCompilationContext>
<AssemblyTitle>SqlTools SqlCore Library</AssemblyTitle>
<Description>Provides core sql functionality for SQL server editors like Object explorer, Query Execution and Scripting</Description>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" Exclude="**/obj/**/*.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SqlServer.SqlManagementObjects" />
<PackageReference Include="System.Configuration.ConfigurationManager" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../Microsoft.SqlTools.Hosting/Microsoft.SqlTools.Hosting.csproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Localization\*.resx" />
<None Include="Localization\sr.strings" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="ObjectExplorer\SmoModel\SmoTreeNodesDefinition.xml" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="Microsoft.SqlTools.ServiceLayer.UnitTests" />
<InternalsVisibleTo Include="Microsoft.SqlTools.ServiceLayer.IntegrationTests" />
<InternalsVisibleTo Include="Microsoft.SqlTools.ServiceLayer.Test.Common" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,14 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer
{
public class IObjectExplorerSession
{
public TreeNode Root { get; protected set; }
}
}

View File

@@ -3,14 +3,11 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using System.Collections.Generic;
using System.Threading;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes
{
/// <summary>
/// A <see cref="ChildFactory"/> supports creation of <see cref="TreeNode"/> children
@@ -36,7 +33,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
/// <param name="includeSystemObjects">include system objects</param>
/// <param name="cancellationToken">cancellation token</param>
/// <param name="filters">filters to apply</param>
public abstract IEnumerable<TreeNode> Expand(TreeNode parent, bool refresh, string name, bool includeSystemObjects, CancellationToken cancellationToken, IEnumerable<NodeFilter>? filters);
public abstract IEnumerable<TreeNode> Expand(TreeNode parent, bool refresh, string name, bool includeSystemObjects, CancellationToken cancellationToken, IEnumerable<INodeFilter>? filters);
/// <summary>
/// The list of filters that should be applied on the smo object list

View File

@@ -8,7 +8,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes
{
/// <summary>
/// Has information for filtering a SMO object by properties

View File

@@ -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.
//
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes
{
/// <summary>
/// The filterable properties that a node supports
/// </summary>
public class NodeFilterProperty
{
/// <summary>
/// The name of the filter property
/// </summary>
public string? Name { get; set; }
/// <summary>
/// The name of the filter property displayed to the user
/// </summary>
public string? DisplayName { get; set; }
/// <summary>
/// The description of the filter property
/// </summary>
public string? Description { get; set; }
/// <summary>
/// The data type of the filter property
/// </summary>
public NodeFilterPropertyDataType Type { get; set; }
/// <summary>
/// The list of choices for the filter property if the type is choice
/// </summary>
public NodeFilterPropertyChoice[]? Choices { get; set; }
}
/// <summary>
/// The data type of the filter property. Matches NodeFilterPropertyDataType enum in ADS : https://github.com/microsoft/azuredatastudio/blob/main/src/sql/azdata.proposed.d.ts#L1847-L1853
/// </summary>
public enum NodeFilterPropertyDataType
{
String = 0,
Number = 1,
Boolean = 2,
Date = 3,
Choice = 4
}
/// <summary>
/// The choice for the filter property if the type is choice
/// </summary>
public class NodeFilterPropertyChoice
{
/// <summary>
/// The dropdown display value for the choice
/// </summary>
/// <value></value>
public string? DisplayName { get; set; }
/// <summary>
/// The value of the choice
/// </summary>
public string? Value { get; set; }
}
}

View File

@@ -2,16 +2,14 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
using Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel;
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes
{
/// <summary>
/// A collection class for <see cref="TreeNode"/>

View File

@@ -3,13 +3,11 @@
// 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.Text;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes
{
/// <summary>
/// Has information for filtering a SMO object by properties

View File

@@ -2,17 +2,14 @@
// Copyright (c) Microsoft. All rights reserved.
// 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.Text;
using System.Text.RegularExpressions;
using Microsoft.SqlTools.ServiceLayer.Management;
using Microsoft.SqlTools.SqlCore.Utility;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes
{
/// <summary>
/// Has information for filtering a SMO object by properties
@@ -186,7 +183,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
if (Type == typeof(string))
{
//Replacing quotes with double quotes
var escapedString = CUtils.EscapeStringSQuote(propertyValue.ToString());
var escapedString = StringUtils.EscapeStringSQuote(propertyValue.ToString());
if (this.FilterType == FilterType.STARTSWITH || this.FilterType == FilterType.ENDSWITH)
{
escapedString = EscapeLikeURNRegex().Replace(escapedString, "[$0]");

View File

@@ -3,10 +3,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes
{
/// <summary>
/// Has information for SMO object properties to be loaded with the SMO object

View File

@@ -7,7 +7,7 @@
// 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
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes
{
/// <summary>
/// Enum listing possible node types in the object explorer tree

View File

@@ -18,7 +18,7 @@
// 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
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes
{
/// <summary>
/// Enum listing possible node types in the object explorer tree

View File

@@ -2,22 +2,18 @@
// Copyright (c) Microsoft. All rights reserved.
// 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.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.Threading;
using Microsoft.SqlTools.ServiceLayer.Metadata.Contracts;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel;
using Microsoft.SqlTools.ServiceLayer.Utility;
using Microsoft.SqlTools.SqlCore.Metadata;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel;
using Microsoft.SqlTools.SqlCore.Utility;
using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes
{
/// <summary>
/// Base class for elements in the object explorer tree. Provides common methods for tree navigation
@@ -30,6 +26,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
private string nodePath;
private string label;
private string nodePathName;
private static Lazy<Dictionary<string, HashSet<ChildFactory>>> ApplicableNodeChildFactories;
public const char PathPartSeperator = '/';
/// <summary>
@@ -206,7 +203,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
nodePath = path;
}
public TreeNode? FindNodeByPath(string path, bool expandIfNeeded = false)
public TreeNode? FindNodeByPath(string path, bool expandIfNeeded = false, CancellationToken cancellationToken = new CancellationToken())
{
TreeNode? nodeForPath = ObjectExplorerUtils.FindNode(this, node =>
{
@@ -214,39 +211,17 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
}, nodeToFilter =>
{
return path.StartsWith(nodeToFilter.GetNodePath());
}, expandIfNeeded);
}, expandIfNeeded, cancellationToken);
return nodeForPath;
}
/// <summary>
/// Converts to a <see cref="NodeInfo"/> object for serialization with just the relevant properties
/// needed to identify the node
/// </summary>
/// <returns></returns>
public NodeInfo ToNodeInfo()
{
return new NodeInfo()
{
IsLeaf = this.IsAlwaysLeaf,
Label = this.Label,
NodePath = this.GetNodePath(),
ParentNodePath = this.Parent?.GetNodePath() ?? "",
NodeType = this.NodeType,
Metadata = this.ObjectMetadata,
NodeStatus = this.NodeStatus,
NodeSubType = this.NodeSubType,
ErrorMessage = this.ErrorMessage,
ObjectType = this.NodeTypeId.ToString(),
FilterableProperties = this.FilterProperties
};
}
/// <summary>
/// Expands this node and returns its children
/// </summary>
/// <returns>Children as an IList. This is the raw children collection, not a copy</returns>
public IList<TreeNode> Expand(string name, CancellationToken cancellationToken, string? accessToken = null, IEnumerable<NodeFilter>? filters = null)
public IList<TreeNode> Expand(string name, CancellationToken cancellationToken, string? accessToken = null, IEnumerable<INodeFilter>? filters = null)
{
// TODO consider why solution explorer has separate Children and Items options
if (children.IsInitialized)
@@ -261,7 +236,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
/// Expands this node and returns its children
/// </summary>
/// <returns>Children as an IList. This is the raw children collection, not a copy</returns>
public IList<TreeNode> Expand(CancellationToken cancellationToken, string? accessToken = null, IEnumerable<NodeFilter>? filters = null)
public IList<TreeNode> Expand(CancellationToken cancellationToken, string? accessToken = null, IEnumerable<INodeFilter>? filters = null)
{
return Expand(null, cancellationToken, accessToken, filters);
}
@@ -270,7 +245,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
/// Refresh this node and returns its children
/// </summary>
/// <returns>Children as an IList. This is the raw children collection, not a copy</returns>
public virtual IList<TreeNode> Refresh(CancellationToken cancellationToken, string? accessToken = null, IEnumerable<NodeFilter>? filters = null)
public virtual IList<TreeNode> Refresh(CancellationToken cancellationToken, string? accessToken = null, IEnumerable<INodeFilter>? filters = null)
{
// TODO consider why solution explorer has separate Children and Items options
PopulateChildren(true, null, cancellationToken, accessToken, filters);
@@ -325,7 +300,48 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
return Parent as T;
}
protected virtual void PopulateChildren(bool refresh, string name, CancellationToken cancellationToken, string? accessToken = null, IEnumerable<NodeFilter>? filters = null)
private void PopulateFactories()
{
var factories = new Dictionary<string, HashSet<ChildFactory>>();
var serviceProvider = this.GetContextAs<SmoQueryContext>().ServiceProvider;
foreach (var factory in serviceProvider.GetServices<ChildFactory>())
{
var parents = factory.ApplicableParents();
if (parents != null)
{
foreach (var parent in parents)
{
HashSet<ChildFactory> applicableFactories;
if (!factories.TryGetValue(parent, out applicableFactories))
{
applicableFactories = new HashSet<ChildFactory>();
factories[parent] = applicableFactories;
}
applicableFactories.Add(factory);
}
}
}
ApplicableNodeChildFactories = new Lazy<Dictionary<string, HashSet<ChildFactory>>>(factories);
}
public IEnumerable<ChildFactory> GetApplicableChildFactories()
{
if (TreeNode.ApplicableNodeChildFactories == null)
{
this.PopulateFactories();
}
HashSet<ChildFactory> applicableFactories;
if (ApplicableNodeChildFactories.Value.TryGetValue(NodeTypeId.ToString(), out applicableFactories))
{
return applicableFactories;
}
return null;
}
protected virtual void PopulateChildren(bool refresh, string name, CancellationToken cancellationToken, string? accessToken = null, IEnumerable<INodeFilter>? filters = null)
{
Logger.Verbose(string.Format(CultureInfo.InvariantCulture, "Populating oe node :{0}", this.GetNodePath()));
Debug.Assert(IsAlwaysLeaf == false);
@@ -347,7 +363,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
try
{
ErrorMessage = null;
IEnumerable<ChildFactory> childFactories = context.GetObjectExplorerService().GetApplicableChildFactories(this);
IEnumerable<ChildFactory> childFactories = this.GetApplicableChildFactories();
if (childFactories != null)
{
foreach (var factory in childFactories)

View File

@@ -3,7 +3,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes
{
public class TreeNodeWithContext
{

View File

@@ -0,0 +1,22 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer
{
public class ObjectExplorerOptions
{
/// <summary>
/// Function that returns flag to group nodes by schema. Default is false
/// </summary>
public Func<bool> GroupBySchemaFlagGetter { get; set; } = () => false;
/// <summary>
/// Timeout for OE session operations in seconds. Default is 60 seconds
/// </summary>
public int OperationTimeoutSeconds { get; set; } = 60;
}
}

View File

@@ -0,0 +1,42 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer
{
public class ObjectExplorerServerInfo
{
/// <summary>
/// Server name for the OE session
/// </summary>
public string? ServerName { get; set; }
/// <summary>
/// Database name for the OE session
/// </summary>
public string? DatabaseName { get; set; }
/// <summary>
/// User name for the OE session
/// </summary>
public string? UserName { get; set; }
/// <summary>
/// SQL Server version for the OE session
/// </summary>
public string? ServerVersion { get; set; }
/// <summary>
/// SQL Server edition for the OE session
/// </summary>
public int EngineEditionId { get; set; }
/// <summary>
/// Checks if the OE session is for Azure SQL DB
/// </summary>
public bool IsCloud { get; set; }
/// <summary>
/// Indicates if the OE session is for default or system database
/// </summary>
public bool isDefaultOrSystemDatabase { get; set; }
}
}

View File

@@ -0,0 +1,78 @@
//
// 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.Threading;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer
{
/// <summary>
/// Utility class for Object Explorer related operations
/// </summary>
public static class ObjectExplorerUtils
{
/// <summary>
/// Visitor that walks all nodes from the child to the root node, unless the
/// <paramref name="visitor"/> function indicates that this should stop traversing
/// </summary>
/// <param name="child">node to start traversing at</param>
/// <param name="visitor">Predicate function that accesses the tree and
/// determines whether to stop going further up the tree</param>
/// <returns>
/// boolean - true to continue navigating up the tree, false to end the loop
/// and return early
/// </returns>
public static bool VisitChildAndParents(TreeNode child, Predicate<TreeNode> visitor)
{
if (child == null)
{
// End case: all nodes have been visited
return true;
}
// Visit the child first, then go up the parents
if (!visitor(child))
{
return false;
}
return VisitChildAndParents(child.Parent, visitor);
}
/// <summary>
/// Finds a node by traversing the tree starting from the given node through all the children
/// </summary>
/// <param name="node">node to start traversing at</param>
/// <param name="condition">Predicate function that accesses the tree and
/// determines whether to stop going further up the tree</param>
/// <param name="filter">Predicate function to filter the children when traversing</param>
/// <returns>A Tree Node that matches the condition, or null if no matching node could be found</returns>
public static TreeNode? FindNode(TreeNode node, Predicate<TreeNode> condition, Predicate<TreeNode> filter, bool expandIfNeeded = false, CancellationToken cancellationToken = new CancellationToken())
{
if (node == null)
{
return null;
}
if (condition(node))
{
return node;
}
var children = expandIfNeeded && !node.IsAlwaysLeaf ? node.Expand(cancellationToken) : node.GetChildren();
foreach (var child in children)
{
if (filter != null && filter(child))
{
TreeNode? childNode = FindNode(child, condition, filter, expandIfNeeded);
if (childNode != null)
{
return childNode;
}
}
}
return null;
}
}
}

View File

@@ -3,21 +3,18 @@
// 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.Globalization;
using System.Threading;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
internal partial class DatabaseTreeNode
public partial class DatabaseTreeNode
{
public DatabaseTreeNode(ServerNode serverNode, string databaseName) : this()
{
@@ -55,7 +52,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
}
}
protected override void PopulateChildren(bool refresh, string name, CancellationToken cancellationToken, string? accessToken = null, IEnumerable<NodeFilter>? filters = null)
protected override void PopulateChildren(bool refresh, string name, CancellationToken cancellationToken, string? accessToken = null, IEnumerable<INodeFilter>? filters = null)
{
var smoQueryContext = this.GetContextAs<SmoQueryContext>();
if (IsAccessible(smoQueryContext))

View File

@@ -3,12 +3,10 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
/// <summary>
/// Represents a folder node in the tree

View File

@@ -3,14 +3,13 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Serialization;
using System.Reflection;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
public class NodePathGenerator
{
@@ -18,15 +17,15 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
private static Dictionary<string, HashSet<Node>> NodeTypeDictionary { get; set; }
internal static void Initialize()
public static void Initialize()
{
if (TreeRoot != null)
{
return;
}
var assembly = typeof(ObjectExplorerService).Assembly;
var resource = assembly.GetManifestResourceStream("Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel.SmoTreeNodesDefinition.xml");
var assembly = Assembly.GetExecutingAssembly();
var resource = assembly.GetManifestResourceStream("Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel.SmoTreeNodesDefinition.xml");
var serializer = new XmlSerializer(typeof(ServerExplorerTree));
NodeTypeDictionary = new Dictionary<string, HashSet<Node>>();
using (var reader = new StreamReader(resource))
@@ -52,7 +51,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
NodeTypeDictionary.Add("Server", serverSet);
}
internal static HashSet<string> FindNodePaths(ObjectExplorerService.ObjectExplorerSession objectExplorerSession, string typeName, string schema, string name, string databaseName, List<string> parentNames = null)
public static HashSet<string> FindNodePaths(IObjectExplorerSession objectExplorerSession, string typeName, string schema, string name, string databaseName, List<string> parentNames = null)
{
if (TreeRoot == null)
{
@@ -85,7 +84,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
return returnSet;
}
private static HashSet<string> GenerateNodePath(ObjectExplorerService.ObjectExplorerSession objectExplorerSession, Node currentNode, string databaseName, List<string> parentNames, string path)
private static HashSet<string> GenerateNodePath(IObjectExplorerSession objectExplorerSession, Node currentNode, string databaseName, List<string> parentNames, string path)
{
if (parentNames != null)
{

View File

@@ -3,47 +3,43 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using System;
using System.Globalization;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.Extensibility;
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.ServiceLayer.Utility;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
using Microsoft.SqlTools.Utility;
using Microsoft.SqlTools.Extensibility;
using Microsoft.SqlTools.SqlCore.Utility;
using System.IO;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
/// <summary>
/// Server node implementation
/// </summary>
public class ServerNode : TreeNode
{
private ConnectionSummary connectionSummary;
private ServerInfo serverInfo;
private ObjectExplorerServerInfo serverInfo;
private Lazy<SmoQueryContext> context;
private SmoWrapper smoWrapper;
private SqlServerType sqlServerType;
private ServerConnection serverConnection;
public ServerConnection serverConnection;
public ServerNode(ConnectionCompleteParams connInfo, IMultiServiceProvider serviceProvider, ServerConnection serverConnection)
public ServerNode(ObjectExplorerServerInfo serverInfo, ServerConnection serverConnection, IMultiServiceProvider serviceProvider = null, Func<bool> groupBySchemaFlag = null)
: base()
{
Validate.IsNotNull(nameof(connInfo), connInfo);
Validate.IsNotNull("connInfo.ConnectionSummary", connInfo.ConnectionSummary);
Validate.IsNotNull(nameof(serviceProvider), serviceProvider);
Validate.IsNotNull(nameof(ObjectExplorerServerInfo), serverInfo);
this.connectionSummary = connInfo.ConnectionSummary;
this.serverInfo = connInfo.ServerInfo;
this.serverInfo = serverInfo;
this.sqlServerType = ServerVersionHelper.CalculateServerType(this.serverInfo);
this.context = new Lazy<SmoQueryContext>(() => CreateContext(serviceProvider));
var assembly = typeof(SqlCore.ObjectExplorer.SmoModel.SmoQuerier).Assembly;
serviceProvider ??= ExtensionServiceProvider.CreateFromAssembliesInDirectory(Path.GetDirectoryName(assembly.Location), new string[] { Path.GetFileName(assembly.Location) });
this.context = new Lazy<SmoQueryContext>(() => CreateContext(serviceProvider, groupBySchemaFlag));
this.serverConnection = serverConnection;
NodeValue = connectionSummary.ServerName;
NodeValue = serverInfo.ServerName;
IsAlwaysLeaf = false;
NodeType = NodeTypes.Server.ToString();
NodeTypeId = NodeTypes.Server;
@@ -68,7 +64,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
/// </summary>
internal string GetConnectionLabel()
{
string userName = connectionSummary.UserName;
string userName = serverInfo.UserName;
// TODO Domain and username is not yet supported on .Net Core.
// Consider passing as an input from the extension where this can be queried
@@ -79,16 +75,16 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
// TODO Consider adding IsAuthenticatingDatabaseMaster check in the code and
// referencing result here
if (!DatabaseUtils.IsSystemDatabaseConnection(connectionSummary.DatabaseName))
if (!DatabaseUtils.IsSystemDatabaseConnection(serverInfo.DatabaseName))
{
// We either have an azure with a database specified or a Denali database using a contained user
if (string.IsNullOrWhiteSpace(userName))
{
userName = connectionSummary.DatabaseName;
userName = serverInfo.DatabaseName;
}
else
{
userName += ", " + connectionSummary.DatabaseName;
userName += ", " + serverInfo.DatabaseName;
}
}
@@ -98,7 +94,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
label = string.Format(
CultureInfo.InvariantCulture,
"{0} ({1} {2})",
connectionSummary.ServerName,
serverInfo.ServerName,
"SQL Server",
serverInfo.ServerVersion);
}
@@ -107,7 +103,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
label = string.Format(
CultureInfo.InvariantCulture,
"{0} ({1} {2} - {3})",
connectionSummary.ServerName,
serverInfo.ServerName,
"SQL Server",
serverInfo.ServerVersion,
userName);
@@ -118,7 +114,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
private SmoQueryContext CreateContext(IMultiServiceProvider serviceProvider)
private SmoQueryContext CreateContext(IMultiServiceProvider serviceProvider, Func<bool> groupBySchemaFlag = null)
{
string exceptionMessage;
@@ -127,7 +123,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
Server server = SmoWrapper.CreateServer(this.serverConnection);
if (server != null)
{
return new SmoQueryContext(server, serviceProvider, SmoWrapper)
return new SmoQueryContext(server, serviceProvider, SmoWrapper, groupBySchemaFlag)
{
Parent = server,
SqlServerType = this.sqlServerType

View File

@@ -1,356 +1,353 @@
//
// Copyright (c) Microsoft. All rights reserved.
// 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.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Threading;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{
public class SmoChildFactoryBase : ChildFactory
{
private IEnumerable<NodeSmoProperty> smoProperties;
public override IEnumerable<string> ApplicableParents()
{
return null;
}
public override IEnumerable<TreeNode> Expand(TreeNode parent, bool refresh, string name, bool includeSystemObjects, CancellationToken cancellationToken, IEnumerable<NodeFilter>? filters = null)
{
List<TreeNode> allChildren = new List<TreeNode>();
try
{
if (this.PutFoldersAfterNodes)
{
OnExpandPopulateNonFolders(allChildren, parent, refresh, name, cancellationToken, filters);
OnExpandPopulateFoldersAndFilter(allChildren, parent, includeSystemObjects);
RemoveFoldersFromInvalidSqlServerVersions(allChildren, parent);
}
else
{
OnExpandPopulateFoldersAndFilter(allChildren, parent, includeSystemObjects);
RemoveFoldersFromInvalidSqlServerVersions(allChildren, parent);
OnExpandPopulateNonFolders(allChildren, parent, refresh, name, cancellationToken, filters);
}
OnBeginAsyncOperations(parent);
}
catch (Exception ex)
{
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.Error(error);
throw;
}
return allChildren;
}
private void OnExpandPopulateFoldersAndFilter(List<TreeNode> allChildren, TreeNode parent, bool includeSystemObjects)
{
SmoQueryContext context = parent.GetContextAs<SmoQueryContext>();
OnExpandPopulateFolders(allChildren, parent);
if (!includeSystemObjects)
{
allChildren.RemoveAll(x => x.IsSystemObject);
}
if (context != null && context.ValidFor != 0 && context.ValidFor != ValidForFlag.All)
{
allChildren.RemoveAll(x =>
{
FolderNode folderNode = x as FolderNode;
if (folderNode != null && !ServerVersionHelper.IsValidFor(context.ValidFor, folderNode.ValidFor))
{
return true;
}
return false;
});
// Remove the Dropped Ledger Columns folder if this isn't under a ledger table
allChildren.RemoveAll(x =>
{
if (x.NodeTypeId == NodeTypes.DroppedLedgerColumns)
{
Table? parentTable = context.Parent as Table;
if (parentTable == null ||
!(parentTable.LedgerType == LedgerTableType.UpdatableLedgerTable ||
parentTable.LedgerType == LedgerTableType.AppendOnlyLedgerTable))
{
return true;
}
}
return false;
});
}
}
/// <summary>
/// Populates any folders for a given parent node
/// </summary>
/// <param name="allChildren">List to which nodes should be added</param>
/// <param name="parent">Parent the nodes are being added to</param>
protected virtual void OnExpandPopulateFolders(IList<TreeNode> allChildren, TreeNode parent)
{
}
/// <summary>
/// Populates any non-folder nodes such as specific items in the tree.
/// </summary>
/// <param name="allChildren">List to which nodes should be added</param>
/// <param name="parent">Parent the nodes are being added to</param>
protected virtual void OnExpandPopulateNonFolders(IList<TreeNode> allChildren, TreeNode parent, bool refresh, string name, CancellationToken cancellationToken, IEnumerable<NodeFilter>? appliedFilters = null)
{
Logger.Verbose(string.Format(CultureInfo.InvariantCulture, "child factory parent :{0}", parent.GetNodePath()));
if (ChildQuerierTypes == null)
{
// This node does not support non-folder children
return;
}
SmoQueryContext context = parent.GetContextAs<SmoQueryContext>();
Validate.IsNotNull(nameof(context), context);
var serverValidFor = context.ValidFor;
if (ShouldFilterNode(parent, serverValidFor))
{
return;
}
IEnumerable<SmoQuerier> queriers = context.ServiceProvider.GetServices<SmoQuerier>(IsCompatibleQuerier);
var filters = this.Filters.ToList();
var smoProperties = this.SmoProperties.Where(p => ServerVersionHelper.IsValidFor(serverValidFor, p.ValidFor)).Select(x => x.Name);
var filterDefinitions = parent.FilterProperties;
if (!string.IsNullOrEmpty(name))
{
filters.Add(new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
Values = new List<object> { name },
});
}
if (appliedFilters != null)
{
foreach (var f in appliedFilters)
{
NodeFilterProperty filterProperty = filterDefinitions.FirstOrDefault(x => x.Name == f.Name);
filters.Add(ObjectExplorerUtils.ConvertExpandNodeFilterToNodeFilter(f, filterProperty));
}
}
foreach (var querier in queriers)
{
cancellationToken.ThrowIfCancellationRequested();
if (!querier.IsValidFor(serverValidFor))
{
continue;
}
string propertyFilter = INodeFilter.GetPropertyFilter(filters, querier.GetType(), serverValidFor);
try
{
var smoObjectList = querier.Query(context, propertyFilter, refresh, smoProperties).ToList();
foreach (var smoObject in smoObjectList)
{
cancellationToken.ThrowIfCancellationRequested();
if (smoObject == null)
{
Logger.Error("smoObject should not be null");
}
TreeNode childNode = CreateChild(parent, smoObject);
if (childNode != null && PassesFinalFilters(childNode, smoObject) && !ShouldFilterNode(childNode, serverValidFor))
{
allChildren.Add(childNode);
}
}
}
catch (Exception ex)
{
string error = string.Format(CultureInfo.InvariantCulture, "Failed getting smo objects. parent:{0} querier: {1} error:{2} inner:{3} stacktrace:{4}",
parent != null ? parent.GetNodePath() : "", querier.GetType(), ex.Message, ex.InnerException != null ? ex.InnerException.Message : "", ex.StackTrace);
Logger.Error(error);
throw;
}
}
}
private bool ShouldFilterNode(TreeNode childNode, ValidForFlag validForFlag)
{
bool filterTheNode = false;
SmoTreeNode smoTreeNode = childNode as SmoTreeNode;
if (smoTreeNode != null)
{
if (!ServerVersionHelper.IsValidFor(validForFlag, smoTreeNode.ValidFor))
{
filterTheNode = true;
}
}
return filterTheNode;
}
private bool IsCompatibleQuerier(SmoQuerier querier)
{
if (ChildQuerierTypes == null)
{
return false;
}
Type actualType = querier.GetType();
foreach (Type childType in ChildQuerierTypes)
{
// We will accept any querier that is compatible with the listed querier type
if (childType.IsAssignableFrom(actualType))
{
return true;
}
}
return false;
}
/// <summary>
/// Filters out invalid folders if they cannot be displayed for the current server version
/// </summary>
/// <param name="allChildren">List to which nodes should be added</param>
/// <param name="parent">Parent the nodes are being added to</param>
protected virtual void RemoveFoldersFromInvalidSqlServerVersions(IList<TreeNode> allChildren, TreeNode parent)
{
}
// TODO Assess whether async operations node is required
protected virtual void OnBeginAsyncOperations(TreeNode parent)
{
}
public override bool CanCreateChild(TreeNode parent, object context)
{
return false;
}
public override TreeNode CreateChild(TreeNode parent, object context)
{
throw new NotImplementedException();
}
protected virtual void InitializeChild(TreeNode parent, TreeNode child, object context)
{
NamedSmoObject smoObj = context as NamedSmoObject;
if (smoObj == null)
{
Debug.WriteLine("context is not a NamedSmoObject. type: " + context.GetType());
}
else
{
smoProperties = SmoProperties;
SmoTreeNode childAsMeItem = (SmoTreeNode)child;
childAsMeItem.CacheInfoFromModel(smoObj);
SmoQueryContext smoContext = parent.GetContextAs<SmoQueryContext>();
// If node has custom name, replaced it with the name already set
string customizedName = GetNodeCustomName(context, smoContext);
if (!string.IsNullOrEmpty(customizedName))
{
childAsMeItem.NodeValue = customizedName;
childAsMeItem.NodePathName = GetNodePathName(context);
}
childAsMeItem.NodeSubType = GetNodeSubType(context, smoContext);
childAsMeItem.NodeStatus = GetNodeStatus(context, smoContext);
}
}
internal virtual Type[] ChildQuerierTypes
{
get
{
return null;
}
}
public override IEnumerable<INodeFilter> Filters
{
get
{
return Enumerable.Empty<INodeFilter>();
}
}
public override IEnumerable<NodeSmoProperty> SmoProperties
{
get
{
return Enumerable.Empty<NodeSmoProperty>();
}
}
internal IEnumerable<NodeSmoProperty> CachedSmoProperties
{
get
{
return smoProperties == null ? SmoProperties : smoProperties;
}
}
/// <summary>
/// Returns true if any final validation of the object to be added passes, and false
/// if validation fails. This provides a chance to filter specific items out of a list
/// </summary>
/// <param name="parent"></param>
/// <param name="contextObject"></param>
/// <returns>boolean</returns>
public virtual bool PassesFinalFilters(TreeNode parent, object context)
{
return true;
}
public override string GetNodeSubType(object smoObject, SmoQueryContext smoContext)
{
return string.Empty;
}
public override string GetNodeStatus(object smoObject, SmoQueryContext smoContext)
{
return string.Empty;
}
public static bool IsPropertySupported(string propertyName, SmoQueryContext context, NamedSmoObject smoObj, IEnumerable<NodeSmoProperty> supportedProperties)
{
var property = supportedProperties.FirstOrDefault(x => string.Compare(x.Name, propertyName, StringComparison.InvariantCultureIgnoreCase) == 0);
if (property != null)
{
return ServerVersionHelper.IsValidFor(context.ValidFor, property.ValidFor);
}
else
{
// Return true if cannot find the proeprty, SMO still tries to get that property but adding the property to supported list can make loading the nodes faster
Logger.Verbose($"Smo property name {propertyName} for Smo type {smoObj.GetType()} is not added as supported properties. This can cause the performance of loading the OE nodes");
return true;
}
}
public override string GetNodeCustomName(object smoObject, SmoQueryContext smoContext)
{
return string.Empty;
}
public override string GetNodePathName(object smoObject)
{
return (smoObject as NamedSmoObject).Name;
}
}
}
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Threading;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
public class SmoChildFactoryBase : ChildFactory
{
private IEnumerable<NodeSmoProperty> smoProperties;
public override IEnumerable<string> ApplicableParents()
{
return null;
}
public override IEnumerable<TreeNode> Expand(TreeNode parent, bool refresh, string name, bool includeSystemObjects, CancellationToken cancellationToken, IEnumerable<INodeFilter>? filters = null)
{
List<TreeNode> allChildren = new List<TreeNode>();
try
{
if (this.PutFoldersAfterNodes)
{
OnExpandPopulateNonFolders(allChildren, parent, refresh, name, cancellationToken, filters);
OnExpandPopulateFoldersAndFilter(allChildren, parent, includeSystemObjects);
RemoveFoldersFromInvalidSqlServerVersions(allChildren, parent);
}
else
{
OnExpandPopulateFoldersAndFilter(allChildren, parent, includeSystemObjects);
RemoveFoldersFromInvalidSqlServerVersions(allChildren, parent);
OnExpandPopulateNonFolders(allChildren, parent, refresh, name, cancellationToken, filters);
}
OnBeginAsyncOperations(parent);
}
catch (Exception ex)
{
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.Error(error);
throw;
}
return allChildren;
}
private void OnExpandPopulateFoldersAndFilter(List<TreeNode> allChildren, TreeNode parent, bool includeSystemObjects)
{
SmoQueryContext context = parent.GetContextAs<SmoQueryContext>();
OnExpandPopulateFolders(allChildren, parent);
if (!includeSystemObjects)
{
allChildren.RemoveAll(x => x.IsSystemObject);
}
if (context != null && context.ValidFor != 0 && context.ValidFor != ValidForFlag.All)
{
allChildren.RemoveAll(x =>
{
FolderNode folderNode = x as FolderNode;
if (folderNode != null && !ServerVersionHelper.IsValidFor(context.ValidFor, folderNode.ValidFor))
{
return true;
}
return false;
});
// Remove the Dropped Ledger Columns folder if this isn't under a ledger table
allChildren.RemoveAll(x =>
{
if (x.NodeTypeId == NodeTypes.DroppedLedgerColumns)
{
Table? parentTable = context.Parent as Table;
if (parentTable == null ||
!(parentTable.LedgerType == LedgerTableType.UpdatableLedgerTable ||
parentTable.LedgerType == LedgerTableType.AppendOnlyLedgerTable))
{
return true;
}
}
return false;
});
}
}
/// <summary>
/// Populates any folders for a given parent node
/// </summary>
/// <param name="allChildren">List to which nodes should be added</param>
/// <param name="parent">Parent the nodes are being added to</param>
protected virtual void OnExpandPopulateFolders(IList<TreeNode> allChildren, TreeNode parent)
{
}
/// <summary>
/// Populates any non-folder nodes such as specific items in the tree.
/// </summary>
/// <param name="allChildren">List to which nodes should be added</param>
/// <param name="parent">Parent the nodes are being added to</param>
protected virtual void OnExpandPopulateNonFolders(IList<TreeNode> allChildren, TreeNode parent, bool refresh, string name, CancellationToken cancellationToken, IEnumerable<INodeFilter>? appliedFilters = null)
{
Logger.Verbose(string.Format(CultureInfo.InvariantCulture, "child factory parent :{0}", parent.GetNodePath()));
if (this.GetChildQuerierTypes(parent) == null)
{
// This node does not support non-folder children
return;
}
SmoQueryContext context = parent.GetContextAs<SmoQueryContext>();
Validate.IsNotNull(nameof(context), context);
var serverValidFor = context.ValidFor;
if (ShouldFilterNode(parent, serverValidFor))
{
return;
}
IEnumerable<SmoQuerier> queriers = context.ServiceProvider.GetServices<SmoQuerier>((q) => IsCompatibleQuerier(q, parent));
var filters = this.Filters.ToList();
var smoProperties = this.SmoProperties.Where(p => ServerVersionHelper.IsValidFor(serverValidFor, p.ValidFor)).Select(x => x.Name);
if (!string.IsNullOrEmpty(name))
{
filters.Add(new NodePropertyFilter
{
Property = "Name",
Type = typeof(string),
Values = new List<object> { name },
});
}
if (appliedFilters != null)
{
filters.AddRange(appliedFilters);
}
foreach (var querier in queriers)
{
cancellationToken.ThrowIfCancellationRequested();
if (!querier.IsValidFor(serverValidFor))
{
continue;
}
string propertyFilter = INodeFilter.GetPropertyFilter(filters, querier.GetType(), serverValidFor);
try
{
var smoObjectList = querier.Query(context, propertyFilter, refresh, smoProperties).ToList();
foreach (var smoObject in smoObjectList)
{
cancellationToken.ThrowIfCancellationRequested();
if (smoObject == null)
{
Logger.Error("smoObject should not be null");
}
TreeNode childNode = CreateChild(parent, smoObject);
if (childNode != null && PassesFinalFilters(childNode, smoObject) && !ShouldFilterNode(childNode, serverValidFor))
{
allChildren.Add(childNode);
}
}
}
catch (Exception ex)
{
string error = string.Format(CultureInfo.InvariantCulture, "Failed getting smo objects. parent:{0} querier: {1} error:{2} inner:{3} stacktrace:{4}",
parent != null ? parent.GetNodePath() : "", querier.GetType(), ex.Message, ex.InnerException != null ? ex.InnerException.Message : "", ex.StackTrace);
Logger.Error(error);
throw;
}
}
}
private bool ShouldFilterNode(TreeNode childNode, ValidForFlag validForFlag)
{
bool filterTheNode = false;
SmoTreeNode smoTreeNode = childNode as SmoTreeNode;
if (smoTreeNode != null)
{
if (!ServerVersionHelper.IsValidFor(validForFlag, smoTreeNode.ValidFor))
{
filterTheNode = true;
}
}
return filterTheNode;
}
private bool IsCompatibleQuerier(SmoQuerier querier, TreeNode parent)
{
if (this.GetChildQuerierTypes(parent) == null)
{
return false;
}
Type actualType = querier.GetType();
foreach (Type childType in this.GetChildQuerierTypes(parent))
{
// We will accept any querier that is compatible with the listed querier type
if (childType.IsAssignableFrom(actualType))
{
return true;
}
}
return false;
}
/// <summary>
/// Filters out invalid folders if they cannot be displayed for the current server version
/// </summary>
/// <param name="allChildren">List to which nodes should be added</param>
/// <param name="parent">Parent the nodes are being added to</param>
protected virtual void RemoveFoldersFromInvalidSqlServerVersions(IList<TreeNode> allChildren, TreeNode parent)
{
}
// TODO Assess whether async operations node is required
protected virtual void OnBeginAsyncOperations(TreeNode parent)
{
}
public override bool CanCreateChild(TreeNode parent, object context)
{
return false;
}
public override TreeNode CreateChild(TreeNode parent, object context)
{
throw new NotImplementedException();
}
protected virtual void InitializeChild(TreeNode parent, TreeNode child, object context)
{
NamedSmoObject smoObj = context as NamedSmoObject;
if (smoObj == null)
{
Debug.WriteLine("context is not a NamedSmoObject. type: " + context.GetType());
}
else
{
smoProperties = SmoProperties;
SmoTreeNode childAsMeItem = (SmoTreeNode)child;
childAsMeItem.CacheInfoFromModel(smoObj);
SmoQueryContext smoContext = parent.GetContextAs<SmoQueryContext>();
// If node has custom name, replaced it with the name already set
string customizedName = GetNodeCustomName(context, smoContext);
if (!string.IsNullOrEmpty(customizedName))
{
childAsMeItem.NodeValue = customizedName;
childAsMeItem.NodePathName = GetNodePathName(context);
}
childAsMeItem.NodeSubType = GetNodeSubType(context, smoContext);
childAsMeItem.NodeStatus = GetNodeStatus(context, smoContext);
}
}
internal virtual Type[] ChildQuerierTypes
{
get
{
return null;
}
}
public override IEnumerable<INodeFilter> Filters
{
get
{
return Enumerable.Empty<INodeFilter>();
}
}
public override IEnumerable<NodeSmoProperty> SmoProperties
{
get
{
return Enumerable.Empty<NodeSmoProperty>();
}
}
internal IEnumerable<NodeSmoProperty> CachedSmoProperties
{
get
{
return smoProperties == null ? SmoProperties : smoProperties;
}
}
protected virtual Type[] GetChildQuerierTypes(TreeNode parent)
{
return ChildQuerierTypes;
}
/// <summary>
/// Returns true if any final validation of the object to be added passes, and false
/// if validation fails. This provides a chance to filter specific items out of a list
/// </summary>
/// <param name="parent"></param>
/// <param name="contextObject"></param>
/// <returns>boolean</returns>
public virtual bool PassesFinalFilters(TreeNode parent, object context)
{
return true;
}
public override string GetNodeSubType(object smoObject, SmoQueryContext smoContext)
{
return string.Empty;
}
public override string GetNodeStatus(object smoObject, SmoQueryContext smoContext)
{
return string.Empty;
}
public static bool IsPropertySupported(string propertyName, SmoQueryContext context, NamedSmoObject smoObj, IEnumerable<NodeSmoProperty> supportedProperties)
{
var property = supportedProperties.FirstOrDefault(x => string.Compare(x.Name, propertyName, StringComparison.InvariantCultureIgnoreCase) == 0);
if (property != null)
{
return ServerVersionHelper.IsValidFor(context.ValidFor, property.ValidFor);
}
else
{
// Return true if cannot find the proeprty, SMO still tries to get that property but adding the property to supported list can make loading the nodes faster
Logger.Verbose($"Smo property name {propertyName} for Smo type {smoObj.GetType()} is not added as supported properties. This can cause the performance of loading the OE nodes");
return true;
}
}
public override string GetNodeCustomName(object smoObject, SmoQueryContext smoContext)
{
return string.Empty;
}
public override string GetNodePathName(object smoObject)
{
return (smoObject as NamedSmoObject).Name;
}
}
}

View File

@@ -3,14 +3,12 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.SqlServer.Management.Smo;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
/// <summary>
/// Wrapper to convert non-generic Smo enumerables to generic enumerable types for easier use in

View File

@@ -3,16 +3,14 @@
// 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.Globalization;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
/// <summary>
/// Custom name for Columns

View File

@@ -3,15 +3,13 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using System.Collections.Generic;
using Microsoft.SqlTools.Utility;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
using System;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
/// <summary>
/// Status for databases

View File

@@ -3,11 +3,10 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.SqlCore.Connection;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
internal static class SmoExtensions
{

View File

@@ -3,15 +3,13 @@
// 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 Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
using Index = Microsoft.SqlServer.Management.Smo.Index;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
/// <summary>
/// Subtye for keys

View File

@@ -3,14 +3,12 @@
// 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 Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
/// <summary>
/// Status for logins

View File

@@ -3,12 +3,10 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using System.Globalization;
using Microsoft.SqlServer.Management.Smo;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
/// <summary>
/// Custom name for parameters

View File

@@ -1,98 +1,87 @@
//
// Copyright (c) Microsoft. All rights reserved.
// 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.Data;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.Extensibility;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{
/// <summary>
/// A <see cref="SmoQuerier"/> handles SMO queries for one or more SMO object types.
/// The <see cref="SupportedObjectTypes"/> property defines which types can be queried.
///
/// To query multiple
/// </summary>
public abstract class SmoQuerier : IComposableService
{
public abstract Type[] SupportedObjectTypes { get; }
private static object lockObject = new object();
/// <summary>
/// Queries SMO for a collection of objects using the <see cref="SmoQueryContext"/>
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public abstract IEnumerable<SqlSmoObject> Query(SmoQueryContext context, string filter, bool refresh, IEnumerable<string> extraProperties);
internal IMultiServiceProvider ServiceProvider
{
get;
private set;
}
public void SetServiceProvider(IMultiServiceProvider provider)
{
ServiceProvider = provider;
}
/// <summary>
/// Convert the data to data reader is possible
/// </summary>
protected IDataReader GetDataReader(object data)
{
IDataReader reader = null;
if (data is IDataReader)
{
reader = data as IDataReader;
}
else if(data is DataTable)
{
reader = ((DataTable)data).CreateDataReader();
}
else if (data is DataSet)
{
reader = ((DataSet)data).Tables[0].CreateDataReader();
}
return reader;
}
/// <summary>
/// Mthod used to do custom filtering on smo objects if cannot be implemented using the filters
/// </summary>
protected virtual bool PassesFinalFilters(SqlSmoObject parent, SqlSmoObject smoObject)
{
return true;
}
/// <summary>
/// Returns true if the querier is valid for the given server version
/// </summary>
/// <param name="serverValidFor"></param>
/// <returns></returns>
public bool IsValidFor(ValidForFlag serverValidFor)
{
return ServerVersionHelper.IsValidFor(serverValidFor, ValidFor);
}
/// <summary>
/// Indicates which platforms the querier is valid for
/// </summary>
public virtual ValidForFlag ValidFor
{
get
{
return ValidForFlag.All;
}
}
}
}
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Collections.Generic;
using System.Data;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.Extensibility;
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
/// <summary>
/// A <see cref="SmoQuerier"/> handles SMO queries for one or more SMO object types.
/// The <see cref="SupportedObjectTypes"/> property defines which types can be queried.
///
/// To query multiple
/// </summary>
public abstract class SmoQuerier : IComposableService
{
public abstract Type[] SupportedObjectTypes { get; }
private static object lockObject = new object();
/// <summary>
/// Queries SMO for a collection of objects using the <see cref="SmoQueryContext"/>
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public abstract IEnumerable<SqlSmoObject> Query(SmoQueryContext context, string filter, bool refresh, IEnumerable<string> extraProperties);
internal IMultiServiceProvider ServiceProvider
{
get;
private set;
}
public void SetServiceProvider(IMultiServiceProvider provider)
{
ServiceProvider = provider;
}
/// <summary>
/// Convert the data to data reader is possible
/// </summary>
protected IDataReader GetDataReader(object data)
{
IDataReader reader = null;
if (data is IDataReader)
{
reader = data as IDataReader;
}
else if(data is DataTable)
{
reader = ((DataTable)data).CreateDataReader();
}
else if (data is DataSet)
{
reader = ((DataSet)data).Tables[0].CreateDataReader();
}
return reader;
}
/// <summary>
/// Mthod used to do custom filtering on smo objects if cannot be implemented using the filters
/// </summary>
protected virtual bool PassesFinalFilters(SqlSmoObject parent, SqlSmoObject smoObject) => true;
/// <summary>
/// Returns true if the querier is valid for the given server version
/// </summary>
/// <param name="serverValidFor"></param>
/// <returns></returns>
public bool IsValidFor(ValidForFlag serverValidFor) => ServerVersionHelper.IsValidFor(serverValidFor, ValidFor);
/// <summary>
/// Indicates which platforms the querier is valid for
/// </summary>
public virtual ValidForFlag ValidFor
{
get => ValidForFlag.All;
}
}
}

View File

@@ -3,14 +3,12 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using System;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.Extensibility;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
/// <summary>
/// Context object containing key properties needed to query for SMO objects
@@ -22,21 +20,23 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
private SmoObjectBase parent;
private SmoWrapper smoWrapper;
private ValidForFlag validFor = 0;
private Func<bool> groupBySchemaFlag;
/// <summary>
/// Creates a context object with a server to use as the basis for any queries
/// </summary>
/// <param name="server"></param>
public SmoQueryContext(Server server, IMultiServiceProvider serviceProvider)
: this(server, serviceProvider, null)
public SmoQueryContext(Server server, IMultiServiceProvider serviceProvider, Func<bool> groupBySchemaFlag = null)
: this(server, serviceProvider, null, groupBySchemaFlag)
{
}
internal SmoQueryContext(Server server, IMultiServiceProvider serviceProvider, SmoWrapper serverManager)
internal SmoQueryContext(Server server, IMultiServiceProvider serviceProvider, SmoWrapper serverManager, Func<bool> groupBySchemaFlag = null)
{
this.server = server;
ServiceProvider = serviceProvider;
this.smoWrapper = serverManager ?? new SmoWrapper();
this.groupBySchemaFlag = groupBySchemaFlag ?? new Func<bool>(() => false);
}
/// <summary>
@@ -85,6 +85,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
}
}
public bool GroupBySchema
{
get => groupBySchemaFlag();
}
/// <summary>
/// A query loader that can be used to find <see cref="SmoQuerier"/> objects
/// for specific SMO types
@@ -102,26 +107,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
return Parent as T;
}
/// <summary>
/// Gets the <see cref="ObjectExplorerService"/> if available, by looking it up
/// from the <see cref="ServiceProvider"/>
/// </summary>
/// <returns></returns>
/// <exception cref="InvalidOperationException">
/// Thrown if the <see cref="ServiceProvider"/> is not set or the <see cref="ObjectExplorerService"/>
/// isn't available from that provider
/// </exception>
public ObjectExplorerService GetObjectExplorerService()
{
if (ServiceProvider == null)
{
throw new InvalidOperationException(SR.ServiceProviderNotSet);
}
return ServiceProvider.GetService<ObjectExplorerService>()
?? throw new InvalidOperationException(SR.ServiceNotFound(nameof(ObjectExplorerService)));
}
/// <summary>
/// Copies the context for use by another node
/// </summary>
@@ -129,7 +114,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
/// <returns>new <see cref="SmoQueryContext"/> with all fields except <see cref="Parent"/> the same</returns>
public SmoQueryContext CopyWithParent(SmoObjectBase parent)
{
SmoQueryContext context = new SmoQueryContext(this.Server, this.ServiceProvider, this.smoWrapper)
SmoQueryContext context = new SmoQueryContext(this.Server, this.ServiceProvider, this.smoWrapper, this.groupBySchemaFlag)
{
database = this.Database,
Parent = parent,

View File

@@ -3,8 +3,6 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
// This file was generated by a T4 Template. Do not modify directly, instead update the SmoQueryModelDefinition.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".
@@ -15,11 +13,11 @@ 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.SqlCore.ObjectExplorer.Nodes;
using Microsoft.SqlTools.Utility;
using Index = Microsoft.SqlServer.Management.Smo.Index;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
[Export(typeof(SmoQuerier))]

View File

@@ -12,8 +12,6 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
// This file was generated by a T4 Template. Do not modify directly, instead update the SmoQueryModelDefinition.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".
@@ -24,11 +22,11 @@ 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.SqlCore.ObjectExplorer.Nodes;
using Microsoft.SqlTools.Utility;
using Index = Microsoft.SqlServer.Management.Smo.Index;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
<#
var directory = Path.GetDirectoryName(Host.TemplateFile);

View File

@@ -3,11 +3,9 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using Microsoft.SqlServer.Management.Smo;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
/// <summary>
/// Custom name for table

View File

@@ -1,127 +1,123 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{
/// <summary>
/// A Node in the tree representing a SMO-based object
/// </summary>
public class SmoTreeNode : TreeNode
{
public static int FolderSortPriority = 0;
private static int _nextSortPriority = FolderSortPriority + 1; // 0 is reserved for folders
protected SmoQueryContext context;
public SmoTreeNode() : base()
{
}
protected virtual void OnInitialize()
{
// TODO setup initialization
}
/// <summary>
/// Is this a system (MSShipped) object?
/// </summary>
public bool IsMsShippedOwned { get; set; }
/// <summary>
/// Indicates which platforms a node is valid for
/// </summary>
public ValidForFlag ValidFor { get; set; }
/// <summary>
/// Gets an incrementing sort priority value to assist in automatically sorting
/// elements in a tree
/// </summary>
public static int NextSortPriority
{
get
{
return System.Threading.Interlocked.Increment(ref _nextSortPriority);
}
}
public NamedSmoObject SmoObject { get; private set; }
public virtual void CacheInfoFromModel(NamedSmoObject smoObject)
{
SmoObject = smoObject;
NodeValue = smoObject.Name;
ScriptSchemaObjectBase schemaBaseObject = smoObject as ScriptSchemaObjectBase;
ObjectMetadata = new Metadata.Contracts.ObjectMetadata();
ObjectMetadata.Name = smoObject.Name;
try
{
if (smoObject.Urn != null)
{
ObjectMetadata.Urn = smoObject.Urn.Value;
ObjectMetadata.MetadataTypeName = smoObject.Urn.Type;
}
}
catch
{
//Ignore the exception, sometimes the urn returns exception and I' not sure why
}
if (schemaBaseObject != null)
{
ObjectMetadata.Schema = schemaBaseObject.Schema;
if (!string.IsNullOrEmpty(ObjectMetadata.Schema))
{
NodeValue = $"{ObjectMetadata.Schema}.{smoObject.Name}";
}
}
else
{
// Try to read the schema from the parent object
var parent = smoObject?.ParentCollection?.ParentInstance as ScriptSchemaObjectBase;
if (parent != null)
{
ObjectMetadata.Schema = parent.Schema;
ObjectMetadata.ParentName = parent.Name;
ObjectMetadata.ParentTypeName = parent.Urn.Type;
}
}
}
public virtual NamedSmoObject GetParentSmoObject()
{
if (SmoObject != null)
{
return SmoObject;
}
// Return the parent's object, or null if it's not set / not a SmoTreeNode
return ParentAs<SmoTreeNode>()?.GetParentSmoObject();
}
public override object GetContext()
{
EnsureContextInitialized();
return context;
}
protected virtual void EnsureContextInitialized()
{
if (context == null)
{
SmoObjectBase smoParent = GetParentSmoObject();
SmoQueryContext parentContext = Parent?.GetContextAs<SmoQueryContext>();
if (smoParent != null && parentContext != null)
{
context = parentContext.CopyWithParent(smoParent);
}
}
}
}
}
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.SqlCore.Metadata;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
/// <summary>
/// A Node in the tree representing a SMO-based object
/// </summary>
public class SmoTreeNode : TreeNode
{
public static int FolderSortPriority = 0;
private static int _nextSortPriority = FolderSortPriority + 1; // 0 is reserved for folders
protected SmoQueryContext context;
public SmoTreeNode() : base()
{
}
protected virtual void OnInitialize()
{
// TODO setup initialization
}
/// <summary>
/// Is this a system (MSShipped) object?
/// </summary>
public bool IsMsShippedOwned { get; set; }
/// <summary>
/// Indicates which platforms a node is valid for
/// </summary>
public ValidForFlag ValidFor { get; set; }
/// <summary>
/// Gets an incrementing sort priority value to assist in automatically sorting
/// elements in a tree
/// </summary>
public static int NextSortPriority
{
get => System.Threading.Interlocked.Increment(ref _nextSortPriority);
}
public NamedSmoObject SmoObject { get; private set; }
public virtual void CacheInfoFromModel(NamedSmoObject smoObject)
{
SmoObject = smoObject;
NodeValue = smoObject.Name;
ScriptSchemaObjectBase schemaBaseObject = smoObject as ScriptSchemaObjectBase;
ObjectMetadata = new ObjectMetadata();
ObjectMetadata.Name = smoObject.Name;
try
{
if (smoObject.Urn != null)
{
ObjectMetadata.Urn = smoObject.Urn.Value;
ObjectMetadata.MetadataTypeName = smoObject.Urn.Type;
}
}
catch
{
//Ignore the exception, sometimes the urn returns exception and I' not sure why
}
if (schemaBaseObject != null)
{
ObjectMetadata.Schema = schemaBaseObject.Schema;
if (!string.IsNullOrEmpty(ObjectMetadata.Schema))
{
NodeValue = $"{ObjectMetadata.Schema}.{smoObject.Name}";
}
}
else
{
// Try to read the schema from the parent object
var parent = smoObject?.ParentCollection?.ParentInstance as ScriptSchemaObjectBase;
if (parent != null)
{
ObjectMetadata.Schema = parent.Schema;
ObjectMetadata.ParentName = parent.Name;
ObjectMetadata.ParentTypeName = parent.Urn.Type;
}
}
}
public virtual NamedSmoObject GetParentSmoObject()
{
if (SmoObject != null)
{
return SmoObject;
}
// Return the parent's object, or null if it's not set / not a SmoTreeNode
return ParentAs<SmoTreeNode>()?.GetParentSmoObject();
}
public override object GetContext()
{
EnsureContextInitialized();
return context;
}
protected virtual void EnsureContextInitialized()
{
if (context == null)
{
SmoObjectBase smoParent = GetParentSmoObject();
SmoQueryContext parentContext = Parent?.GetContextAs<SmoQueryContext>();
if (smoParent != null && parentContext != null)
{
context = parentContext.CopyWithParent(smoParent);
}
}
}
}
}

View File

@@ -3,8 +3,6 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
// 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".
@@ -13,47 +11,23 @@ using System;
using System.Collections.Generic;
using System.Composition;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
using Microsoft.SqlTools.ServiceLayer.SqlContext;
using Microsoft.SqlTools.ServiceLayer.Workspace;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
internal sealed partial class DatabaseTreeNode : SmoTreeNode
public partial class DatabaseTreeNode : SmoTreeNode
{
public DatabaseTreeNode() : base()
{
NodeValue = string.Empty;
this.NodeType = "Database";
this.NodeTypeId = NodeTypes.Database;
if(WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema)
{
this.FilterProperties = new NodeFilterProperty[]
{
new NodeFilterProperty
{
Name = "Name",
DisplayName = SR.FilterName,
Type = NodeFilterPropertyDataType.String,
Description = SR.FilterNameDescription,
},
new NodeFilterProperty
{
Name = "Owner",
DisplayName = SR.FilterOwner,
Type = NodeFilterPropertyDataType.String,
Description = SR.FilterOwnerDescription,
},
};
}
OnInitialize();
}
}
internal sealed partial class TableTreeNode : SmoTreeNode
public partial class TableTreeNode : SmoTreeNode
{
public TableTreeNode() : base()
{
@@ -64,7 +38,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
}
}
internal sealed partial class ViewTreeNode : SmoTreeNode
public partial class ViewTreeNode : SmoTreeNode
{
public ViewTreeNode() : base()
{
@@ -75,7 +49,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
}
}
internal sealed partial class UserDefinedTableTypeTreeNode : SmoTreeNode
public partial class UserDefinedTableTypeTreeNode : SmoTreeNode
{
public UserDefinedTableTypeTreeNode() : base()
{
@@ -86,7 +60,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
}
}
internal sealed partial class StoredProcedureTreeNode : SmoTreeNode
public partial class StoredProcedureTreeNode : SmoTreeNode
{
public StoredProcedureTreeNode() : base()
{
@@ -97,7 +71,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
}
}
internal sealed partial class TableValuedFunctionTreeNode : SmoTreeNode
public partial class TableValuedFunctionTreeNode : SmoTreeNode
{
public TableValuedFunctionTreeNode() : base()
{
@@ -108,7 +82,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
}
}
internal sealed partial class ScalarValuedFunctionTreeNode : SmoTreeNode
public partial class ScalarValuedFunctionTreeNode : SmoTreeNode
{
public ScalarValuedFunctionTreeNode() : base()
{
@@ -119,7 +93,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
}
}
internal sealed partial class AggregateFunctionTreeNode : SmoTreeNode
public partial class AggregateFunctionTreeNode : SmoTreeNode
{
public AggregateFunctionTreeNode() : base()
{
@@ -130,7 +104,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
}
}
internal sealed partial class FileGroupTreeNode : SmoTreeNode
public partial class FileGroupTreeNode : SmoTreeNode
{
public FileGroupTreeNode() : base()
{
@@ -141,7 +115,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
}
}
internal sealed partial class ExternalTableTreeNode : SmoTreeNode
public partial class ExternalTableTreeNode : SmoTreeNode
{
public ExternalTableTreeNode() : base()
{
@@ -152,7 +126,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
}
}
internal sealed partial class ExternalResourceTreeNode : SmoTreeNode
public partial class ExternalResourceTreeNode : SmoTreeNode
{
public ExternalResourceTreeNode() : base()
{
@@ -163,7 +137,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
}
}
internal sealed partial class HistoryTableTreeNode : SmoTreeNode
public partial class HistoryTableTreeNode : SmoTreeNode
{
public HistoryTableTreeNode() : base()
{
@@ -174,7 +148,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
}
}
internal sealed partial class ExpandableSchemaTreeNode : SmoTreeNode
public partial class ExpandableSchemaTreeNode : SmoTreeNode
{
public ExpandableSchemaTreeNode() : base()
{
@@ -303,6 +277,26 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{
var child = new DatabaseTreeNode();
InitializeChild(parent, child, context);
if((parent.GetContext() as SmoQueryContext).GroupBySchema)
{
child.FilterProperties = new NodeFilterProperty[]
{
new NodeFilterProperty
{
Name = "Name",
DisplayName = SR.FilterName,
Type = NodeFilterPropertyDataType.String,
Description = SR.FilterNameDescription,
},
new NodeFilterProperty
{
Name = "Owner",
DisplayName = SR.FilterOwner,
Type = NodeFilterPropertyDataType.String,
Description = SR.FilterOwnerDescription,
},
};
}
return child;
}
}
@@ -444,6 +438,26 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{
var child = new DatabaseTreeNode();
InitializeChild(parent, child, context);
if((parent.GetContext() as SmoQueryContext).GroupBySchema)
{
child.FilterProperties = new NodeFilterProperty[]
{
new NodeFilterProperty
{
Name = "Name",
DisplayName = SR.FilterName,
Type = NodeFilterPropertyDataType.String,
Description = SR.FilterNameDescription,
},
new NodeFilterProperty
{
Name = "Owner",
DisplayName = SR.FilterOwner,
Type = NodeFilterPropertyDataType.String,
Description = SR.FilterOwnerDescription,
},
};
}
return child;
}
}
@@ -769,7 +783,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
protected override void OnExpandPopulateFolders(IList<TreeNode> currentChildren, TreeNode parent)
{
if (!WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema)
if (!(parent.GetContext() as SmoQueryContext).GroupBySchema)
{
currentChildren.Add(new FolderNode {
NodeValue = SR.SchemaHierarchy_Tables,
@@ -833,7 +847,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
}
});
}
if (!WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema)
if (!(parent.GetContext() as SmoQueryContext).GroupBySchema)
{
currentChildren.Add(new FolderNode {
NodeValue = SR.SchemaHierarchy_Views,
@@ -873,7 +887,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
}
});
}
if (!WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema)
if (!(parent.GetContext() as SmoQueryContext).GroupBySchema)
{
currentChildren.Add(new FolderNode {
NodeValue = SR.SchemaHierarchy_Synonyms,
@@ -883,7 +897,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
SortPriority = SmoTreeNode.NextSortPriority,
});
}
if (WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema)
if ((parent.GetContext() as SmoQueryContext).GroupBySchema)
{
currentChildren.Add(new FolderNode {
NodeValue = SR.SchemaHierarchy_BuiltInSchema,
@@ -928,19 +942,17 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
});
}
internal override Type[] ChildQuerierTypes
protected override Type[] GetChildQuerierTypes(TreeNode parent)
{
get
{
List<Type> conditionalTypesList = new List<Type>();
if (WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema)
{
conditionalTypesList.Add(typeof(SqlSchemaQuerier));
}
return conditionalTypesList.ToArray();
}
List<Type> conditionalTypesList = new List<Type>();
if ((parent.GetContext() as SmoQueryContext).GroupBySchema)
{
conditionalTypesList.Add(typeof(SqlSchemaQuerier));
}
return conditionalTypesList.ToArray();
}
public override TreeNode CreateChild(TreeNode parent, object context)
{
var child = new ExpandableSchemaTreeNode();
@@ -1557,7 +1569,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
protected override void OnExpandPopulateFolders(IList<TreeNode> currentChildren, TreeNode parent)
{
if (!WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema)
if (!(parent.GetContext() as SmoQueryContext).GroupBySchema)
{
currentChildren.Add(new FolderNode {
NodeValue = SR.SchemaHierarchy_StoredProcedures,
@@ -1604,7 +1616,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
}
});
}
if (!WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema)
if (!(parent.GetContext() as SmoQueryContext).GroupBySchema)
{
currentChildren.Add(new FolderNode {
NodeValue = SR.SchemaHierarchy_Functions,
@@ -1628,7 +1640,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
ValidFor = ValidForFlag.AllOnPrem|ValidForFlag.AzureV12,
SortPriority = SmoTreeNode.NextSortPriority,
});
if (!WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema)
if (!(parent.GetContext() as SmoQueryContext).GroupBySchema)
{
currentChildren.Add(new FolderNode {
NodeValue = SR.SchemaHierarchy_Types,
@@ -1638,7 +1650,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
SortPriority = SmoTreeNode.NextSortPriority,
});
}
if (!WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings.SqlTools.ObjectExplorer.GroupBySchema)
if (!(parent.GetContext() as SmoQueryContext).GroupBySchema)
{
currentChildren.Add(new FolderNode {
NodeValue = SR.SchemaHierarchy_Sequences,

View File

@@ -14,8 +14,6 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
// 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".
@@ -24,13 +22,9 @@ using System;
using System.Collections.Generic;
using System.Composition;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
using Microsoft.SqlTools.ServiceLayer.SqlContext;
using Microsoft.SqlTools.ServiceLayer.Workspace;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
<#
@@ -79,76 +73,13 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{
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(" public partial class {0} : SmoTreeNode", name);
WriteLine(" {");
WriteLine(" public {0}() : base()", name);
WriteLine(" {");
WriteLine(" NodeValue = string.Empty;");
WriteLine(" this.NodeType = \"{0}\";", type.Replace("TreeNode", string.Empty));
WriteLine(" this.NodeTypeId = NodeTypes.{0};", name.Replace("TreeNode", string.Empty));
List<XmlElement> filterProperties = GetFilterProperties(xmlFile, type.Replace("TreeNode", string.Empty));
string settingsFlag = GetFilterSettingsFlag(xmlFile, type.Replace("TreeNode", string.Empty));
if(!String.IsNullOrEmpty(settingsFlag))
{
WriteLine(" if({0})", GetSettingsString(settingsFlag));
WriteLine(" {");
}
if(filterProperties.Count > 0){
WriteLine(" this.FilterProperties = new NodeFilterProperty[]");
WriteLine(" {");
foreach (var filterDef in filterProperties)
{
var filterName = filterDef.GetAttribute("Name");
var filterDisplayName = filterDef.GetAttribute("LocLabel");
var filterType = filterDef.GetAttribute("Type");
var enumString = "NodeFilterPropertyDataType";
switch (filterType)
{
case "string":
enumString += ".String";
break;
case "bool":
enumString += ".Boolean";
break;
case "date":
enumString += ".Date";
break;
case "choice":
enumString += ".Choice";
break;
}
var filterDescription = filterDef.GetAttribute("Description");
WriteLine(" new NodeFilterProperty");
WriteLine(" {");
WriteLine(" Name = \"{0}\",", filterName);
WriteLine(" DisplayName = {0},", filterDisplayName);
WriteLine(" Type = {0},", enumString);
WriteLine(" Description = {0},", filterDescription);
if(filterType == "choice")
{
var choiceValues = filterDef.ChildNodes;
WriteLine(" Choices = new NodeFilterPropertyChoice[] {");
foreach (XmlElement choice in choiceValues)
{
var choiceName = choice.GetAttribute("LocLabel");
var choiceValue = choice.GetAttribute("Value");
WriteLine(" new NodeFilterPropertyChoice {");
WriteLine(" DisplayName = {0},", choiceName);
WriteLine(" Value = \"{0}\",", choiceValue);
WriteLine(" },");
}
WriteLine(" }");
}
WriteLine(" },");
}
WriteLine(" };");
}
if(!String.IsNullOrEmpty(settingsFlag))
{
WriteLine(" }");
}
WriteLine(" OnInitialize();");
WriteLine(" }");
WriteLine(" }");
@@ -435,11 +366,10 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
if(ConditionalChildQuerierTypes.Count > 0)
{
WriteLine("");
WriteLine(" internal override Type[] ChildQuerierTypes");
WriteLine(" protected override Type[] GetChildQuerierTypes(TreeNode parent)");
WriteLine(" {");
WriteLine(" get");
WriteLine(" {");
WriteLine(" List<Type> conditionalTypesList = new List<Type>();");
WriteLine(" List<Type> conditionalTypesList = new List<Type>();");
foreach(XmlElement Querier in ConditionalChildQuerierTypes)
{
var settingsFlag = Querier.GetAttribute("SettingsFlag");
@@ -447,20 +377,20 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
if(!string.IsNullOrEmpty(settingsFlag))
{
WriteLine(" if ({0})", GetSettingsString(settingsFlag));
WriteLine(" {");
WriteLine(" conditionalTypesList.Add(typeof({0}Querier));", QuerierName);
WriteLine(" }");
WriteLine(" if ({0})", GetSettingsString(settingsFlag));
WriteLine(" {");
WriteLine(" conditionalTypesList.Add(typeof({0}Querier));", QuerierName);
WriteLine(" }");
}
else
{
WriteLine(" conditionalTypesList.Add(typeof({0}Querier));", QuerierName);
WriteLine(" conditionalTypesList.Add(typeof({0}Querier));", QuerierName);
}
}
WriteLine(" return conditionalTypesList.ToArray();");
WriteLine(" }");
WriteLine(" return conditionalTypesList.ToArray();");
WriteLine(" }");
}
WriteLine("");
}
else
{
string[] allTypes = ChildQuerierTypes.Split(new [] { ';' }, StringSplitOptions.RemoveEmptyEntries);
@@ -514,6 +444,67 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
WriteLine(" child.SortPriority = SmoTreeNode.NextSortPriority;");
}
WriteLine(" InitializeChild(parent, child, context);");
List<XmlElement> filterProperties = GetFilterProperties(xmlFile, TreeNode.Replace("TreeNode", string.Empty));
string filterFlag = GetFilterSettingsFlag(xmlFile, TreeNode.Replace("TreeNode", string.Empty));
if(!String.IsNullOrEmpty(filterFlag))
{
WriteLine(" if((parent.GetContext() as SmoQueryContext).{0})", filterFlag);
WriteLine(" {");
}
if(filterProperties.Count > 0){
WriteLine(" child.FilterProperties = new NodeFilterProperty[]");
WriteLine(" {");
foreach (var filterDef in filterProperties)
{
var filterName = filterDef.GetAttribute("Name");
var filterDisplayName = filterDef.GetAttribute("LocLabel");
var filterType = filterDef.GetAttribute("Type");
var enumString = "NodeFilterPropertyDataType";
switch (filterType)
{
case "string":
enumString += ".String";
break;
case "bool":
enumString += ".Boolean";
break;
case "date":
enumString += ".Date";
break;
case "choice":
enumString += ".Choice";
break;
}
var filterDescription = filterDef.GetAttribute("Description");
WriteLine(" new NodeFilterProperty");
WriteLine(" {");
WriteLine(" Name = \"{0}\",", filterName);
WriteLine(" DisplayName = {0},", filterDisplayName);
WriteLine(" Type = {0},", enumString);
WriteLine(" Description = {0},", filterDescription);
if(filterType == "choice")
{
var choiceValues = filterDef.ChildNodes;
WriteLine(" Choices = new NodeFilterPropertyChoice[] {");
foreach (XmlElement choice in choiceValues)
{
var choiceName = choice.GetAttribute("LocLabel");
var choiceValue = choice.GetAttribute("Value");
WriteLine(" new NodeFilterPropertyChoice {");
WriteLine(" DisplayName = {0},", choiceName);
WriteLine(" Value = \"{0}\",", choiceValue);
WriteLine(" },");
}
WriteLine(" }");
}
WriteLine(" },");
}
WriteLine(" };");
WriteLine(" }");
}
WriteLine(" return child;");
WriteLine(" }");
}
@@ -849,6 +840,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
notOperator = "!";
settingsName = settingsName.Substring(1, settingsName.Length-1);
}
return String.Format("{0}WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings.SqlTools.ObjectExplorer.{1}", notOperator, settingsName);
return String.Format("{0}(parent.GetContext() as SmoQueryContext).{1}", notOperator, settingsName);
}
#>

View File

@@ -677,4 +677,3 @@
<FilterProperty Name="IsNativelyCompiled" LocLabel="SR.FilterIsNativelyCompiled" Type="bool" Description="SR.FilterIsNativelyCompiledDescription"/>
<FilterProperty Name="InPrimaryKey" LocLabel="SR.FilterInPrimaryKey" Type="bool" Description="SR.FilterInPrimaryKeyDescription"/>
</ServerExplorerTree>

View File

@@ -3,14 +3,12 @@
// 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 Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
/// <summary>
/// Status for triggers

View File

@@ -3,14 +3,12 @@
// 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 Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
/// <summary>
/// Status for logins

View File

@@ -3,11 +3,10 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using Microsoft.SqlServer.Management.Smo;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
/// <summary>
/// Custom name for view

View File

@@ -3,12 +3,10 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
/// <summary>
/// Internal for testing purposes only. This class provides wrapper functionality

View File

@@ -3,12 +3,10 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using System;
using Microsoft.SqlServer.Management.Smo;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
/// <summary>
/// Filters the history tables to only return ones related to the parent table

View File

@@ -3,13 +3,11 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using System.Collections.Generic;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel
{
internal partial class SystemExactNumericsChildFactory
{

View File

@@ -3,15 +3,12 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using System;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer
{
/// <summary>
/// Server Types
@@ -102,7 +99,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
/// <summary>
/// Creates a server type from the server version
/// </summary>
public static SqlServerType CalculateServerType(ServerInfo serverInfo)
public static SqlServerType CalculateServerType(ObjectExplorerServerInfo serverInfo)
{
string serverVersion = serverInfo.ServerVersion;

View File

@@ -0,0 +1,119 @@
//
// 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 System.Threading;
using System.Threading.Tasks;
using Microsoft.Data.SqlClient;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlTools.SqlCore.Connection;
using Microsoft.SqlTools.SqlCore.ObjectExplorer;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.Nodes;
using Microsoft.SqlTools.SqlCore.ObjectExplorer.SmoModel;
namespace Microsoft.SqlTools.CoreSql.ObjectExplorer
{
/// <summary>
/// Stateless object explorer class can be used to handle object explorer requests without creating a session. It requires a connection string and a node path to query objects from the server.
/// </summary>
public class StatelessObjectExplorer
{
/// <summary>
/// Expands the node at the given path and returns the child nodes.
/// </summary>
/// <param name="connectionString"> Connection string to connect to the server </param>
/// <param name="accessToken"> Access token to connect to the server. To be used in case of AAD based connections </param>
/// <param name="nodePath"> Path of the node to expand </param>
/// <param name="serverInfo"> Server information </param>
/// <param name="options"> Object explorer options </param>
/// <param name="filters"> Filters to be applied on the leaf nodes </param>
/// <returns> Array of child nodes </returns>
/// <exception cref="ArgumentNullException"> Thrown when the parent node is not found </exception>
/// <exception cref="TimeoutException"> Thrown when the operation times out.</exception> <summary>
/// </summary>
public static TreeNode[] Expand(string connectionString, SecurityToken? accessToken, string nodePath, ObjectExplorerServerInfo serverInfo, ObjectExplorerOptions options, INodeFilter[]? filters = null)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
ServerConnection connection;
if (accessToken != null)
{
connection = new ServerConnection(conn, accessToken as IRenewableToken);
}
else
{
connection = new ServerConnection(conn);
}
ServerNode serverNode = new ServerNode(serverInfo, connection, null, options.GroupBySchemaFlagGetter);
TreeNode rootNode = new DatabaseTreeNode(serverNode, serverInfo.DatabaseName);
if(nodePath == null || nodePath == string.Empty)
{
nodePath = rootNode.GetNodePath();
}
using (var taskCancellationTokenSource = new CancellationTokenSource())
{
TreeNode? node = rootNode;
if (node == null)
{
// Return empty array if node is not found
return new TreeNode[0];
}
if (Monitor.TryEnter(node.BuildingMetadataLock, options.OperationTimeoutSeconds))
{
try
{
var token = accessToken == null ? null : accessToken.Token;
var task = Task.Run(() =>
{
var node = rootNode.FindNodeByPath(nodePath, true, taskCancellationTokenSource.Token);
if (node != null)
{
return node.Expand(taskCancellationTokenSource.Token, token, filters);
} else
{
throw new InvalidArgumentException($"Parent node not found for path {nodePath}");
}
});
if (task.Wait(TimeSpan.FromSeconds(options.OperationTimeoutSeconds)))
{
if (taskCancellationTokenSource.IsCancellationRequested)
{
throw new TimeoutException("The operation has timed out.");
}
return task.Result.ToArray();
}
else
{
throw new TimeoutException("The operation has timed out.");
}
}
finally
{
if (connection.IsOpen)
{
connection.Disconnect();
}
Monitor.Exit(node.BuildingMetadataLock);
}
}
else
{
throw new TimeoutException("The operation has timed out. Could not acquire the lock to build metadata for the node.");
}
}
}
}
}
}

View File

@@ -3,11 +3,9 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using System;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
namespace Microsoft.SqlTools.SqlCore.ObjectExplorer
{
/// <summary>
/// Indicates which type of server a given node type is valid for

View File

@@ -3,10 +3,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
namespace Microsoft.SqlTools.ServiceLayer.Utility
namespace Microsoft.SqlTools.SqlCore.Utility
{
/// <summary>
/// Common Constant values used across multiple services

View File

@@ -0,0 +1,27 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
namespace Microsoft.SqlTools.SqlCore.Utility
{
public static class DatabaseUtils
{
/// <summary>
/// Check if the database is a system database
/// </summary>
/// <param name="databaseName">the name of database</param>
/// <returns>return true if the database is a system database</returns>
public static bool IsSystemDatabaseConnection(string databaseName)
{
return (string.IsNullOrWhiteSpace(databaseName) ||
string.Compare(databaseName, CommonConstants.MasterDatabaseName, StringComparison.OrdinalIgnoreCase) == 0 ||
string.Compare(databaseName, CommonConstants.MsdbDatabaseName, StringComparison.OrdinalIgnoreCase) == 0 ||
string.Compare(databaseName, CommonConstants.ModelDatabaseName, StringComparison.OrdinalIgnoreCase) == 0 ||
string.Compare(databaseName, CommonConstants.TempDbDatabaseName, StringComparison.OrdinalIgnoreCase) == 0);
}
}
}

View File

@@ -0,0 +1,109 @@
//
// 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.Text;
namespace Microsoft.SqlTools.SqlCore.Utility
{
public class StringUtils
{
/// <summary>
/// Function doubles up specified character in a string
/// </summary>
/// <param name="s"></param>
/// <param name="cEsc"></param>
/// <returns></returns>
public static String EscapeString(string s, char cEsc)
{
if (string.IsNullOrWhiteSpace(s))
{
return s;
}
StringBuilder sb = new StringBuilder(s.Length * 2);
foreach (char c in s)
{
sb.Append(c);
if (cEsc == c)
sb.Append(c);
}
return sb.ToString();
}
/// <summary>
/// Function doubles up ']' character in a string
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static String EscapeStringCBracket(string s)
{
return EscapeString(s, ']');
}
/// <summary>
/// Function doubles up '\'' character in a string
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static String EscapeStringSQuote(string s)
{
return EscapeString(s, '\'');
}
/// <summary>
/// Function removes doubled up specified character from a string
/// </summary>
/// <param name="s"></param>
/// <param name="cEsc"></param>
/// <returns></returns>
public static String UnEscapeString(string s, char cEsc)
{
StringBuilder sb = new StringBuilder(s.Length);
bool foundBefore = false;
foreach (char c in s)
{
if (cEsc == c) // character to unescape
{
if (foundBefore) // skip second occurrence
{
foundBefore = false;
}
else // set the flag to skip next time around
{
sb.Append(c);
foundBefore = true;
}
}
else
{
sb.Append(c);
foundBefore = false;
}
}
return sb.ToString();
}
/// <summary>
/// Function removes doubled up ']' character from a string
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static String UnEscapeStringCBracket(string s)
{
return UnEscapeString(s, ']');
}
/// <summary>
/// Function removes doubled up '\'' character from a string
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static String UnEscapeStringSQuote(string s)
{
return UnEscapeString(s, '\'');
}
}
}