diff --git a/sqltoolsservice.sln b/sqltoolsservice.sln
index b993537f..828baca9 100644
--- a/sqltoolsservice.sln
+++ b/sqltoolsservice.sln
@@ -11,9 +11,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
global.json = global.json
EndProjectSection
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ServiceHost", "src\ServiceHost\ServiceHost.xproj", "{0D61DC2B-DA66-441D-B9D0-F76C98F780F9}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.SqlTools.ServiceLayer", "src\Microsoft.SqlTools.ServiceLayer\Microsoft.SqlTools.ServiceLayer.xproj", "{0D61DC2B-DA66-441D-B9D0-F76C98F780F9}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ServiceHost.Test", "test\ServiceHost.Test\ServiceHost.Test.xproj", "{2D771D16-9D85-4053-9F79-E2034737DEEF}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.SqlTools.ServiceLayer.Test", "test\Microsoft.SqlTools.ServiceLayer.Test\Microsoft.SqlTools.ServiceLayer.Test.xproj", "{2D771D16-9D85-4053-9F79-E2034737DEEF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/src/ServiceHost/ConnectionServices/ConnectionService.cs b/src/Microsoft.SqlTools.ServiceLayer/ConnectionServices/ConnectionService.cs
similarity index 68%
rename from src/ServiceHost/ConnectionServices/ConnectionService.cs
rename to src/Microsoft.SqlTools.ServiceLayer/ConnectionServices/ConnectionService.cs
index d7f11fe1..90b7c61f 100644
--- a/src/ServiceHost/ConnectionServices/ConnectionService.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/ConnectionServices/ConnectionService.cs
@@ -5,14 +5,14 @@
using System;
using System.Collections.Generic;
-using System.Data;
using System.Data.SqlClient;
-using System.Linq;
using System.Threading.Tasks;
using Microsoft.SqlTools.EditorServices.Utility;
+using Microsoft.SqlTools.ServiceLayer.ConnectionServices.Contracts;
using Microsoft.SqlTools.ServiceLayer.Hosting;
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
-using Microsoft.SqlTools.ServiceLayer.ConnectionServices.Contracts;
+using Microsoft.SqlTools.ServiceLayer.SqlContext;
+using Microsoft.SqlTools.ServiceLayer.WorkspaceServices;
namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices
{
@@ -56,12 +56,17 @@ namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices
///
private ISqlConnectionFactory connectionFactory;
+ ///
+ /// The current connection id that was previously used
+ ///
+ private int maxConnectionId = 0;
+
///
/// Active connections lazy dictionary instance
///
- private Lazy> activeConnections
- = new Lazy>(()
- => new Dictionary());
+ private Lazy> activeConnections
+ = new Lazy>(()
+ => new Dictionary());
///
/// Callback for onconnection handler
@@ -77,7 +82,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices
///
/// Gets the active connection map
///
- public Dictionary ActiveConnections
+ public Dictionary ActiveConnections
{
get
{
@@ -117,56 +122,40 @@ namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices
/// Open a connection with the specified connection details
///
///
- public async Task Connect(ConnectionDetails connectionDetails)
+ public ConnectionResult Connect(ConnectionDetails connectionDetails)
{
// build the connection string from the input parameters
string connectionString = BuildConnectionString(connectionDetails);
// create a sql connection instance
- ISqlConnection connection = ConnectionFactory.CreateSqlConnection(connectionString);
+ ISqlConnection connection = this.ConnectionFactory.CreateSqlConnection(connectionString);
// open the database
- await connection.OpenAsync();
+ connection.Open();
// map the connection id to the connection object for future lookups
- Guid connectionId = Guid.NewGuid();
- ActiveConnections.Add(connectionId, connection);
+ this.ActiveConnections.Add(++maxConnectionId, connection);
// invoke callback notifications
- var onConnectionCallbackTasks = onConnectionActivities.Select(t => t(connection));
- await Task.WhenAll(onConnectionCallbackTasks);
- // TODO: Evaulate if we want to avoid waiting here. We'll need error handling on the other side if we don't wait
+ foreach (var activity in this.onConnectionActivities)
+ {
+ activity(connection);
+ }
// return the connection result
- return new ConnectionResult
+ return new ConnectionResult()
{
- ConnectionId = connectionId
+ ConnectionId = maxConnectionId
};
}
- ///
- /// Closes an active connection and removes it from the active connections list
- ///
- /// ID of the connection to close
- public void Disconnect(Guid connectionId)
- {
- if (!ActiveConnections.ContainsKey(connectionId))
- {
- // TODO: Should this possibly be a throw condition?
- return;
- }
-
- ActiveConnections[connectionId].Close();
- ActiveConnections.Remove(connectionId);
- }
-
- public void Initialize(ServiceHost serviceHost)
+ public void InitializeService(ServiceHost serviceHost)
{
// Register request and event handlers with the Service Host
serviceHost.SetRequestHandler(ConnectionRequest.Type, HandleConnectRequest);
-
- // Register the shutdown handler
- serviceHost.RegisterShutdownTask(HandleShutdownRequest);
+
+ // Register the configuration update handler
+ WorkspaceService.Instance.RegisterConfigChangeCallback(HandleDidChangeConfigurationNotification);
}
///
@@ -178,15 +167,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices
onConnectionActivities.Add(activity);
}
- public ISqlConnection GetConnection(Guid connectionId)
- {
- if (!ActiveConnections.ContainsKey(connectionId))
- {
- throw new ArgumentException("Connection with provided ID could not be found");
- }
- return ActiveConnections[connectionId];
- }
-
#endregion
#region Request Handlers
@@ -203,24 +183,28 @@ namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices
{
Logger.Write(LogLevel.Verbose, "HandleConnectRequest");
- // open connection base on request details
- ConnectionResult result = await Connect(connectionDetails);
-
- await requestContext.SendResult(result);
+ try
+ {
+ // open connection base on request details
+ ConnectionResult result = ConnectionService.Instance.Connect(connectionDetails);
+ await requestContext.SendResult(result);
+ }
+ catch(Exception ex)
+ {
+ await requestContext.SendError(ex.Message);
+ }
}
- ///
- /// Handles shutdown event by closing out any active connections
- ///
- protected async Task HandleShutdownRequest(object shutdownObj, RequestContext