Stubbing out connectionservice with guid id

This commit is contained in:
Benjamin Russell
2016-07-29 12:52:24 -07:00
parent bc0383b6e6
commit d78c1947e0
6 changed files with 74 additions and 47 deletions

View File

@@ -5,6 +5,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient; using System.Data.SqlClient;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -55,17 +56,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices
/// </summary> /// </summary>
private ISqlConnectionFactory connectionFactory; private ISqlConnectionFactory connectionFactory;
/// <summary>
/// The current connection id that was previously used
/// </summary>
private int maxConnectionId = 0;
/// <summary> /// <summary>
/// Active connections lazy dictionary instance /// Active connections lazy dictionary instance
/// </summary> /// </summary>
private Lazy<Dictionary<int, ISqlConnection>> activeConnections private Lazy<Dictionary<Guid, ISqlConnection>> activeConnections
= new Lazy<Dictionary<int, ISqlConnection>>(() = new Lazy<Dictionary<Guid, ISqlConnection>>(()
=> new Dictionary<int, ISqlConnection>()); => new Dictionary<Guid, ISqlConnection>());
/// <summary> /// <summary>
/// Callback for onconnection handler /// Callback for onconnection handler
@@ -81,7 +77,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices
/// <summary> /// <summary>
/// Gets the active connection map /// Gets the active connection map
/// </summary> /// </summary>
public Dictionary<int, ISqlConnection> ActiveConnections public Dictionary<Guid, ISqlConnection> ActiveConnections
{ {
get get
{ {
@@ -133,7 +129,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices
await connection.OpenAsync(); await connection.OpenAsync();
// map the connection id to the connection object for future lookups // map the connection id to the connection object for future lookups
ActiveConnections.Add(++maxConnectionId, connection); Guid connectionId = Guid.NewGuid();
ActiveConnections.Add(connectionId, connection);
// invoke callback notifications // invoke callback notifications
var onConnectionCallbackTasks = onConnectionActivities.Select(t => t(connection)); var onConnectionCallbackTasks = onConnectionActivities.Select(t => t(connection));
@@ -141,16 +138,35 @@ namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices
// TODO: Evaulate if we want to avoid waiting here. We'll need error handling on the other side if we don't wait // TODO: Evaulate if we want to avoid waiting here. We'll need error handling on the other side if we don't wait
// return the connection result // return the connection result
return new ConnectionResult() return new ConnectionResult
{ {
ConnectionId = maxConnectionId ConnectionId = connectionId
}; };
} }
/// <summary>
/// Closes an active connection and removes it from the active connections list
/// </summary>
/// <param name="connectionId">ID of the connection to close</param>
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 Initialize(ServiceHost serviceHost)
{ {
// Register request and event handlers with the Service Host // Register request and event handlers with the Service Host
serviceHost.SetRequestHandler(ConnectionRequest.Type, HandleConnectRequest); serviceHost.SetRequestHandler(ConnectionRequest.Type, HandleConnectRequest);
// Register the shutdown handler
serviceHost.RegisterShutdownTask(HandleShutdownRequest);
} }
/// <summary> /// <summary>
@@ -162,6 +178,15 @@ namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices
onConnectionActivities.Add(activity); 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 #endregion
#region Request Handlers #region Request Handlers
@@ -184,6 +209,20 @@ namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices
await requestContext.SendResult(result); await requestContext.SendResult(result);
} }
/// <summary>
/// Handles shutdown event by closing out any active connections
/// </summary>
protected async Task HandleShutdownRequest(object shutdownObj, RequestContext<object> shutdownContext)
{
// Go through all the existing connections and close them out
foreach (ISqlConnection conn in ActiveConnections.Values)
{
conn.Close();
}
await Task.FromResult(0);
}
#endregion #endregion
#region Private Helpers #region Private Helpers

View File

@@ -3,6 +3,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
// //
using System;
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts; using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts;
namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices.Contracts namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices.Contracts
@@ -42,7 +43,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices.Contracts
/// <summary> /// <summary>
/// Gets or sets the connection id /// Gets or sets the connection id
/// </summary> /// </summary>
public int ConnectionId { get; set; } public Guid ConnectionId { get; set; }
/// <summary> /// <summary>
/// Gets or sets any connection error messages /// Gets or sets any connection error messages

View File

@@ -3,6 +3,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
// //
using System;
using System.Data; using System.Data;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -14,14 +15,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices.Contracts
/// </summary> /// </summary>
public interface ISqlConnection : IDbConnection public interface ISqlConnection : IDbConnection
{ {
///// <summary>
///// Open a connection to the provided connection string
///// </summary>
///// <param name="connectionString"></param>
//void OpenDatabaseConnection(string connectionString);
//IEnumerable<string> GetServerObjects();
string DataSource { get; } string DataSource { get; }
string ServerVersion { get; } string ServerVersion { get; }

View File

@@ -32,29 +32,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices.Contracts
connection = new SqlConnection(connectionString); connection = new SqlConnection(connectionString);
} }
///// <summary>
///// Gets a list of database server schema objects
///// </summary>
///// <returns></returns>
//public IEnumerable<string> GetServerObjects()
//{
// // Select the values from sys.tables to give a super basic
// // autocomplete experience. This will be replaced by SMO.
// SqlCommand command = connection.CreateCommand();
// command.CommandText = "SELECT name FROM sys.tables";
// command.CommandTimeout = 15;
// command.CommandType = CommandType.Text;
// var reader = command.ExecuteReader();
// List<string> results = new List<string>();
// while (reader.Read())
// {
// results.Add(reader[0].ToString());
// }
// return results;
//}
#region ISqlConnection Implementation #region ISqlConnection Implementation
#region Properties #region Properties

View File

@@ -5,8 +5,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlTools.ServiceLayer.ConnectionServices;
using Microsoft.SqlTools.ServiceLayer.ConnectionServices.Contracts;
using Microsoft.SqlTools.ServiceLayer.Hosting; using Microsoft.SqlTools.ServiceLayer.Hosting;
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts; using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
using Microsoft.SqlTools.ServiceLayer.WorkspaceServices.Contracts; using Microsoft.SqlTools.ServiceLayer.WorkspaceServices.Contracts;
@@ -60,11 +63,24 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
/// <summary> /// <summary>
/// Update the cached autocomplete candidate list when the user connects to a database /// Update the cached autocomplete candidate list when the user connects to a database
/// TODO: Update with refactoring/async
/// </summary> /// </summary>
/// <param name="connection"></param> /// <param name="connection"></param>
public async Task UpdateAutoCompleteCache(ISqlConnection connection) public async Task UpdateAutoCompleteCache(ISqlConnection connection)
{ {
AutoCompleteList = connection.GetServerObjects(); IDbCommand command = connection.CreateCommand();
command.CommandText = "SELECT name FROM sys.tables";
command.CommandTimeout = 15;
command.CommandType = CommandType.Text;
var reader = command.ExecuteReader();
List<string> results = new List<string>();
while (reader.Read())
{
results.Add(reader[0].ToString());
}
AutoCompleteList = results;
await Task.FromResult(0); await Task.FromResult(0);
} }

View File

@@ -17,7 +17,8 @@ using Microsoft.SqlTools.ServiceLayer.WorkspaceServices.Contracts;
using System.Linq; using System.Linq;
using Microsoft.SqlServer.Management.SqlParser.Parser; using Microsoft.SqlServer.Management.SqlParser.Parser;
using Location = Microsoft.SqlTools.ServiceLayer.WorkspaceServices.Contracts.Location; using Location = Microsoft.SqlTools.ServiceLayer.WorkspaceServices.Contracts.Location;
using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlTools.ServiceLayer.ConnectionServices;
using Microsoft.SqlTools.ServiceLayer.ConnectionServices.Contracts;
namespace Microsoft.SqlTools.ServiceLayer.LanguageServices namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
{ {