diff --git a/src/Microsoft.SqlTools.Hosting/Extensibility/ExtensionServiceProvider.cs b/src/Microsoft.SqlTools.Hosting/Extensibility/ExtensionServiceProvider.cs index 573b4a87..6d609fda 100644 --- a/src/Microsoft.SqlTools.Hosting/Extensibility/ExtensionServiceProvider.cs +++ b/src/Microsoft.SqlTools.Hosting/Extensibility/ExtensionServiceProvider.cs @@ -11,8 +11,6 @@ using System.Composition.Hosting; using System.IO; using System.Linq; using System.Reflection; -using System.Runtime.Loader; -using Microsoft.Extensions.DependencyModel; using Microsoft.SqlTools.Utility; namespace Microsoft.SqlTools.Extensibility @@ -53,7 +51,6 @@ namespace Microsoft.SqlTools.Extensibility string assemblyPath = typeof(ExtensionStore).GetTypeInfo().Assembly.Location; string directory = Path.GetDirectoryName(assemblyPath); - AssemblyLoadContext context = new AssemblyLoader(directory); var assemblyPaths = Directory.GetFiles(directory, "*.dll", SearchOption.TopDirectoryOnly); List assemblies = new List(); @@ -77,9 +74,7 @@ namespace Microsoft.SqlTools.Extensibility try { - assemblies.Add( - context.LoadFromAssemblyName( - AssemblyLoadContext.GetAssemblyName(path))); + assemblies.Add(Assembly.LoadFrom(path)); } catch (Exception) { @@ -193,7 +188,7 @@ namespace Microsoft.SqlTools.Extensibility try { Logger.Verbose("Loading service assembly: " + path); - assemblies.Add(AssemblyLoadContext.Default.LoadFromAssemblyPath(path)); + assemblies.Add(Assembly.LoadFrom(path)); Logger.Verbose("Loaded service assembly: " + path); } catch (Exception ex) @@ -281,13 +276,9 @@ namespace Microsoft.SqlTools.Extensibility public static ContainerConfiguration WithAssembliesInPath(this ContainerConfiguration configuration, string path, AttributedModelProvider conventions, SearchOption searchOption = SearchOption.TopDirectoryOnly) { - AssemblyLoadContext context = new AssemblyLoader(path); - var assemblyNames = Directory - .GetFiles(path, "*.dll", searchOption) - .Select(AssemblyLoadContext.GetAssemblyName); - - var assemblies = assemblyNames - .Select(context.LoadFromAssemblyName) + var assemblyPaths = Directory.GetFiles(path, "*.dll", SearchOption.TopDirectoryOnly); + var assemblies = assemblyPaths + .Select(path => Assembly.LoadFrom(path)) .ToList(); configuration = configuration.WithAssemblies(assemblies, conventions); @@ -295,37 +286,4 @@ namespace Microsoft.SqlTools.Extensibility return configuration; } } - - public class AssemblyLoader : AssemblyLoadContext - { - private string folderPath; - - public AssemblyLoader(string folderPath) - { - this.folderPath = folderPath; - } - - protected override Assembly Load(AssemblyName assemblyName) - { - var deps = DependencyContext.Default; - var res = deps.CompileLibraries.Where(d => d.Name.Equals(assemblyName.Name)).ToList(); - if (res.Count > 0) - { - return Assembly.Load(new AssemblyName(res.First().Name)); - } - else - { - var apiApplicationFileInfo = new FileInfo($"{folderPath}{Path.DirectorySeparatorChar}{assemblyName.Name}.dll"); - if (File.Exists(apiApplicationFileInfo.FullName)) - { - // Creating a new AssemblyContext instance for the same folder puts us at risk - // of loading the same DLL in multiple contexts, which leads to some unpredictable - // behavior in the loader. See https://github.com/dotnet/coreclr/issues/19632 - - return LoadFromAssemblyPath(apiApplicationFileInfo.FullName); - } - } - return Assembly.Load(assemblyName); - } - } } diff --git a/src/Microsoft.SqlTools.ManagedBatchParser/Microsoft.SqlTools.ManagedBatchParser.csproj b/src/Microsoft.SqlTools.ManagedBatchParser/Microsoft.SqlTools.ManagedBatchParser.csproj index c76a9704..8b400265 100644 --- a/src/Microsoft.SqlTools.ManagedBatchParser/Microsoft.SqlTools.ManagedBatchParser.csproj +++ b/src/Microsoft.SqlTools.ManagedBatchParser/Microsoft.SqlTools.ManagedBatchParser.csproj @@ -2,7 +2,7 @@ - net7.0;net472 + net7.0;net472;netstandard2.0 9.0 disable Microsoft.SqlTools.ManagedBatchParser @@ -37,7 +37,6 @@ version=$(PackageVersion) $(NoWarn);CA1852 - net7.0 diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/AgentNotebookHelper.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/AgentNotebookHelper.cs index b42d7c64..6b832700 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/AgentNotebookHelper.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/AgentNotebookHelper.cs @@ -16,6 +16,7 @@ using Microsoft.SqlTools.ServiceLayer.Agent.Contracts; using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlServer.Management.Smo.Agent; using Microsoft.SqlTools.ServiceLayer.Management; +using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection; namespace Microsoft.SqlTools.ServiceLayer.Agent { @@ -43,7 +44,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent } using (SqlConnection connection = new SqlConnection(ConnectionService.BuildConnectionString(connInfo.ConnectionDetails))) { - connection.RetryLogicProvider = Connection.ReliableConnection.SqlRetryProviders.ServerlessDBRetryProvider(); + connection.RetryLogicProvider = SqlRetryProviders.ServerlessDBRetryProvider(); connection.Open(); using (SqlCommand sqlQueryCommand = new SqlCommand(sqlQuery, connection)) { diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs index 179ec783..30a1a759 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs @@ -821,22 +821,6 @@ namespace Microsoft.SqlTools.ServiceLayer } } - public static string ScriptingParams_ConnectionString_Property_Invalid - { - get - { - return Keys.GetString(Keys.ScriptingParams_ConnectionString_Property_Invalid); - } - } - - public static string ScriptingParams_FilePath_Property_Invalid - { - get - { - return Keys.GetString(Keys.ScriptingParams_FilePath_Property_Invalid); - } - } - public static string ScriptingListObjectsCompleteParams_ConnectionString_Property_Invalid { get @@ -845,30 +829,6 @@ namespace Microsoft.SqlTools.ServiceLayer } } - public static string StoredProcedureScriptParameterComment - { - get - { - return Keys.GetString(Keys.StoredProcedureScriptParameterComment); - } - } - - public static string ScriptingGeneralError - { - get - { - return Keys.GetString(Keys.ScriptingGeneralError); - } - } - - public static string ScriptingExecuteNotSupportedError - { - get - { - return Keys.GetString(Keys.ScriptingExecuteNotSupportedError); - } - } - public static string BackupTaskName { get @@ -11651,24 +11611,9 @@ namespace Microsoft.SqlTools.ServiceLayer public const string SqlScriptFormatterScalarTypeMissingScale = "SqlScriptFormatterScalarTypeMissingScale"; - public const string ScriptingParams_ConnectionString_Property_Invalid = "ScriptingParams_ConnectionString_Property_Invalid"; - - - public const string ScriptingParams_FilePath_Property_Invalid = "ScriptingParams_FilePath_Property_Invalid"; - - public const string ScriptingListObjectsCompleteParams_ConnectionString_Property_Invalid = "ScriptingListObjectsCompleteParams_ConnectionString_Property_Invalid"; - public const string StoredProcedureScriptParameterComment = "StoredProcedureScriptParameterComment"; - - - public const string ScriptingGeneralError = "ScriptingGeneralError"; - - - public const string ScriptingExecuteNotSupportedError = "ScriptingExecuteNotSupportedError"; - - public const string BackupTaskName = "BackupTaskName"; diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx index 9728be04..1c61994c 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx @@ -678,30 +678,10 @@ Scalar column missing scale - - Error parsing ScriptingParams.ConnectionString property. - - - - Invalid directory specified by the ScriptingParams.FilePath property. - - Error parsing ScriptingListObjectsCompleteParams.ConnectionString property. - - -- TODO: Set parameter values here. - - - - An error occurred while scripting the objects. - - - - Scripting as Execute is only supported for Stored Procedures - - Backup Database diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings index 1d556f87..ac181ec3 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings @@ -330,19 +330,8 @@ SqlScriptFormatterScalarTypeMissingScale = Scalar column missing scale ############################################################################ # Scripting Service -ScriptingParams_ConnectionString_Property_Invalid = Error parsing ScriptingParams.ConnectionString property. - -ScriptingParams_FilePath_Property_Invalid = Invalid directory specified by the ScriptingParams.FilePath property. - ScriptingListObjectsCompleteParams_ConnectionString_Property_Invalid = Error parsing ScriptingListObjectsCompleteParams.ConnectionString property. - -StoredProcedureScriptParameterComment = -- TODO: Set parameter values here. - -ScriptingGeneralError = An error occurred while scripting the objects. -ScriptingExecuteNotSupportedError = Scripting as Execute is only supported for Stored Procedures - - ############################################################################ # Backup Service BackupTaskName = Backup Database diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf index 1a037aef..fc751f35 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf @@ -457,21 +457,6 @@ Table or view requested for edit could not be found - - Error parsing ScriptingParams.ConnectionString property. - Error parsing ScriptingParams.ConnectionString property. - - - - Invalid directory specified by the ScriptingParams.FilePath property. - Invalid directory specified by the ScriptingParams.FilePath property. - - - - Error parsing ScriptingListObjectsCompleteParams.ConnectionString property. - Error parsing ScriptingListObjectsCompleteParams.ConnectionString property. - - Query has no results to return Query has no results to return @@ -688,21 +673,6 @@ Scalar column missing scale - - -- TODO: Set parameter values here. - -- TODO: Set parameter values here. - - - - An error occurred while scripting the objects. - An error occurred while scripting the objects. - - - - Scripting as Execute is only supported for Stored Procedures - Scripting as Execute is only supported for Stored Procedures - - EditData queries targeting multiple tables are not supported EditData queries targeting multiple tables are not supported @@ -7273,6 +7243,11 @@ The Query Processor estimates that implementing the following index could improv . Parameters: 0 - table (string) + + Error parsing ScriptingListObjectsCompleteParams.ConnectionString property. + Error parsing ScriptingListObjectsCompleteParams.ConnectionString property. + + \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingCancelRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingCancelRequest.cs index dd994842..b7d4bfcb 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingCancelRequest.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingCancelRequest.cs @@ -6,6 +6,7 @@ #nullable disable using Microsoft.SqlTools.Hosting.Protocol.Contracts; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts { diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingCompleteEvent.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingCompleteEvent.cs index af093cae..e56818db 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingCompleteEvent.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingCompleteEvent.cs @@ -5,41 +5,11 @@ #nullable disable - using Microsoft.SqlTools.Hosting.Protocol.Contracts; +using Microsoft.SqlTools.Hosting.Protocol.Contracts; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts { - /// - /// Parameters sent to when a scripting operation has completed. - /// - public class ScriptingCompleteParams : ScriptingEventParams - { - /// - /// Get or sets the error details for an error that occurred during the scripting operation. - /// - public string ErrorDetails { get; set; } - - /// - /// Get or sets the error message for an error that occurred during the scripting operation. - /// - public string ErrorMessage { get; set; } - - /// - /// Get or sets a value to indicate an error occurred during the scripting operation. - /// - public bool HasError { get; set; } - - /// - /// Get or sets a value to indicate the scripting operation was canceled. - /// - public bool Canceled { get; set; } - - /// - /// Get or sets a value to indicate the scripting operation successfully completed. - /// - public bool Success { get; set; } - } - /// /// Event sent to indicate a scripting operation has completed. /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingListObjectsEvent.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingListObjectsEvent.cs index 57f2c5a2..4e3d5261 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingListObjectsEvent.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingListObjectsEvent.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using Microsoft.SqlTools.Hosting.Protocol.Contracts; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts { diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingPlanNotificationEvent.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingPlanNotificationEvent.cs index 359a0f5d..a1371a0e 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingPlanNotificationEvent.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingPlanNotificationEvent.cs @@ -5,27 +5,11 @@ #nullable disable -using System.Collections.Generic; using Microsoft.SqlTools.Hosting.Protocol.Contracts; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts { - /// - /// Parameters to indicate the script operation has resolved the objects to be scripted. - /// - public class ScriptingPlanNotificationParams : ScriptingEventParams - { - /// - /// Gets or sets the list of database objects whose progress has changed. - /// - public List ScriptingObjects { get; set; } - - /// - /// Gets or sets the count of database objects whose progress has changed. - /// - public int Count { get; set; } - } - /// /// Event sent to indicate a script operation has determined which objects will be scripted. /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingProgressNotificationEvent.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingProgressNotificationEvent.cs index fbfc4458..aceb145c 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingProgressNotificationEvent.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingProgressNotificationEvent.cs @@ -6,48 +6,10 @@ #nullable disable using Microsoft.SqlTools.Hosting.Protocol.Contracts; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts { - /// - /// Parameters sent when a scripting operation has made progress. - /// - public class ScriptingProgressNotificationParams : ScriptingEventParams - { - /// - /// Gets or sets the scripting object whose progress has changed. - /// - public ScriptingObject ScriptingObject { get; set; } - - /// - /// Gets or sets the status of the scripting operation for the scripting object. - /// - /// - /// Values can be: 'Completed', 'Progress', and 'Error'. - /// - public string Status { get; set; } - - /// - /// Gets or count of completed scripting operations. - /// - public int CompletedCount { get; set; } - - /// - /// Gets this total count of objects to script. - /// - public int TotalCount { get; set; } - - /// - /// Gets or sets the error details if an error occurred scripting a database object. - /// - public string ErrorDetails { get; set; } - - /// - /// Get or sets the error message for an error that occurred scripting a database object. - /// - public string ErrorMessage { get; set; } - } - /// /// Event to indicate the scripting operation has made progress. /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingRequest.cs index 670e5e11..d79aa839 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingRequest.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingRequest.cs @@ -5,83 +5,11 @@ #nullable disable -using System.Collections.Generic; using Microsoft.SqlTools.Hosting.Protocol.Contracts; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts { - /// - /// Parameters for a script request. - /// - public class ScriptingParams - { - /// - /// Gets or sets the file path used when writing out the script. - /// - public string FilePath { get; set; } - - /// - /// Gets or sets whether scripting to a single file or file per object. - /// - public string ScriptDestination { get; set; } - - /// - /// Gets or sets connection string of the target database the scripting operation will run against. - /// - public string ConnectionString { get; set; } - - /// - /// Gets or sets a list of scripting objects to script. - /// - public List ScriptingObjects { get; set; } - - /// - /// Gets or sets a list of scripting object which specify the include criteria of objects to script. - /// - public List IncludeObjectCriteria { get; set; } - - /// - /// Gets or sets a list of scripting object which specify the exclude criteria of objects to not script. - /// - public List ExcludeObjectCriteria { get; set; } - - /// - /// Gets or sets a list of schema name of objects to script. - /// - public List IncludeSchemas { get; set; } - - /// - /// Gets or sets a list of schema name of objects to not script. - /// - public List ExcludeSchemas { get; set; } - - /// - /// Gets or sets a list of type name of objects to script. - /// - public List IncludeTypes { get; set; } - - /// - /// Gets or sets a list of type name of objects to not script - /// - public List ExcludeTypes { get; set; } - - /// - /// Gets or sets the scripting options. - /// - public ScriptOptions ScriptOptions { get; set; } - - /// - /// Gets or sets the connection owner URI - /// - public string OwnerUri { get; set; } - - /// - /// The script operation - /// - public ScriptingOperationType Operation { get; set; } = ScriptingOperationType.Create; - - } - /// /// Parameters returned from a script request. /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScripterCore.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScripterCore.cs index 4b044ec9..86d0db78 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScripterCore.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScripterCore.cs @@ -20,14 +20,13 @@ using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlTools.ServiceLayer.LanguageServices; using Microsoft.SqlTools.ServiceLayer.Utility; using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; -using Microsoft.SqlTools.ServiceLayer.Scripting.Contracts; using Microsoft.SqlTools.Utility; using ConnectionType = Microsoft.SqlTools.ServiceLayer.Connection.ConnectionType; using Location = Microsoft.SqlTools.ServiceLayer.Workspace.Contracts.Location; -using Microsoft.SqlServer.Management.Sdk.Sfc; -using System.Text; using System.Data; using Range = Microsoft.SqlTools.ServiceLayer.Workspace.Contracts.Range; +using Microsoft.SqlTools.SqlCore.Scripting; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; namespace Microsoft.SqlTools.ServiceLayer.Scripting { @@ -540,303 +539,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting } return false; } - - internal static class ScriptingGlobals - { - /// - /// Left delimiter for an named object - /// - public const char LeftDelimiter = '['; - - /// - /// right delimiter for a named object - /// - public const char RightDelimiter = ']'; - } - - internal static class ScriptingUtils - { - /// - /// Quote the name of a given sql object. - /// - /// object - /// quoted object name - internal static string QuoteObjectName(string sqlObject) - { - return QuoteObjectName(sqlObject, ']'); - } - - /// - /// Quotes the name of a given sql object - /// - /// object - /// quote to use - /// - internal static string QuoteObjectName(string sqlObject, char quote) - { - int len = sqlObject.Length; - StringBuilder result = new StringBuilder(sqlObject.Length); - for (int i = 0; i < len; i++) - { - if (sqlObject[i] == quote) - { - result.Append(quote); - } - result.Append(sqlObject[i]); - } - return result.ToString(); - } - - /// - /// Returns the value whether the server supports XTP or not s - internal static bool IsXTPSupportedOnServer(Server server) - { - bool isXTPSupported = false; - if (server.ConnectionContext.ExecuteScalar("SELECT SERVERPROPERTY('IsXTPSupported')") != DBNull.Value) - { - isXTPSupported = server.IsXTPSupported; - } - return isXTPSupported; - } - } - - internal static string SelectAllValuesFromTransmissionQueue(Urn urn) - { - string script = string.Empty; - StringBuilder selectQuery = new StringBuilder(); - - /* - SELECT TOP *, casted_message_body = - CASE MESSAGE_TYPE_NAME WHEN 'X' - THEN CAST(MESSAGE_BODY AS NVARCHAR(MAX)) - ELSE MESSAGE_BODY - END - FROM [new].[sys].[transmission_queue] - */ - selectQuery.Append("SELECT TOP (1000) "); - selectQuery.Append("*, casted_message_body = \r\nCASE message_type_name WHEN 'X' \r\n THEN CAST(message_body AS NVARCHAR(MAX)) \r\n ELSE message_body \r\nEND \r\n"); - - // from clause - selectQuery.Append("FROM "); - Urn dbUrn = urn; - - // database - while (dbUrn.Parent != null && dbUrn.Type != "Database") - { - dbUrn = dbUrn.Parent; - } - selectQuery.AppendFormat("{0}{1}{2}", - ScriptingGlobals.LeftDelimiter, - ScriptingUtils.QuoteObjectName(dbUrn.GetAttribute("Name"), ScriptingGlobals.RightDelimiter), - ScriptingGlobals.RightDelimiter); - //SYS - selectQuery.AppendFormat(".{0}sys{1}", - ScriptingGlobals.LeftDelimiter, - ScriptingGlobals.RightDelimiter); - //TRANSMISSION QUEUE - selectQuery.AppendFormat(".{0}transmission_queue{1}", - ScriptingGlobals.LeftDelimiter, - ScriptingGlobals.RightDelimiter); - - script = selectQuery.ToString(); - return script; - } - - internal static string SelectAllValues(Urn urn) - { - string script = string.Empty; - StringBuilder selectQuery = new StringBuilder(); - selectQuery.Append("SELECT TOP (1000) "); - selectQuery.Append("*, casted_message_body = \r\nCASE message_type_name WHEN 'X' \r\n THEN CAST(message_body AS NVARCHAR(MAX)) \r\n ELSE message_body \r\nEND \r\n"); - - // from clause - selectQuery.Append("FROM "); - Urn dbUrn = urn; - - // database - while (dbUrn.Parent != null && dbUrn.Type != "Database") - { - dbUrn = dbUrn.Parent; - } - selectQuery.AppendFormat("{0}{1}{2}", - ScriptingGlobals.LeftDelimiter, - ScriptingUtils.QuoteObjectName(dbUrn.GetAttribute("Name"), ScriptingGlobals.RightDelimiter), - ScriptingGlobals.RightDelimiter); - // schema - selectQuery.AppendFormat(".{0}{1}{2}", - ScriptingGlobals.LeftDelimiter, - ScriptingUtils.QuoteObjectName(urn.GetAttribute("Schema"), ScriptingGlobals.RightDelimiter), - ScriptingGlobals.RightDelimiter); - // object - selectQuery.AppendFormat(".{0}{1}{2}", - ScriptingGlobals.LeftDelimiter, - ScriptingUtils.QuoteObjectName(urn.GetAttribute("Name"), ScriptingGlobals.RightDelimiter), - ScriptingGlobals.RightDelimiter); - - //Adding no lock in the end. - selectQuery.AppendFormat(" WITH(NOLOCK)"); - - script = selectQuery.ToString(); - return script; - } - - internal DataTable GetColumnNames(Server server, Urn urn, bool isDw) - { - List filterExpressions = new List(); - if (server.Version.Major >= 10) - { - // We don't have to include sparce columns as all the sparce columns data. - // Can be obtain from column set columns. - filterExpressions.Add("@IsSparse=0"); - } - - // Check if we're called for EDIT for SQL2016+/Sterling+. - // We need to omit temporal columns if such are present on this table. - if (server.Version.Major >= 13 || (DatabaseEngineType.SqlAzureDatabase == server.DatabaseEngineType && server.Version.Major >= 12 && !isDw)) - { - // We're called in order to generate a list of columns for EDIT TOP N rows. - // Don't return auto-generated, auto-populated, read-only temporal columns. - filterExpressions.Add("@GeneratedAlwaysType=0"); - } - - // Check if we're called for EDIT for SQL2022+/Sterling+. - // We need to omit dropped ledger columns if such are present - if (server.Version.Major >= 16 || (DatabaseEngineType.SqlAzureDatabase == server.DatabaseEngineType && server.Version.Major >= 12 && !isDw)) - { - filterExpressions.Add("@IsDroppedLedgerColumn=0"); - } - - // Check if we're called for SQL2017/Sterling+. - // We need to omit graph internal columns if such are present on this table. - if (server.Version.Major >= 14 || (DatabaseEngineType.SqlAzureDatabase == server.DatabaseEngineType && !isDw)) - { - // from Smo.GraphType: - // 0 = None - // 1 = GraphId - // 2 = GraphIdComputed - // 3 = GraphFromId - // 4 = GraphFromObjId - // 5 = GraphFromIdComputed - // 6 = GraphToId - // 7 = GraphToObjId - // 8 = GraphToIdComputed - // - // We only want to show types 0, 2, 5, and 8: - filterExpressions.Add("(@GraphType=0 or @GraphType=2 or @GraphType=5 or @GraphType=8)"); - } - - Request request = new Request(); - // If we have any filters on the columns, add them. - if (filterExpressions.Count > 0) - { - request.Urn = String.Format("{0}/Column[{1}]", urn.ToString(), string.Join(" and ", filterExpressions.ToArray())); - } - else - { - request.Urn = String.Format("{0}/Column", urn.ToString()); - } - - request.Fields = new String[] { "Name" }; - - // get the columns in the order they were created - OrderBy order = new OrderBy(); - order.Dir = OrderBy.Direction.Asc; - order.Field = "ID"; - request.OrderByList = new OrderBy[] { order }; - - Enumerator en = new Enumerator(); - - // perform the query. - DataTable dt = null; - EnumResult result = en.Process(server.ConnectionContext, request); - - if (result.Type == ResultType.DataTable) - { - dt = result; - } - else - { - dt = ((DataSet)result).Tables[0]; - } - return dt; - } - - internal string SelectFromTableOrView(Server server, Urn urn, bool isDw) - { - DataTable dt = GetColumnNames(server, urn, isDw); - StringBuilder selectQuery = new StringBuilder(); - - // build the first line - if (dt != null && dt.Rows.Count > 0) - { - - selectQuery.Append("SELECT TOP (1000) "); - - // first column - selectQuery.AppendFormat("{0}{1}{2}\r\n", - ScriptingGlobals.LeftDelimiter, - ScriptingUtils.QuoteObjectName(dt.Rows[0][0] as string, ScriptingGlobals.RightDelimiter), - ScriptingGlobals.RightDelimiter); - // add all other columns on separate lines. Make the names align. - for (int i = 1; i < dt.Rows.Count; i++) - { - selectQuery.AppendFormat(" ,{0}{1}{2}\r\n", - ScriptingGlobals.LeftDelimiter, - ScriptingUtils.QuoteObjectName(dt.Rows[i][0] as string, ScriptingGlobals.RightDelimiter), - ScriptingGlobals.RightDelimiter); - } - } - else - { - selectQuery.Append("SELECT TOP (1000) * "); - } - - // from clause - selectQuery.Append(" FROM "); - - if (server.ServerType != DatabaseEngineType.SqlAzureDatabase) - { - // Azure doesn't allow qualifying object names with the DB, so only add it on if we're not in Azure database URN - Urn dbUrn = urn.Parent; - selectQuery.AppendFormat("{0}{1}{2}.", - ScriptingGlobals.LeftDelimiter, - ScriptingUtils.QuoteObjectName(dbUrn.GetAttribute("Name"), ScriptingGlobals.RightDelimiter), - ScriptingGlobals.RightDelimiter); - } - - // schema - selectQuery.AppendFormat("{0}{1}{2}.", - ScriptingGlobals.LeftDelimiter, - ScriptingUtils.QuoteObjectName(urn.GetAttribute("Schema"), ScriptingGlobals.RightDelimiter), - ScriptingGlobals.RightDelimiter); - // object - selectQuery.AppendFormat("{0}{1}{2}", - ScriptingGlobals.LeftDelimiter, - ScriptingUtils.QuoteObjectName(urn.GetAttribute("Name"), ScriptingGlobals.RightDelimiter), - ScriptingGlobals.RightDelimiter); - - // In Hekaton M5, if it's a memory optimized table, we need to provide SNAPSHOT hint for SELECT. - if (urn.Type.Equals("Table") && ScriptingUtils.IsXTPSupportedOnServer(server)) - { - try - { - Table table = (Table)server.GetSmoObject(urn); - table.Refresh(); - if (table.IsMemoryOptimized) - { - selectQuery.Append(" WITH (SNAPSHOT)"); - } - } - catch (Exception ex) - { - // log any exceptions determining if InMemory, but don't treat as fatal exception - Logger.Error("Could not determine if is InMemory table " + ex.ToString()); - } - } - - return selectQuery.ToString(); - } - #endregion } } \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingListObjectsOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingListObjectsOperation.cs index 87a57a72..31c0b98f 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingListObjectsOperation.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingListObjectsOperation.cs @@ -10,6 +10,8 @@ using System.Collections.Generic; using Microsoft.Data.SqlClient; using Microsoft.SqlServer.Management.SqlScriptPublish; using Microsoft.SqlTools.ServiceLayer.Scripting.Contracts; +using Microsoft.SqlTools.SqlCore.Scripting; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; using Microsoft.SqlTools.Utility; namespace Microsoft.SqlTools.ServiceLayer.Scripting diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingObjectMatcher.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingObjectMatcher.cs index c8624eeb..838d881d 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingObjectMatcher.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingObjectMatcher.cs @@ -8,7 +8,7 @@ using System; using System.Collections.Generic; using System.Linq; -using Microsoft.SqlTools.ServiceLayer.Scripting.Contracts; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; using Microsoft.SqlTools.Utility; namespace Microsoft.SqlTools.ServiceLayer.Scripting diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingScriptOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingScriptOperation.cs index 64d360d1..3c1beed0 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingScriptOperation.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingScriptOperation.cs @@ -10,8 +10,9 @@ using System.Collections.Generic; using Microsoft.Data.SqlClient; using System.Linq; using Microsoft.SqlServer.Management.SqlScriptPublish; -using Microsoft.SqlTools.ServiceLayer.Scripting.Contracts; using Microsoft.SqlTools.Utility; +using Microsoft.SqlTools.SqlCore.Scripting; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; namespace Microsoft.SqlTools.ServiceLayer.Scripting { diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingService.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingService.cs index e9f2f053..65229946 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingService.cs @@ -18,6 +18,8 @@ using Microsoft.SqlTools.Utility; using Microsoft.SqlTools.ServiceLayer.Utility; using static Microsoft.SqlTools.Utility.SqlConstants; using System.Linq; +using Microsoft.SqlTools.SqlCore.Scripting; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; namespace Microsoft.SqlTools.ServiceLayer.Scripting { diff --git a/src/Microsoft.SqlTools.SqlCore/Localization/sr.cs b/src/Microsoft.SqlTools.SqlCore/Localization/sr.cs index 23cd31ff..125217cf 100644 --- a/src/Microsoft.SqlTools.SqlCore/Localization/sr.cs +++ b/src/Microsoft.SqlTools.SqlCore/Localization/sr.cs @@ -1725,6 +1725,54 @@ namespace Microsoft.SqlTools.SqlCore } } + public static string ScriptingParams_ConnectionString_Property_Invalid + { + get + { + return Keys.GetString(Keys.ScriptingParams_ConnectionString_Property_Invalid); + } + } + + public static string ScriptingParams_FilePath_Property_Invalid + { + get + { + return Keys.GetString(Keys.ScriptingParams_FilePath_Property_Invalid); + } + } + + public static string ScriptingListObjectsCompleteParams_ConnectionString_Property_Invalid + { + get + { + return Keys.GetString(Keys.ScriptingListObjectsCompleteParams_ConnectionString_Property_Invalid); + } + } + + public static string StoredProcedureScriptParameterComment + { + get + { + return Keys.GetString(Keys.StoredProcedureScriptParameterComment); + } + } + + public static string ScriptingGeneralError + { + get + { + return Keys.GetString(Keys.ScriptingGeneralError); + } + } + + public static string ScriptingExecuteNotSupportedError + { + get + { + return Keys.GetString(Keys.ScriptingExecuteNotSupportedError); + } + } + [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class Keys { @@ -2369,6 +2417,24 @@ namespace Microsoft.SqlTools.SqlCore public const string FilterInPrimaryKeyDescription = "FilterInPrimaryKeyDescription"; + public const string ScriptingParams_ConnectionString_Property_Invalid = "ScriptingParams_ConnectionString_Property_Invalid"; + + + public const string ScriptingParams_FilePath_Property_Invalid = "ScriptingParams_FilePath_Property_Invalid"; + + + public const string ScriptingListObjectsCompleteParams_ConnectionString_Property_Invalid = "ScriptingListObjectsCompleteParams_ConnectionString_Property_Invalid"; + + + public const string StoredProcedureScriptParameterComment = "StoredProcedureScriptParameterComment"; + + + public const string ScriptingGeneralError = "ScriptingGeneralError"; + + + public const string ScriptingExecuteNotSupportedError = "ScriptingExecuteNotSupportedError"; + + private Keys() { } diff --git a/src/Microsoft.SqlTools.SqlCore/Localization/sr.resx b/src/Microsoft.SqlTools.SqlCore/Localization/sr.resx index 583aa54e..1b9592ae 100644 --- a/src/Microsoft.SqlTools.SqlCore/Localization/sr.resx +++ b/src/Microsoft.SqlTools.SqlCore/Localization/sr.resx @@ -965,4 +965,28 @@ Include or exclude objects based on whether the column is in a primary key. + + Error parsing ScriptingParams.ConnectionString property. + + + + Invalid directory specified by the ScriptingParams.FilePath property. + + + + Error parsing ScriptingListObjectsCompleteParams.ConnectionString property. + + + + -- TODO: Set parameter values here. + + + + An error occurred while scripting the objects. + + + + Scripting as Execute is only supported for Stored Procedures + + diff --git a/src/Microsoft.SqlTools.SqlCore/Localization/sr.strings b/src/Microsoft.SqlTools.SqlCore/Localization/sr.strings index 3d6f67e9..153960ec 100644 --- a/src/Microsoft.SqlTools.SqlCore/Localization/sr.strings +++ b/src/Microsoft.SqlTools.SqlCore/Localization/sr.strings @@ -430,3 +430,17 @@ FilterIsNativelyCompiledDescription = Include or exclude objects based on whethe FilterInPrimaryKey = In Primary Key FilterInPrimaryKeyDescription = Include or exclude objects based on whether the column is in a primary key. +############################################################################ +# Scripting Service + +ScriptingParams_ConnectionString_Property_Invalid = Error parsing ScriptingParams.ConnectionString property. + +ScriptingParams_FilePath_Property_Invalid = Invalid directory specified by the ScriptingParams.FilePath property. + +ScriptingListObjectsCompleteParams_ConnectionString_Property_Invalid = Error parsing ScriptingListObjectsCompleteParams.ConnectionString property. + + +StoredProcedureScriptParameterComment = -- TODO: Set parameter values here. + +ScriptingGeneralError = An error occurred while scripting the objects. +ScriptingExecuteNotSupportedError = Scripting as Execute is only supported for Stored Procedures diff --git a/src/Microsoft.SqlTools.SqlCore/Localization/sr.xlf b/src/Microsoft.SqlTools.SqlCore/Localization/sr.xlf index 8a1cb1df..19d37f5c 100644 --- a/src/Microsoft.SqlTools.SqlCore/Localization/sr.xlf +++ b/src/Microsoft.SqlTools.SqlCore/Localization/sr.xlf @@ -1062,6 +1062,36 @@ Schema and Data + + Error parsing ScriptingParams.ConnectionString property. + Error parsing ScriptingParams.ConnectionString property. + + + + Invalid directory specified by the ScriptingParams.FilePath property. + Invalid directory specified by the ScriptingParams.FilePath property. + + + + Error parsing ScriptingListObjectsCompleteParams.ConnectionString property. + Error parsing ScriptingListObjectsCompleteParams.ConnectionString property. + + + + -- TODO: Set parameter values here. + -- TODO: Set parameter values here. + + + + An error occurred while scripting the objects. + An error occurred while scripting the objects. + + + + Scripting as Execute is only supported for Stored Procedures + Scripting as Execute is only supported for Stored Procedures + + \ No newline at end of file diff --git a/src/Microsoft.SqlTools.SqlCore/Microsoft.SqlTools.SqlCore.csproj b/src/Microsoft.SqlTools.SqlCore/Microsoft.SqlTools.SqlCore.csproj index d3e0f9d9..f5a81e9e 100644 --- a/src/Microsoft.SqlTools.SqlCore/Microsoft.SqlTools.SqlCore.csproj +++ b/src/Microsoft.SqlTools.SqlCore/Microsoft.SqlTools.SqlCore.csproj @@ -26,6 +26,8 @@ + + @@ -41,7 +43,7 @@ - + true lib\ diff --git a/src/Microsoft.SqlTools.SqlCore/ObjectExplorer/StatelessObjectExplorer.cs b/src/Microsoft.SqlTools.SqlCore/ObjectExplorer/StatelessObjectExplorer.cs index 95e36f94..199a3ce7 100644 --- a/src/Microsoft.SqlTools.SqlCore/ObjectExplorer/StatelessObjectExplorer.cs +++ b/src/Microsoft.SqlTools.SqlCore/ObjectExplorer/StatelessObjectExplorer.cs @@ -10,11 +10,10 @@ 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 +namespace Microsoft.SqlTools.SqlCore.ObjectExplorer { /// /// 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. diff --git a/src/Microsoft.SqlTools.SqlCore/Scripting/AsyncScriptAsScriptingOperation.cs b/src/Microsoft.SqlTools.SqlCore/Scripting/AsyncScriptAsScriptingOperation.cs new file mode 100644 index 00000000..01477bdd --- /dev/null +++ b/src/Microsoft.SqlTools.SqlCore/Scripting/AsyncScriptAsScriptingOperation.cs @@ -0,0 +1,41 @@ +// +// 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.Tasks; +using Azure.Core; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; + +namespace Microsoft.SqlTools.SqlCore.Scripting +{ + public class AsyncScriptAsScriptingOperation + { + public static async Task GetScriptAsScript(ScriptingParams parameters, AccessToken? accessToken) + { + var scriptAsOperation = new ScriptAsScriptingOperation(parameters, accessToken?.Token); + TaskCompletionSource scriptAsTask = new TaskCompletionSource(); + + scriptAsOperation.CompleteNotification += (sender, args) => + { + if (args.HasError) + { + scriptAsTask.SetException(new Exception(args.ErrorMessage)); + } + scriptAsTask.SetResult(scriptAsOperation.ScriptText); + }; + + scriptAsOperation.ProgressNotification += (sender, args) => + { + if(args.ErrorMessage != null) + { + scriptAsTask.SetException(new Exception(args.ErrorMessage)); + } + }; + + scriptAsOperation.Execute(); + return await scriptAsTask.Task; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingCompleteParams.cs b/src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingCompleteParams.cs new file mode 100644 index 00000000..7020d3ee --- /dev/null +++ b/src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingCompleteParams.cs @@ -0,0 +1,38 @@ +// +// 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.Scripting.Contracts +{ + /// + /// Parameters sent to when a scripting operation has completed. + /// + public class ScriptingCompleteParams : ScriptingEventParams + { + /// + /// Get or sets the error details for an error that occurred during the scripting operation. + /// + public string ErrorDetails { get; set; } + + /// + /// Get or sets the error message for an error that occurred during the scripting operation. + /// + public string ErrorMessage { get; set; } + + /// + /// Get or sets a value to indicate an error occurred during the scripting operation. + /// + public bool HasError { get; set; } + + /// + /// Get or sets a value to indicate the scripting operation was canceled. + /// + public bool Canceled { get; set; } + + /// + /// Get or sets a value to indicate the scripting operation successfully completed. + /// + public bool Success { get; set; } + } +} diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingEventParams.cs b/src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingEventParams.cs similarity index 90% rename from src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingEventParams.cs rename to src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingEventParams.cs index afc4d5ef..24b4dc02 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingEventParams.cs +++ b/src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingEventParams.cs @@ -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.Scripting.Contracts +namespace Microsoft.SqlTools.SqlCore.Scripting.Contracts { /// /// Base class for all scripting event parameters. diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingObject.cs b/src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingObject.cs similarity index 97% rename from src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingObject.cs rename to src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingObject.cs index a84aa3ca..f8005f6e 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingObject.cs +++ b/src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingObject.cs @@ -3,11 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -#nullable disable - using System; -namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts +namespace Microsoft.SqlTools.SqlCore.Scripting.Contracts { /// /// Class to represent a database object that can be scripted. diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingOperationType.cs b/src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingOperationType.cs similarity index 87% rename from src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingOperationType.cs rename to src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingOperationType.cs index 25597ef0..af383371 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingOperationType.cs +++ b/src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingOperationType.cs @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts +namespace Microsoft.SqlTools.SqlCore.Scripting.Contracts { /// /// Scripting Operation type diff --git a/src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingParams.cs b/src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingParams.cs new file mode 100644 index 00000000..21d968c8 --- /dev/null +++ b/src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingParams.cs @@ -0,0 +1,81 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System.Collections.Generic; + +namespace Microsoft.SqlTools.SqlCore.Scripting.Contracts +{ + /// + /// Parameters for a script request. + /// + public class ScriptingParams + { + /// + /// Gets or sets the file path used when writing out the script. + /// + public string FilePath { get; set; } + + /// + /// Gets or sets whether scripting to a single file or file per object. + /// + public string ScriptDestination { get; set; } + + /// + /// Gets or sets connection string of the target database the scripting operation will run against. + /// + public string ConnectionString { get; set; } + + /// + /// Gets or sets a list of scripting objects to script. + /// + public List ScriptingObjects { get; set; } + + /// + /// Gets or sets a list of scripting object which specify the include criteria of objects to script. + /// + public List IncludeObjectCriteria { get; set; } + + /// + /// Gets or sets a list of scripting object which specify the exclude criteria of objects to not script. + /// + public List ExcludeObjectCriteria { get; set; } + + /// + /// Gets or sets a list of schema name of objects to script. + /// + public List IncludeSchemas { get; set; } + + /// + /// Gets or sets a list of schema name of objects to not script. + /// + public List ExcludeSchemas { get; set; } + + /// + /// Gets or sets a list of type name of objects to script. + /// + public List IncludeTypes { get; set; } + + /// + /// Gets or sets a list of type name of objects to not script + /// + public List ExcludeTypes { get; set; } + + /// + /// Gets or sets the scripting options. + /// + public ScriptOptions ScriptOptions { get; set; } + + /// + /// Gets or sets the connection owner URI + /// + public string OwnerUri { get; set; } + + /// + /// The script operation + /// + public ScriptingOperationType Operation { get; set; } = ScriptingOperationType.Create; + + } +} diff --git a/src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingPlanNotificationParams.cs b/src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingPlanNotificationParams.cs new file mode 100644 index 00000000..98ccf7d3 --- /dev/null +++ b/src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingPlanNotificationParams.cs @@ -0,0 +1,25 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System.Collections.Generic; + +namespace Microsoft.SqlTools.SqlCore.Scripting.Contracts +{ + /// + /// Parameters to indicate the script operation has resolved the objects to be scripted. + /// + public class ScriptingPlanNotificationParams : ScriptingEventParams + { + /// + /// Gets or sets the list of database objects whose progress has changed. + /// + public List ScriptingObjects { get; set; } + + /// + /// Gets or sets the count of database objects whose progress has changed. + /// + public int Count { get; set; } + } +} diff --git a/src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingProgressNotificationParams.cs b/src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingProgressNotificationParams.cs new file mode 100644 index 00000000..386b3df9 --- /dev/null +++ b/src/Microsoft.SqlTools.SqlCore/Scripting/Contracts/ScriptingProgressNotificationParams.cs @@ -0,0 +1,46 @@ +// +// 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.Scripting.Contracts +{ + /// + /// Parameters sent when a scripting operation has made progress. + /// + public class ScriptingProgressNotificationParams : ScriptingEventParams + { + /// + /// Gets or sets the scripting object whose progress has changed. + /// + public ScriptingObject ScriptingObject { get; set; } + + /// + /// Gets or sets the status of the scripting operation for the scripting object. + /// + /// + /// Values can be: 'Completed', 'Progress', and 'Error'. + /// + public string Status { get; set; } + + /// + /// Gets or count of completed scripting operations. + /// + public int CompletedCount { get; set; } + + /// + /// Gets this total count of objects to script. + /// + public int TotalCount { get; set; } + + /// + /// Gets or sets the error details if an error occurred scripting a database object. + /// + public string ErrorDetails { get; set; } + + /// + /// Get or sets the error message for an error that occurred scripting a database object. + /// + public string ErrorMessage { get; set; } + } +} diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptAsOptions.cs b/src/Microsoft.SqlTools.SqlCore/Scripting/ScriptAsOptions.cs similarity index 99% rename from src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptAsOptions.cs rename to src/Microsoft.SqlTools.SqlCore/Scripting/ScriptAsOptions.cs index 51429e52..06cedcb6 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptAsOptions.cs +++ b/src/Microsoft.SqlTools.SqlCore/Scripting/ScriptAsOptions.cs @@ -3,12 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -#nullable disable - -using Microsoft.SqlTools.ServiceLayer.Scripting.Contracts; using Microsoft.SqlTools.Utility; -namespace Microsoft.SqlTools.ServiceLayer.Scripting +namespace Microsoft.SqlTools.SqlCore.Scripting { /// /// A wrpaper of ScriptOptions to map the option name with the oen in SMO.ScriptingOptions diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptAsScriptingOperation.cs b/src/Microsoft.SqlTools.SqlCore/Scripting/ScriptAsScriptingOperation.cs similarity index 95% rename from src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptAsScriptingOperation.cs rename to src/Microsoft.SqlTools.SqlCore/Scripting/ScriptAsScriptingOperation.cs index c92755a0..8a9809fb 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptAsScriptingOperation.cs +++ b/src/Microsoft.SqlTools.SqlCore/Scripting/ScriptAsScriptingOperation.cs @@ -3,8 +3,6 @@ // 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.Specialized; @@ -15,12 +13,13 @@ 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.ServiceLayer.Connection.ReliableConnection; using Microsoft.SqlTools.SqlCore.Connection; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; using Microsoft.SqlTools.SqlCore.Utility; using Microsoft.SqlTools.Utility; -namespace Microsoft.SqlTools.ServiceLayer.Scripting +namespace Microsoft.SqlTools.SqlCore.Scripting { /// /// Class to generate script as for one smo object @@ -47,7 +46,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting public ScriptAsScriptingOperation(ScriptingParams parameters, string azureAccountToken) : base(parameters) { SqlConnection sqlConnection = new SqlConnection(this.Parameters.ConnectionString); - sqlConnection.RetryLogicProvider = Connection.ReliableConnection.SqlRetryProviders.ServerlessDBRetryProvider(); + sqlConnection.RetryLogicProvider = SqlRetryProviders.ServerlessDBRetryProvider(); if (azureAccountToken != null) { sqlConnection.AccessToken = azureAccountToken; @@ -176,14 +175,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting // select from service broker if (string.Compare(typeName, "ServiceBroker", StringComparison.CurrentCultureIgnoreCase) == 0) { - script = Scripter.SelectAllValuesFromTransmissionQueue(objectUrn); + script = ScriptingHelper.SelectAllValuesFromTransmissionQueue(objectUrn); } // select from queues else if (string.Compare(typeName, "Queues", StringComparison.CurrentCultureIgnoreCase) == 0 || string.Compare(typeName, "SystemQueues", StringComparison.CurrentCultureIgnoreCase) == 0) { - script = Scripter.SelectAllValues(objectUrn); + script = ScriptingHelper.SelectAllValues(objectUrn); } // select from table or view @@ -191,7 +190,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting { Database db = server.Databases[databaseName]; bool isDw = db.IsSqlDw; - script = new Scripter().SelectFromTableOrView(server, objectUrn, isDw); + script = ScriptingHelper.SelectFromTableOrView(server, objectUrn, isDw); } return script; @@ -589,10 +588,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting // for cloud scripting to work we also have to have Script Compat set to 105. // the defaults from scripting options should take care of it - object targetDatabaseEngineType; - if (Enum.TryParse(typeof(SqlScriptOptions.ScriptDatabaseEngineType), this.Parameters.ScriptOptions.TargetDatabaseEngineType, out targetDatabaseEngineType)) + SqlScriptOptions.ScriptDatabaseEngineType targetDatabaseEngineType; + if (Enum.TryParse(this.Parameters.ScriptOptions.TargetDatabaseEngineType, out targetDatabaseEngineType)) { - switch ((SqlScriptOptions.ScriptDatabaseEngineType)targetDatabaseEngineType) + switch (targetDatabaseEngineType) { case SqlScriptOptions.ScriptDatabaseEngineType.SingleInstance: scriptingOptions.TargetDatabaseEngineType = DatabaseEngineType.Standalone; @@ -603,10 +602,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting } } - object targetDatabaseEngineEdition; - if (Enum.TryParse(typeof(SqlScriptOptions.ScriptDatabaseEngineEdition), this.Parameters.ScriptOptions.TargetDatabaseEngineEdition, out targetDatabaseEngineEdition)) + SqlScriptOptions.ScriptDatabaseEngineEdition targetDatabaseEngineEdition; + if (Enum.TryParse(this.Parameters.ScriptOptions.TargetDatabaseEngineEdition, out targetDatabaseEngineEdition)) { - switch ((SqlScriptOptions.ScriptDatabaseEngineEdition)targetDatabaseEngineEdition) + switch (targetDatabaseEngineEdition) { case SqlScriptOptions.ScriptDatabaseEngineEdition.SqlServerPersonalEdition: scriptingOptions.TargetDatabaseEngineEdition = DatabaseEngineEdition.Personal; @@ -650,10 +649,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting // scripting of stats is a combination of the Statistics // and the OptimizerData flag - object scriptStatistics; - if (Enum.TryParse(typeof(SqlScriptOptions.ScriptStatisticsOptions), this.Parameters.ScriptOptions.ScriptStatistics, out scriptStatistics)) + SqlScriptOptions.ScriptStatisticsOptions scriptStatistics; + if (Enum.TryParse(this.Parameters.ScriptOptions.ScriptStatistics, out scriptStatistics)) { - switch ((SqlScriptOptions.ScriptStatisticsOptions)scriptStatistics) + switch (scriptStatistics) { case SqlScriptOptions.ScriptStatisticsOptions.ScriptStatsAll: scriptingOptions.Statistics = true; diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingExtensionMethods.cs b/src/Microsoft.SqlTools.SqlCore/Scripting/ScriptingExtensionMethods.cs similarity index 97% rename from src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingExtensionMethods.cs rename to src/Microsoft.SqlTools.SqlCore/Scripting/ScriptingExtensionMethods.cs index 1782981e..521e0bac 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingExtensionMethods.cs +++ b/src/Microsoft.SqlTools.SqlCore/Scripting/ScriptingExtensionMethods.cs @@ -3,22 +3,20 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -#nullable disable - using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.SqlServer.Management.Sdk.Sfc; using Microsoft.SqlServer.Management.SqlScriptPublish; -using Microsoft.SqlTools.ServiceLayer.Scripting.Contracts; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; using Microsoft.SqlTools.Utility; -namespace Microsoft.SqlTools.ServiceLayer.Scripting +namespace Microsoft.SqlTools.SqlCore.Scripting { /// /// Extension methods used by the scripting service. /// - internal static class ScriptingExtensionMethods + public static class ScriptingExtensionMethods { /// /// Gets the status of a scripting operation for the passed scripting event. diff --git a/src/Microsoft.SqlTools.SqlCore/Scripting/ScriptingHelper.cs b/src/Microsoft.SqlTools.SqlCore/Scripting/ScriptingHelper.cs new file mode 100644 index 00000000..cf6f3f20 --- /dev/null +++ b/src/Microsoft.SqlTools.SqlCore/Scripting/ScriptingHelper.cs @@ -0,0 +1,318 @@ +// +// 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 System.Text; +using Microsoft.SqlServer.Management.Common; +using Microsoft.SqlServer.Management.Sdk.Sfc; +using Microsoft.SqlServer.Management.Smo; +using Microsoft.SqlTools.Utility; + +namespace Microsoft.SqlTools.SqlCore.Scripting +{ + /// + /// Helper class for scripting + /// + public static class ScriptingHelper + { + internal static string SelectAllValuesFromTransmissionQueue(Urn urn) + { + string script = string.Empty; + StringBuilder selectQuery = new StringBuilder(); + + /* + SELECT TOP *, casted_message_body = + CASE MESSAGE_TYPE_NAME WHEN 'X' + THEN CAST(MESSAGE_BODY AS NVARCHAR(MAX)) + ELSE MESSAGE_BODY + END + FROM [new].[sys].[transmission_queue] + */ + selectQuery.Append("SELECT TOP (1000) "); + selectQuery.Append("*, casted_message_body = \r\nCASE message_type_name WHEN 'X' \r\n THEN CAST(message_body AS NVARCHAR(MAX)) \r\n ELSE message_body \r\nEND \r\n"); + + // from clause + selectQuery.Append("FROM "); + Urn dbUrn = urn; + + // database + while (dbUrn.Parent != null && dbUrn.Type != "Database") + { + dbUrn = dbUrn.Parent; + } + selectQuery.AppendFormat("{0}{1}{2}", + ScriptingGlobals.LeftDelimiter, + QuoteObjectName(dbUrn.GetAttribute("Name"), ScriptingGlobals.RightDelimiter), + ScriptingGlobals.RightDelimiter); + //SYS + selectQuery.AppendFormat(".{0}sys{1}", + ScriptingGlobals.LeftDelimiter, + ScriptingGlobals.RightDelimiter); + //TRANSMISSION QUEUE + selectQuery.AppendFormat(".{0}transmission_queue{1}", + ScriptingGlobals.LeftDelimiter, + ScriptingGlobals.RightDelimiter); + + script = selectQuery.ToString(); + return script; + } + + internal static string SelectAllValues(Urn urn) + { + string script = string.Empty; + StringBuilder selectQuery = new StringBuilder(); + selectQuery.Append("SELECT TOP (1000) "); + selectQuery.Append("*, casted_message_body = \r\nCASE message_type_name WHEN 'X' \r\n THEN CAST(message_body AS NVARCHAR(MAX)) \r\n ELSE message_body \r\nEND \r\n"); + + // from clause + selectQuery.Append("FROM "); + Urn dbUrn = urn; + + // database + while (dbUrn.Parent != null && dbUrn.Type != "Database") + { + dbUrn = dbUrn.Parent; + } + selectQuery.AppendFormat("{0}{1}{2}", + ScriptingGlobals.LeftDelimiter, + QuoteObjectName(dbUrn.GetAttribute("Name"), ScriptingGlobals.RightDelimiter), + ScriptingGlobals.RightDelimiter); + // schema + selectQuery.AppendFormat(".{0}{1}{2}", + ScriptingGlobals.LeftDelimiter, + QuoteObjectName(urn.GetAttribute("Schema"), ScriptingGlobals.RightDelimiter), + ScriptingGlobals.RightDelimiter); + // object + selectQuery.AppendFormat(".{0}{1}{2}", + ScriptingGlobals.LeftDelimiter, + QuoteObjectName(urn.GetAttribute("Name"), ScriptingGlobals.RightDelimiter), + ScriptingGlobals.RightDelimiter); + + //Adding no lock in the end. + selectQuery.AppendFormat(" WITH(NOLOCK)"); + + script = selectQuery.ToString(); + return script; + } + + internal static class ScriptingGlobals + { + /// + /// Left delimiter for an named object + /// + public const char LeftDelimiter = '['; + + /// + /// right delimiter for a named object + /// + public const char RightDelimiter = ']'; + } + + + + static DataTable GetColumnNames(Server server, Urn urn, bool isDw) + { + List filterExpressions = new List(); + if (server.Version.Major >= 10) + { + // We don't have to include sparce columns as all the sparce columns data. + // Can be obtain from column set columns. + filterExpressions.Add("@IsSparse=0"); + } + + // Check if we're called for EDIT for SQL2016+/Sterling+. + // We need to omit temporal columns if such are present on this table. + if (server.Version.Major >= 13 || (DatabaseEngineType.SqlAzureDatabase == server.DatabaseEngineType && server.Version.Major >= 12 && !isDw)) + { + // We're called in order to generate a list of columns for EDIT TOP N rows. + // Don't return auto-generated, auto-populated, read-only temporal columns. + filterExpressions.Add("@GeneratedAlwaysType=0"); + } + + // Check if we're called for EDIT for SQL2022+/Sterling+. + // We need to omit dropped ledger columns if such are present + if (server.Version.Major >= 16 || (DatabaseEngineType.SqlAzureDatabase == server.DatabaseEngineType && server.Version.Major >= 12 && !isDw)) + { + filterExpressions.Add("@IsDroppedLedgerColumn=0"); + } + + // Check if we're called for SQL2017/Sterling+. + // We need to omit graph internal columns if such are present on this table. + if (server.Version.Major >= 14 || (DatabaseEngineType.SqlAzureDatabase == server.DatabaseEngineType && !isDw)) + { + // from Smo.GraphType: + // 0 = None + // 1 = GraphId + // 2 = GraphIdComputed + // 3 = GraphFromId + // 4 = GraphFromObjId + // 5 = GraphFromIdComputed + // 6 = GraphToId + // 7 = GraphToObjId + // 8 = GraphToIdComputed + // + // We only want to show types 0, 2, 5, and 8: + filterExpressions.Add("(@GraphType=0 or @GraphType=2 or @GraphType=5 or @GraphType=8)"); + } + + Request request = new Request(); + // If we have any filters on the columns, add them. + if (filterExpressions.Count > 0) + { + request.Urn = String.Format("{0}/Column[{1}]", urn.ToString(), string.Join(" and ", filterExpressions.ToArray())); + } + else + { + request.Urn = String.Format("{0}/Column", urn.ToString()); + } + + request.Fields = new String[] { "Name" }; + + // get the columns in the order they were created + OrderBy order = new OrderBy(); + order.Dir = OrderBy.Direction.Asc; + order.Field = "ID"; + request.OrderByList = new OrderBy[] { order }; + + Enumerator en = new Enumerator(); + + // perform the query. + DataTable? dt = null; + EnumResult result = en.Process(server.ConnectionContext, request); + + if (result.Type == ResultType.DataTable) + { + dt = result; + } + else + { + dt = ((DataSet)result).Tables[0]; + } + return dt; + } + + public static string SelectFromTableOrView(Server server, Urn urn, bool isDw) + { + DataTable dt = GetColumnNames(server, urn, isDw); + StringBuilder selectQuery = new StringBuilder(); + + // build the first line + if (dt != null && dt.Rows.Count > 0) + { + + selectQuery.Append("SELECT TOP (1000) "); + + // first column + selectQuery.AppendFormat("{0}{1}{2}\r\n", + ScriptingGlobals.LeftDelimiter, + QuoteObjectName(dt.Rows[0][0] as string, ScriptingGlobals.RightDelimiter), + ScriptingGlobals.RightDelimiter); + // add all other columns on separate lines. Make the names align. + for (int i = 1; i < dt.Rows.Count; i++) + { + selectQuery.AppendFormat(" ,{0}{1}{2}\r\n", + ScriptingGlobals.LeftDelimiter, + QuoteObjectName(dt.Rows[i][0] as string, ScriptingGlobals.RightDelimiter), + ScriptingGlobals.RightDelimiter); + } + } + else + { + selectQuery.Append("SELECT TOP (1000) * "); + } + + // from clause + selectQuery.Append(" FROM "); + + if (server.ServerType != DatabaseEngineType.SqlAzureDatabase) + { + // Azure doesn't allow qualifying object names with the DB, so only add it on if we're not in Azure database URN + Urn dbUrn = urn.Parent; + selectQuery.AppendFormat("{0}{1}{2}.", + ScriptingGlobals.LeftDelimiter, + QuoteObjectName(dbUrn.GetAttribute("Name"), ScriptingGlobals.RightDelimiter), + ScriptingGlobals.RightDelimiter); + } + + // schema + selectQuery.AppendFormat("{0}{1}{2}.", + ScriptingGlobals.LeftDelimiter, + QuoteObjectName(urn.GetAttribute("Schema"), ScriptingGlobals.RightDelimiter), + ScriptingGlobals.RightDelimiter); + // object + selectQuery.AppendFormat("{0}{1}{2}", + ScriptingGlobals.LeftDelimiter, + QuoteObjectName(urn.GetAttribute("Name"), ScriptingGlobals.RightDelimiter), + ScriptingGlobals.RightDelimiter); + + // In Hekaton M5, if it's a memory optimized table, we need to provide SNAPSHOT hint for SELECT. + if (urn.Type.Equals("Table") && IsXTPSupportedOnServer(server)) + { + try + { + Table table = (Table)server.GetSmoObject(urn); + table.Refresh(); + if (table.IsMemoryOptimized) + { + selectQuery.Append(" WITH (SNAPSHOT)"); + } + } + catch (Exception ex) + { + // log any exceptions determining if InMemory, but don't treat as fatal exception + Logger.Error("Could not determine if is InMemory table " + ex.ToString()); + } + } + + return selectQuery.ToString(); + } + + /// + /// Quote the name of a given sql object. + /// + /// object + /// quoted object name + internal static string QuoteObjectName(string sqlObject) + { + return QuoteObjectName(sqlObject, ']'); + } + + /// + /// Quotes the name of a given sql object + /// + /// object + /// quote to use + /// + internal static string QuoteObjectName(string sqlObject, char quote) + { + int len = sqlObject.Length; + StringBuilder result = new StringBuilder(sqlObject.Length); + for (int i = 0; i < len; i++) + { + if (sqlObject[i] == quote) + { + result.Append(quote); + } + result.Append(sqlObject[i]); + } + return result.ToString(); + } + + /// + /// Returns the value whether the server supports XTP or not s + internal static bool IsXTPSupportedOnServer(Server server) + { + bool isXTPSupported = false; + if (server.ConnectionContext.ExecuteScalar("SELECT SERVERPROPERTY('IsXTPSupported')") != DBNull.Value) + { + isXTPSupported = server.IsXTPSupported; + } + return isXTPSupported; + } + + } +} \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingOperation.cs b/src/Microsoft.SqlTools.SqlCore/Scripting/ScriptingOperation.cs similarity index 96% rename from src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingOperation.cs rename to src/Microsoft.SqlTools.SqlCore/Scripting/ScriptingOperation.cs index 173e538c..51ae9898 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingOperation.cs +++ b/src/Microsoft.SqlTools.SqlCore/Scripting/ScriptingOperation.cs @@ -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.Threading; using Microsoft.SqlTools.Utility; -namespace Microsoft.SqlTools.ServiceLayer.Scripting +namespace Microsoft.SqlTools.SqlCore.Scripting { /// /// Base class for scripting operations. Because scripting operations can be very long diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingOptions.cs b/src/Microsoft.SqlTools.SqlCore/Scripting/ScriptingOptions.cs similarity index 99% rename from src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingOptions.cs rename to src/Microsoft.SqlTools.SqlCore/Scripting/ScriptingOptions.cs index e989cca2..f43c7669 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingOptions.cs +++ b/src/Microsoft.SqlTools.SqlCore/Scripting/ScriptingOptions.cs @@ -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.Scripting.Contracts +namespace Microsoft.SqlTools.SqlCore.Scripting { /// /// Defines the scripting options. diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/SmoScriptingOperation.cs b/src/Microsoft.SqlTools.SqlCore/Scripting/SmoScriptingOperation.cs similarity index 96% rename from src/Microsoft.SqlTools.ServiceLayer/Scripting/SmoScriptingOperation.cs rename to src/Microsoft.SqlTools.SqlCore/Scripting/SmoScriptingOperation.cs index c7ea6cd3..f0d464e6 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/SmoScriptingOperation.cs +++ b/src/Microsoft.SqlTools.SqlCore/Scripting/SmoScriptingOperation.cs @@ -3,19 +3,18 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -#nullable disable - using System; using System.IO; using System.Reflection; using Microsoft.Data.SqlClient; using Microsoft.SqlServer.Management.Common; -using Microsoft.SqlTools.ServiceLayer.Scripting.Contracts; +using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection; using Microsoft.SqlTools.SqlCore.Connection; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; using Microsoft.SqlTools.Utility; using static Microsoft.SqlServer.Management.SqlScriptPublish.SqlScriptOptions; -namespace Microsoft.SqlTools.ServiceLayer.Scripting +namespace Microsoft.SqlTools.SqlCore.Scripting { /// /// Base class for all SMO scripting operations @@ -78,7 +77,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting string serverName = null; using (SqlConnection connection = new SqlConnection(connectionString)) { - connection.RetryLogicProvider = Connection.ReliableConnection.SqlRetryProviders.ServerlessDBRetryProvider(); + connection.RetryLogicProvider = SqlRetryProviders.ServerlessDBRetryProvider(); if (azureAccessToken != null) { connection.AccessToken = azureAccessToken; diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/StatelessObjectExplorerServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/StatelessObjectExplorerServiceTests.cs index 342869de..3c42704b 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/StatelessObjectExplorerServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/StatelessObjectExplorerServiceTests.cs @@ -7,9 +7,8 @@ using System; using System.Threading.Tasks; using NUnit.Framework; using Microsoft.SqlTools.ServiceLayer.Test.Common; -using Microsoft.SqlTools.CoreSql.ObjectExplorer; -using Microsoft.SqlTools.ServiceLayer.Test.Common.Extensions; using Microsoft.SqlTools.SqlCore.ObjectExplorer; +using Microsoft.SqlTools.ServiceLayer.Test.Common.Extensions; using System.Linq; namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Scripting/AsyncScriptAsScriptingOperationTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Scripting/AsyncScriptAsScriptingOperationTests.cs new file mode 100644 index 00000000..dab9366f --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Scripting/AsyncScriptAsScriptingOperationTests.cs @@ -0,0 +1,118 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + + +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.SqlTools.ServiceLayer.Test.Common; +using Microsoft.SqlTools.SqlCore.Scripting; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; +using NUnit.Framework; + +namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Scripting +{ + public class AsyncScriptAsScriptingOperationTests + { + public static IEnumerable ScriptAsTestCases + { + get + { + yield return new TestCaseData( + "CREATE TABLE testTable1 (c1 int)", + new ScriptingParams() + { + ScriptDestination = "ToEditor", + ScriptingObjects = new List() + { + new ScriptingObject() + { + Name = "testTable1", + Schema = "dbo", + Type = "Table", + + } + }, + Operation = ScriptingOperationType.Select, + ScriptOptions = new ScriptOptions() + { + ScriptCreateDrop = "ScriptSelect" + } + }, + new List() { "SELECT TOP (1000) [c1]" }); + + yield return new TestCaseData( + "CREATE TABLE testTable1 (c1 int)", + new ScriptingParams() + { + ScriptDestination = "ToEditor", + ScriptingObjects = new List() + { + new ScriptingObject() + { + Name = "testTable1", + Schema = "dbo", + Type = "Table" + } + }, + Operation = ScriptingOperationType.Delete, + ScriptOptions = new ScriptOptions() + { + ScriptCreateDrop = "ScriptDrop" + } + }, + new List { "DROP TABLE [dbo].[testTable1]" } + ); + + yield return new TestCaseData( + @"CREATE TABLE testTable1 (c1 int) + GO + CREATE CLUSTERED INDEX [ClusteredIndex-1] ON [dbo].[testTable1] + ( + [c1] ASC + ) + GO + ", + new ScriptingParams() + { + ScriptDestination = "ToEditor", + ScriptingObjects = new List() + { + new ScriptingObject() + { + Name = "testTable1", + Schema = "dbo", + Type = "Table" + } + }, + Operation = ScriptingOperationType.Create, + ScriptOptions = new ScriptOptions() + { + ScriptCreateDrop = "ScriptCreate" + } + }, + new List { "CREATE TABLE [dbo].[testTable1]", "CREATE CLUSTERED INDEX [ClusteredIndex-1] ON [dbo].[testTable1]" } + ); + } + } + + [Test] + [TestCaseSource("ScriptAsTestCases")] + public async Task TestCommonScenarios( + string query, ScriptingParams scriptingParams, List expectedScriptContents) + { + var testDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, query, "ScriptingTests"); + scriptingParams.ConnectionString = testDb.ConnectionString; + + var actualScript = await AsyncScriptAsScriptingOperation.GetScriptAsScript(scriptingParams, null); + + foreach(var expectedStr in expectedScriptContents) + { + Assert.That(actualScript, Does.Contain(expectedStr)); + } + + await testDb.CleanupAsync(); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Scripting/ScriptingServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Scripting/ScriptingServiceTests.cs index 1a5868ea..59ced76e 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Scripting/ScriptingServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Scripting/ScriptingServiceTests.cs @@ -19,6 +19,8 @@ using System.Threading; using System.Threading.Tasks; using NUnit.Framework; using static Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility.LiveConnectionHelper; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; +using Microsoft.SqlTools.SqlCore.Scripting; namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Scripting { diff --git a/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/ScriptinTests.cs b/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/ScriptinTests.cs index af2fa26f..463d8ee0 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/ScriptinTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/ScriptinTests.cs @@ -8,8 +8,9 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Threading.Tasks; -using Microsoft.SqlTools.ServiceLayer.Scripting.Contracts; using Microsoft.SqlTools.ServiceLayer.Test.Common; +using Microsoft.SqlTools.SqlCore.Scripting; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; using Xunit; namespace Microsoft.SqlTools.ServiceLayer.PerfTests diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestServiceDriverProvider.cs b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestServiceDriverProvider.cs index e60accd7..1a9dac15 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestServiceDriverProvider.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestServiceDriverProvider.cs @@ -20,6 +20,7 @@ using Microsoft.SqlTools.ServiceLayer.SqlContext; using Microsoft.SqlTools.ServiceLayer.TestDriver.Driver; using Microsoft.SqlTools.ServiceLayer.TestDriver.Utility; using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; using NUnit.Framework; namespace Microsoft.SqlTools.ServiceLayer.Test.Common diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/SqlScriptPublishModelTests.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/SqlScriptPublishModelTests.cs index 67eb6221..2bf8df06 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/SqlScriptPublishModelTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/SqlScriptPublishModelTests.cs @@ -12,6 +12,8 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.SqlTools.ServiceLayer.Scripting.Contracts; using Microsoft.SqlTools.ServiceLayer.Test.Common; +using Microsoft.SqlTools.SqlCore.Scripting; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; using NUnit.Framework; namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Scripting/ScriptingExtensionMethodsTests.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Scripting/ScriptingExtensionMethodsTests.cs index 834c6894..86dec0af 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Scripting/ScriptingExtensionMethodsTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Scripting/ScriptingExtensionMethodsTests.cs @@ -6,8 +6,8 @@ #nullable disable using Microsoft.SqlServer.Management.Sdk.Sfc; -using Microsoft.SqlTools.ServiceLayer.Scripting; -using Microsoft.SqlTools.ServiceLayer.Scripting.Contracts; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; +using Microsoft.SqlTools.SqlCore.Scripting; using NUnit.Framework; using Assert = NUnit.Framework.Assert; diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Scripting/ScriptingObjectMatcherTests.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Scripting/ScriptingObjectMatcherTests.cs index 25509714..b839ec15 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Scripting/ScriptingObjectMatcherTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Scripting/ScriptingObjectMatcherTests.cs @@ -8,7 +8,8 @@ using System.Collections.Generic; using System.Linq; using Microsoft.SqlTools.ServiceLayer.Scripting; -using Microsoft.SqlTools.ServiceLayer.Scripting.Contracts; +using Microsoft.SqlTools.SqlCore.Scripting; +using Microsoft.SqlTools.SqlCore.Scripting.Contracts; using NUnit.Framework; namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting @@ -451,7 +452,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Scripting { for (int i = 0; i < TestObjects.Length; i++) { - Assert.AreEqual(Scripter.ScriptingUtils.QuoteObjectName(TestObjects[i]), ExpectedObjects[i]); + Assert.AreEqual(ScriptingHelper.QuoteObjectName(TestObjects[i]), ExpectedObjects[i]); } } }