mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-16 10:58:30 -05:00
Expanding SqlConnection to be more like DBConnection
Also shifting the Connect operation to be async
This commit is contained in:
@@ -6,12 +6,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data.SqlClient;
|
using System.Data.SqlClient;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.SqlTools.EditorServices.Utility;
|
using Microsoft.SqlTools.EditorServices.Utility;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
|
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.ConnectionServices.Contracts;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.Connection
|
namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Main class for the Connection Management services
|
/// Main class for the Connection Management services
|
||||||
@@ -119,25 +121,24 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
|||||||
/// Open a connection with the specified connection details
|
/// Open a connection with the specified connection details
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="connectionDetails"></param>
|
/// <param name="connectionDetails"></param>
|
||||||
public ConnectionResult Connect(ConnectionDetails connectionDetails)
|
public async Task<ConnectionResult> Connect(ConnectionDetails connectionDetails)
|
||||||
{
|
{
|
||||||
// build the connection string from the input parameters
|
// build the connection string from the input parameters
|
||||||
string connectionString = BuildConnectionString(connectionDetails);
|
string connectionString = BuildConnectionString(connectionDetails);
|
||||||
|
|
||||||
// create a sql connection instance
|
// create a sql connection instance
|
||||||
ISqlConnection connection = this.ConnectionFactory.CreateSqlConnection();
|
ISqlConnection connection = ConnectionFactory.CreateSqlConnection(connectionString);
|
||||||
|
|
||||||
// open the database
|
// open the database
|
||||||
connection.OpenDatabaseConnection(connectionString);
|
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
|
||||||
this.ActiveConnections.Add(++maxConnectionId, connection);
|
ActiveConnections.Add(++maxConnectionId, connection);
|
||||||
|
|
||||||
// invoke callback notifications
|
// invoke callback notifications
|
||||||
foreach (var activity in this.onConnectionActivities)
|
var onConnectionCallbackTasks = onConnectionActivities.Select(t => t(connection));
|
||||||
{
|
await Task.WhenAll(onConnectionCallbackTasks);
|
||||||
activity(connection);
|
// 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()
|
||||||
@@ -178,7 +179,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
|||||||
Logger.Write(LogLevel.Verbose, "HandleConnectRequest");
|
Logger.Write(LogLevel.Verbose, "HandleConnectRequest");
|
||||||
|
|
||||||
// open connection base on request details
|
// open connection base on request details
|
||||||
ConnectionResult result = ConnectionService.Instance.Connect(connectionDetails);
|
ConnectionResult result = await Connect(connectionDetails);
|
||||||
|
|
||||||
await requestContext.SendResult(result);
|
await requestContext.SendResult(result);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,21 +3,33 @@
|
|||||||
// 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.Collections.Generic;
|
using System.Data;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices.Contracts
|
namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices.Contracts
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interface for the SQL Connection wrapper
|
/// Interface for the SQL Connection wrapper
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ISqlConnection
|
public interface ISqlConnection : IDbConnection
|
||||||
{
|
{
|
||||||
/// <summary>
|
///// <summary>
|
||||||
/// Open a connection to the provided connection string
|
///// Open a connection to the provided connection string
|
||||||
/// </summary>
|
///// </summary>
|
||||||
/// <param name="connectionString"></param>
|
///// <param name="connectionString"></param>
|
||||||
void OpenDatabaseConnection(string connectionString);
|
//void OpenDatabaseConnection(string connectionString);
|
||||||
|
|
||||||
IEnumerable<string> GetServerObjects();
|
//IEnumerable<string> GetServerObjects();
|
||||||
|
|
||||||
|
string DataSource { get; }
|
||||||
|
|
||||||
|
string ServerVersion { get; }
|
||||||
|
|
||||||
|
void ClearPool();
|
||||||
|
|
||||||
|
Task OpenAsync();
|
||||||
|
|
||||||
|
Task OpenAsync(CancellationToken token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices.Contracts
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new SQL Connection object
|
/// Create a new SQL Connection object
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ISqlConnection CreateSqlConnection();
|
ISqlConnection CreateSqlConnection(string connectionString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,11 @@
|
|||||||
// 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.Collections.Generic;
|
using System;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.SqlClient;
|
using System.Data.SqlClient;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices.Contracts
|
namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices.Contracts
|
||||||
{
|
{
|
||||||
@@ -21,36 +23,161 @@ namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices.Contracts
|
|||||||
private SqlConnection connection;
|
private SqlConnection connection;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Opens a SqlConnection using provided connection string
|
/// Creates a new instance of the SqlClientConnection with an underlying connection to the
|
||||||
|
/// database server provided in <paramref name="connectionString"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="connectionString"></param>
|
/// <param name="connectionString">Connection string for the database to connect to</param>
|
||||||
public void OpenDatabaseConnection(string connectionString)
|
public SqlClientConnection(string connectionString)
|
||||||
{
|
{
|
||||||
this.connection = new SqlConnection(connectionString);
|
connection = new SqlConnection(connectionString);
|
||||||
this.connection.Open();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
///// <summary>
|
||||||
/// Gets a list of database server schema objects
|
///// Gets a list of database server schema objects
|
||||||
/// </summary>
|
///// </summary>
|
||||||
/// <returns></returns>
|
///// <returns></returns>
|
||||||
public IEnumerable<string> GetServerObjects()
|
//public IEnumerable<string> GetServerObjects()
|
||||||
{
|
//{
|
||||||
// Select the values from sys.tables to give a super basic
|
// // Select the values from sys.tables to give a super basic
|
||||||
// autocomplete experience. This will be replaced by SMO.
|
// // autocomplete experience. This will be replaced by SMO.
|
||||||
SqlCommand command = connection.CreateCommand();
|
// SqlCommand command = connection.CreateCommand();
|
||||||
command.CommandText = "SELECT name FROM sys.tables";
|
// command.CommandText = "SELECT name FROM sys.tables";
|
||||||
command.CommandTimeout = 15;
|
// command.CommandTimeout = 15;
|
||||||
command.CommandType = CommandType.Text;
|
// command.CommandType = CommandType.Text;
|
||||||
var reader = command.ExecuteReader();
|
// var reader = command.ExecuteReader();
|
||||||
|
|
||||||
List<string> results = new List<string>();
|
// List<string> results = new List<string>();
|
||||||
while (reader.Read())
|
// while (reader.Read())
|
||||||
|
// {
|
||||||
|
// results.Add(reader[0].ToString());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return results;
|
||||||
|
//}
|
||||||
|
|
||||||
|
#region ISqlConnection Implementation
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
public string ConnectionString
|
||||||
|
{
|
||||||
|
get { return connection.ConnectionString; }
|
||||||
|
set { connection.ConnectionString = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ConnectionTimeout
|
||||||
|
{
|
||||||
|
get { return connection.ConnectionTimeout; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Database
|
||||||
|
{
|
||||||
|
get { return connection.Database; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string DataSource
|
||||||
|
{
|
||||||
|
get { return connection.DataSource; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ServerVersion
|
||||||
|
{
|
||||||
|
get { return connection.ServerVersion; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnectionState State
|
||||||
|
{
|
||||||
|
get { return connection.State; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Methods
|
||||||
|
|
||||||
|
public IDbTransaction BeginTransaction()
|
||||||
|
{
|
||||||
|
return connection.BeginTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDbTransaction BeginTransaction(IsolationLevel il)
|
||||||
|
{
|
||||||
|
return connection.BeginTransaction(il);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ChangeDatabase(string databaseName)
|
||||||
|
{
|
||||||
|
connection.ChangeDatabase(databaseName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearPool()
|
||||||
|
{
|
||||||
|
if (connection != null)
|
||||||
{
|
{
|
||||||
results.Add(reader[0].ToString());
|
SqlConnection.ClearPool(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
connection.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDbCommand CreateCommand()
|
||||||
|
{
|
||||||
|
return connection.CreateCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Open()
|
||||||
|
{
|
||||||
|
connection.Open();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task OpenAsync()
|
||||||
|
{
|
||||||
|
return connection.OpenAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task OpenAsync(CancellationToken token)
|
||||||
|
{
|
||||||
|
return connection.OpenAsync(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IDisposable Implementation
|
||||||
|
|
||||||
|
private bool disposed;
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (!disposed)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
if (connection.State == ConnectionState.Open)
|
||||||
|
{
|
||||||
|
connection.Close();
|
||||||
|
}
|
||||||
|
connection.Dispose();
|
||||||
|
}
|
||||||
|
disposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~SqlClientConnection()
|
||||||
|
{
|
||||||
|
Dispose(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ namespace Microsoft.SqlTools.ServiceLayer.ConnectionServices.Contracts
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new SqlClientConnection object
|
/// Creates a new SqlClientConnection object
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ISqlConnection CreateSqlConnection()
|
public ISqlConnection CreateSqlConnection(string connectionString)
|
||||||
{
|
{
|
||||||
return new SqlClientConnection();
|
return new SqlClientConnection(connectionString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using Microsoft.SqlTools.ServiceLayer.Hosting;
|
|||||||
using Microsoft.SqlTools.ServiceLayer.SqlContext;
|
using Microsoft.SqlTools.ServiceLayer.SqlContext;
|
||||||
using Microsoft.SqlTools.ServiceLayer.WorkspaceServices;
|
using Microsoft.SqlTools.ServiceLayer.WorkspaceServices;
|
||||||
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
|
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
using Microsoft.SqlTools.ServiceLayer.ConnectionServices;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer
|
namespace Microsoft.SqlTools.ServiceLayer
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user