diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs index 5a96a6c7..735eed29 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs @@ -952,6 +952,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection serviceHost.SetRequestHandler(ListDatabasesRequest.Type, HandleListDatabasesRequest); serviceHost.SetRequestHandler(ChangeDatabaseRequest.Type, HandleChangeDatabaseRequest); serviceHost.SetRequestHandler(GetConnectionStringRequest.Type, HandleGetConnectionStringRequest); + serviceHost.SetRequestHandler(BuildConnectionInfoRequest.Type, HandleBuildConnectionInfoRequest); } /// @@ -1288,6 +1289,64 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection }); } + /// + /// Handles a request to serialize a connection string + /// + public async Task HandleBuildConnectionInfoRequest( + string connectionString, + RequestContext requestContext) + { + await Task.Run(async () => + { + try + { + await requestContext.SendResult(ParseConnectionString(connectionString)); + } + catch (Exception e) + { + // If theres an error in the parse, it means we just can't parse, so we return undefined + // rather than an error. + await requestContext.SendResult(null); + } + }); + } + + public ConnectionDetails ParseConnectionString(string connectionString) + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectionString); + ConnectionDetails details = new ConnectionDetails() + { + ApplicationIntent = builder.ApplicationIntent.ToString(), + ApplicationName = builder.ApplicationName, + AttachDbFilename = builder.AttachDBFilename, + AuthenticationType = builder.IntegratedSecurity ? "Integrated" : "SqlLogin", + ConnectRetryCount = builder.ConnectRetryCount, + ConnectRetryInterval = builder.ConnectRetryInterval, + ConnectTimeout = builder.ConnectTimeout, + CurrentLanguage = builder.CurrentLanguage, + DatabaseName = builder.InitialCatalog, + Encrypt = builder.Encrypt, + FailoverPartner = builder.FailoverPartner, + LoadBalanceTimeout = builder.LoadBalanceTimeout, + MaxPoolSize = builder.MaxPoolSize, + MinPoolSize = builder.MinPoolSize, + MultipleActiveResultSets = builder.MultipleActiveResultSets, + MultiSubnetFailover = builder.MultiSubnetFailover, + PacketSize = builder.PacketSize, + Password = !builder.IntegratedSecurity ? builder.Password : string.Empty, + PersistSecurityInfo = builder.PersistSecurityInfo, + Pooling = builder.Pooling, + Replication = builder.Replication, + ServerName = builder.DataSource, + TrustServerCertificate = builder.TrustServerCertificate, + TypeSystemVersion = builder.TypeSystemVersion, + UserName = builder.UserID, + WorkstationId = builder.WorkstationID, + }; + + return details; + } + /// /// Handles a request to change the database for a connection /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/BuildConnectionInfoRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/BuildConnectionInfoRequest.cs new file mode 100644 index 00000000..a301e179 --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/BuildConnectionInfoRequest.cs @@ -0,0 +1,19 @@ +// +// 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.Hosting.Protocol.Contracts; + +namespace Microsoft.SqlTools.ServiceLayer.Connection.Contracts +{ + /// + /// Serialize Connection String request + /// + public class BuildConnectionInfoRequest + { + public static readonly + RequestType Type = + RequestType.Create("connection/buildconnectioninfo"); + } +} diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Connection/ConnectionServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Connection/ConnectionServiceTests.cs index 36bd0e0d..505a19a8 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Connection/ConnectionServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Connection/ConnectionServiceTests.cs @@ -1460,5 +1460,29 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection Assert.Equal(defaultDbName, dbName); } + + /// + /// Test ParseConnectionString + /// + [Fact] + public void ParseConnectionStringTest() + { + // If we make a connection to a live database + ConnectionService service = ConnectionService.Instance; + + var connectionString = "Server=tcp:{servername},1433;Initial Catalog={databasename};Persist Security Info=False;User ID={your_username};Password={your_password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"; + + var details = service.ParseConnectionString(connectionString); + + Assert.Equal("tcp:{servername},1433", details.ServerName); + Assert.Equal("{databasename}", details.DatabaseName); + Assert.Equal("{your_username}", details.UserName); + Assert.Equal("{your_password}", details.Password); + Assert.Equal(false, details.PersistSecurityInfo); + Assert.Equal(false, details.MultipleActiveResultSets); + Assert.Equal(true, details.Encrypt); + Assert.Equal(false, details.TrustServerCertificate); + Assert.Equal(30, details.ConnectTimeout); + } } }