diff --git a/bin/nuget/Microsoft.SqlServer.Smo.140.2.8.nupkg b/bin/nuget/Microsoft.SqlServer.Smo.140.2.8.nupkg deleted file mode 100644 index e563c748..00000000 Binary files a/bin/nuget/Microsoft.SqlServer.Smo.140.2.8.nupkg and /dev/null differ diff --git a/bin/nuget/Microsoft.SqlServer.Smo.140.2.9.nupkg b/bin/nuget/Microsoft.SqlServer.Smo.140.2.9.nupkg new file mode 100644 index 00000000..3dc81063 Binary files /dev/null and b/bin/nuget/Microsoft.SqlServer.Smo.140.2.9.nupkg differ diff --git a/src/Microsoft.SqlTools.Credentials/Microsoft.SqlTools.Credentials.csproj b/src/Microsoft.SqlTools.Credentials/Microsoft.SqlTools.Credentials.csproj index e3a59613..56ee63af 100644 --- a/src/Microsoft.SqlTools.Credentials/Microsoft.SqlTools.Credentials.csproj +++ b/src/Microsoft.SqlTools.Credentials/Microsoft.SqlTools.Credentials.csproj @@ -19,7 +19,7 @@ - + diff --git a/src/Microsoft.SqlTools.ServiceLayer/Microsoft.SqlTools.ServiceLayer.csproj b/src/Microsoft.SqlTools.ServiceLayer/Microsoft.SqlTools.ServiceLayer.csproj index 5d8998f1..2138a933 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Microsoft.SqlTools.ServiceLayer.csproj +++ b/src/Microsoft.SqlTools.ServiceLayer/Microsoft.SqlTools.ServiceLayer.csproj @@ -18,8 +18,8 @@ - - + + diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingOperationType.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingOperationType.cs index c016e0bb..25597ef0 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingOperationType.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingOperationType.cs @@ -15,6 +15,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts Insert = 2, Update = 3, Delete = 4, - Execute = 5 + Execute = 5, + Alter = 6 } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptAsScriptingOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptAsScriptingOperation.cs index 9ec1c74a..3bbda445 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptAsScriptingOperation.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptAsScriptingOperation.cs @@ -87,6 +87,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting switch (this.Parameters.Operation) { case ScriptingOperationType.Create: + case ScriptingOperationType.Alter: case ScriptingOperationType.Delete: // Using Delete here is wrong. delete usually means delete rows from table but sqlopsstudio sending the operation name as delete instead of drop resultScript = GenerateScriptAs(server, urns, options); break; @@ -438,6 +439,17 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting try { scripter = new SqlServer.Management.Smo.Scripter(server); + if(this.Parameters.Operation == ScriptingOperationType.Alter) + { + options.ScriptForAlter = true; + foreach (var urn in urns) + { + SqlSmoObject smoObject = server.GetSmoObject(urn); + + // without calling the toch method, no alter script get generated from smo + smoObject.Touch(); + } + } scripter.Options = options; scripter.ScriptingError += ScripterScriptingError; diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingService.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingService.cs index 127ab1cf..820a330c 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptingService.cs @@ -163,7 +163,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting // To script Select, alter and execute use scripting as operation. The other operation doesn't support those types if( (parameters.ScriptingObjects != null && parameters.ScriptingObjects.Count == 1 && parameters.ScriptOptions != null && parameters.ScriptOptions.TypeOfDataToScript == "SchemaOnly" && parameters.ScriptDestination == "ToEditor") || - parameters.Operation == ScriptingOperationType.Select || parameters.Operation == ScriptingOperationType.Execute) + parameters.Operation == ScriptingOperationType.Select || parameters.Operation == ScriptingOperationType.Execute || + parameters.Operation == ScriptingOperationType.Alter) { return true; } diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Microsoft.SqlTools.ServiceLayer.IntegrationTests.csproj b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Microsoft.SqlTools.ServiceLayer.IntegrationTests.csproj index ff6f6404..3a434a77 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Microsoft.SqlTools.ServiceLayer.IntegrationTests.csproj +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Microsoft.SqlTools.ServiceLayer.IntegrationTests.csproj @@ -32,7 +32,7 @@ - + diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Scripting/ScriptingServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Scripting/ScriptingServiceTests.cs index 96daba75..d42f7606 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Scripting/ScriptingServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Scripting/ScriptingServiceTests.cs @@ -12,6 +12,7 @@ using Microsoft.SqlTools.ServiceLayer.Test.Common; using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; using Moq; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Xunit; @@ -113,10 +114,51 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Scripting Type = "Table" }; string expectedScript = null; - await VerifyScriptAs(query, scriptingObject, scriptCreateDrop, expectedScript); } + [Fact] + public async void VerifyScriptAsAlter() + { + string query = @"CREATE PROCEDURE testSp1 @StartProductID [int] AS BEGIN Select * from sys.all_columns END + GO + CREATE VIEW testView1 AS SELECT * from sys.all_columns + GO + CREATE FUNCTION testFun1() RETURNS [int] AS BEGIN RETURN 1 END + GO"; + ScriptingOperationType scriptCreateDrop = ScriptingOperationType.Alter; + + List scriptingObjects = new List + { + new ScriptingObject + { + Name = "testSp1", + Schema = "dbo", + Type = "StoredProcedure" + }, + new ScriptingObject + { + Name = "testView1", + Schema = "dbo", + Type = "View" + }, + new ScriptingObject + { + Name = "testFun1", + Schema = "dbo", + Type = "UserDefinedFunction" + } + }; + List expectedScripts = new List + { + "ALTER PROCEDURE [dbo].[testSp1]", + "ALTER VIEW [dbo].[testView1]", + "ALTER FUNCTION [dbo].[testFun1]" + }; + + await VerifyScriptAsForMultipleObjects(query, scriptingObjects, scriptCreateDrop, expectedScripts); + } + [Fact] public async void VerifyScriptAsExecuteStoredProcedure() { @@ -238,6 +280,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Scripting } private async Task VerifyScriptAs(string query, ScriptingObject scriptingObject, ScriptingOperationType operation, string expectedScript) + { + await VerifyScriptAsForMultipleObjects(query, new List { scriptingObject }, operation, new List { expectedScript }); + } + + private async Task VerifyScriptAsForMultipleObjects(string query, List scriptingObjects, ScriptingOperationType operation, List expectedScripts) { var testDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, query, "ScriptingTests"); try @@ -271,10 +318,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Scripting ScriptCreateDrop = scriptCreateOperation, }; - scriptingParams.ScriptingObjects = new List - { - scriptingObject - }; + scriptingParams.ScriptingObjects = scriptingObjects; ScriptingService service = new ScriptingService(); @@ -282,7 +326,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Scripting Thread.Sleep(2000); await service.ScriptingTask; - requestContext.Verify(x => x.SendResult(It.Is(r => VerifyScriptingResult(r, expectedScript)))); + requestContext.Verify(x => x.SendResult(It.Is(r => VerifyScriptingResult(r, expectedScripts)))); connectionService.Disconnect(new ServiceLayer.Connection.Contracts.DisconnectParams { OwnerUri = queryTempFile.FilePath @@ -299,9 +343,21 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Scripting } } - private static bool VerifyScriptingResult(ScriptingResult result, string expected) + private static bool VerifyScriptingResult(ScriptingResult result, List expectedScripts) { - return string.IsNullOrEmpty(expected) ? string.IsNullOrEmpty(result.Script) : !string.IsNullOrEmpty(result.Script) && result.Script.Contains(expected); + if (expectedScripts == null || (expectedScripts.Count > 0 && expectedScripts.All(x => x == null))) + { + return string.IsNullOrEmpty(result.Script); + } + + foreach (string expectedScript in expectedScripts) + { + if (!result.Script.Contains(expectedScript)) + { + return false; + } + } + return true; } } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/Microsoft.SqlTools.ServiceLayer.Test.Common.csproj b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/Microsoft.SqlTools.ServiceLayer.Test.Common.csproj index ba21b441..2916cc4a 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/Microsoft.SqlTools.ServiceLayer.Test.Common.csproj +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/Microsoft.SqlTools.ServiceLayer.Test.Common.csproj @@ -12,7 +12,7 @@ - + diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Microsoft.SqlTools.ServiceLayer.TestDriver.csproj b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Microsoft.SqlTools.ServiceLayer.TestDriver.csproj index 62e1d05e..b71e4b25 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Microsoft.SqlTools.ServiceLayer.TestDriver.csproj +++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Microsoft.SqlTools.ServiceLayer.TestDriver.csproj @@ -12,7 +12,7 @@ - + diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Microsoft.SqlTools.ServiceLayer.UnitTests.csproj b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Microsoft.SqlTools.ServiceLayer.UnitTests.csproj index f9fed1cb..8a4a0da7 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Microsoft.SqlTools.ServiceLayer.UnitTests.csproj +++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Microsoft.SqlTools.ServiceLayer.UnitTests.csproj @@ -13,7 +13,7 @@ - +