mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-29 01:25:41 -05:00
3326 Kusto HTTPS url fix (#1086)
* 3326 Removed sqlConnection.Open from CreateSqlConnection in ConnectionService. * 3326 Removed unused variables and functions from ConnectedBindingContext, ConnectedBindingQueue, IBindingContext, and IConnectedBindingQueue * 3326 Removed unused constant SqlAzureEdition and unused functions CreateSqlConnection and CreateServerConnection from ConnectionService. Removed ServerConnection, MetadataDisplayInfoProvider, Binder, and SmoMetaDataProvider from ConnectedBindingContext. Deleted SqlConnectionOpener and ISqlConnectionOpener.
This commit is contained in:
@@ -31,9 +31,8 @@ namespace Microsoft.Kusto.ServiceLayer.Connection
|
||||
/// </summary>
|
||||
public class ConnectionService
|
||||
{
|
||||
public const string AdminConnectionPrefix = "ADMIN:";
|
||||
internal const string PasswordPlaceholder = "******";
|
||||
private const string SqlAzureEdition = "SQL Azure";
|
||||
private const string AdminConnectionPrefix = "ADMIN:";
|
||||
private const string PasswordPlaceholder = "******";
|
||||
|
||||
/// <summary>
|
||||
/// Singleton service instance
|
||||
@@ -984,7 +983,7 @@ namespace Microsoft.Kusto.ServiceLayer.Connection
|
||||
/// Build a connection string builder a connection details instance
|
||||
/// </summary>
|
||||
/// <param name="connectionDetails"></param>
|
||||
public static SqlConnectionStringBuilder CreateConnectionStringBuilder(ConnectionDetails connectionDetails)
|
||||
private static SqlConnectionStringBuilder CreateConnectionStringBuilder(ConnectionDetails connectionDetails)
|
||||
{
|
||||
SqlConnectionStringBuilder connectionBuilder;
|
||||
|
||||
@@ -1359,63 +1358,6 @@ namespace Microsoft.Kusto.ServiceLayer.Connection
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create and open a new SqlConnection from a ConnectionInfo object
|
||||
/// Note: we need to audit all uses of this method to determine why we're
|
||||
/// bypassing normal ConnectionService connection management
|
||||
/// </summary>
|
||||
/// <param name="connInfo">The connection info to connect with</param>
|
||||
/// <param name="featureName">A plaintext string that will be included in the application name for the connection</param>
|
||||
/// <returns>A SqlConnection created with the given connection info</returns>
|
||||
internal static SqlConnection OpenSqlConnection(ConnectionInfo connInfo, string featureName = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// capture original values
|
||||
int? originalTimeout = connInfo.ConnectionDetails.ConnectTimeout;
|
||||
bool? originalPersistSecurityInfo = connInfo.ConnectionDetails.PersistSecurityInfo;
|
||||
bool? originalPooling = connInfo.ConnectionDetails.Pooling;
|
||||
|
||||
// increase the connection timeout to at least 30 seconds and and build connection string
|
||||
connInfo.ConnectionDetails.ConnectTimeout = Math.Max(30, originalTimeout ?? 0);
|
||||
// enable PersistSecurityInfo to handle issues in SMO where the connection context is lost in reconnections
|
||||
connInfo.ConnectionDetails.PersistSecurityInfo = true;
|
||||
// turn off connection pool to avoid hold locks on server resources after calling SqlConnection Close method
|
||||
connInfo.ConnectionDetails.Pooling = false;
|
||||
connInfo.ConnectionDetails.ApplicationName = GetApplicationNameWithFeature(connInfo.ConnectionDetails.ApplicationName, featureName);
|
||||
|
||||
// generate connection string
|
||||
string connectionString = BuildConnectionString(connInfo.ConnectionDetails);
|
||||
|
||||
// restore original values
|
||||
connInfo.ConnectionDetails.ConnectTimeout = originalTimeout;
|
||||
connInfo.ConnectionDetails.PersistSecurityInfo = originalPersistSecurityInfo;
|
||||
connInfo.ConnectionDetails.Pooling = originalPooling;
|
||||
|
||||
// open a dedicated binding server connection
|
||||
using (SqlConnection sqlConn = new SqlConnection(connectionString))
|
||||
{
|
||||
// Fill in Azure authentication token if needed
|
||||
if (connInfo.ConnectionDetails.AzureAccountToken != null)
|
||||
{
|
||||
sqlConn.AccessToken = connInfo.ConnectionDetails.AzureAccountToken;
|
||||
}
|
||||
|
||||
sqlConn.Open();
|
||||
return sqlConn;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
string error = string.Format(CultureInfo.InvariantCulture,
|
||||
"Failed opening a SqlConnection: error:{0} inner:{1} stacktrace:{2}",
|
||||
ex.Message, ex.InnerException != null ? ex.InnerException.Message : string.Empty, ex.StackTrace);
|
||||
Logger.Write(TraceEventType.Error, error);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create and open a new SqlConnection from a ConnectionInfo object
|
||||
/// Note: we need to audit all uses of this method to determine why we're
|
||||
@@ -1445,23 +1387,6 @@ namespace Microsoft.Kusto.ServiceLayer.Connection
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create and open a new ServerConnection from a ConnectionInfo object.
|
||||
/// This calls ConnectionService.OpenSqlConnection and then creates a
|
||||
/// ServerConnection from it.
|
||||
/// </summary>
|
||||
/// <param name="connInfo">The connection info to connect with</param>
|
||||
/// <param name="featureName">A plaintext string that will be included in the application name for the connection</param>
|
||||
/// <returns>A ServerConnection (wrapping a SqlConnection) created with the given connection info</returns>
|
||||
internal static ServerConnection OpenServerConnection(ConnectionInfo connInfo, string featureName = null)
|
||||
{
|
||||
SqlConnection sqlConnection = OpenSqlConnection(connInfo, featureName);
|
||||
|
||||
return connInfo.ConnectionDetails.AzureAccountToken != null
|
||||
? new ServerConnection(sqlConnection, new AzureAccessToken(connInfo.ConnectionDetails.AzureAccountToken))
|
||||
: new ServerConnection(sqlConnection);
|
||||
}
|
||||
|
||||
public static void EnsureConnectionIsOpen(ReliableDataSourceConnection conn, bool forceReopen = false)
|
||||
{
|
||||
// verify that the connection is open
|
||||
|
||||
@@ -202,15 +202,6 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
{
|
||||
// disconnect existing connection
|
||||
var bindingContext = this.BindingContextMap[key];
|
||||
if (bindingContext.ServerConnection != null && bindingContext.ServerConnection.IsOpen)
|
||||
{
|
||||
// Disconnecting can take some time so run it in a separate task so that it doesn't block removal
|
||||
Task.Run(() =>
|
||||
{
|
||||
bindingContext.ServerConnection.Cancel();
|
||||
bindingContext.ServerConnection.Disconnect();
|
||||
});
|
||||
}
|
||||
|
||||
// remove key from the map
|
||||
this.BindingContextMap.Remove(key);
|
||||
@@ -483,17 +474,6 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
{
|
||||
_itemQueuedEvent.Dispose();
|
||||
}
|
||||
|
||||
if (this.BindingContextMap != null)
|
||||
{
|
||||
foreach (var item in this.BindingContextMap)
|
||||
{
|
||||
if (item.Value != null && item.Value.ServerConnection != null && item.Value.ServerConnection.SqlConnectionObject != null)
|
||||
{
|
||||
item.Value.ServerConnection.SqlConnectionObject.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsExceptionOfType(Exception ex, Type t)
|
||||
|
||||
@@ -3,14 +3,7 @@
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlServer.Management.SmoMetadataProvider;
|
||||
using Microsoft.SqlServer.Management.SqlParser.Binder;
|
||||
using Microsoft.SqlServer.Management.SqlParser.Common;
|
||||
using Microsoft.SqlServer.Management.SqlParser.MetadataProvider;
|
||||
using Microsoft.SqlServer.Management.SqlParser.Parser;
|
||||
using Microsoft.Kusto.ServiceLayer.DataSource;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
@@ -20,11 +13,7 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
/// </summary>
|
||||
public class ConnectedBindingContext : IBindingContext
|
||||
{
|
||||
private ParseOptions parseOptions;
|
||||
|
||||
private ManualResetEvent bindingLock;
|
||||
|
||||
private ServerConnection serverConnection;
|
||||
private readonly ManualResetEvent bindingLock;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IDataSource DataSource { get; set; }
|
||||
@@ -36,7 +25,6 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
{
|
||||
this.bindingLock = new ManualResetEvent(initialState: true);
|
||||
this.BindingTimeout = ConnectedBindingQueue.DefaultBindingTimeout;
|
||||
this.MetadataDisplayInfoProvider = new MetadataDisplayInfoProvider();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -44,39 +32,6 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
/// </summary>
|
||||
public bool IsConnected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the binding server connection
|
||||
/// </summary>
|
||||
public ServerConnection ServerConnection
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.serverConnection;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.serverConnection = value;
|
||||
|
||||
// reset the parse options so the get recreated for the current connection
|
||||
this.parseOptions = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the metadata display info provider
|
||||
/// </summary>
|
||||
public MetadataDisplayInfoProvider MetadataDisplayInfoProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the SMO metadata provider
|
||||
/// </summary>
|
||||
public SmoMetadataProvider SmoMetadataProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the binder
|
||||
/// </summary>
|
||||
public IBinder Binder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the binding lock object
|
||||
/// </summary>
|
||||
@@ -91,130 +46,6 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
/// <summary>
|
||||
/// Gets or sets the binding operation timeout in milliseconds
|
||||
/// </summary>
|
||||
public int BindingTimeout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Language Service ServerVersion
|
||||
/// </summary>
|
||||
public ServerVersion ServerVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.ServerConnection != null
|
||||
? this.ServerConnection.ServerVersion
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current DataEngineType
|
||||
/// </summary>
|
||||
public DatabaseEngineType DatabaseEngineType
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.ServerConnection != null
|
||||
? this.ServerConnection.DatabaseEngineType
|
||||
: DatabaseEngineType.Standalone;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current connections TransactSqlVersion
|
||||
/// </summary>
|
||||
public TransactSqlVersion TransactSqlVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.IsConnected
|
||||
? GetTransactSqlVersion(this.ServerVersion)
|
||||
: TransactSqlVersion.Current;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current DatabaseCompatibilityLevel
|
||||
/// </summary>
|
||||
public DatabaseCompatibilityLevel DatabaseCompatibilityLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.IsConnected
|
||||
? GetDatabaseCompatibilityLevel(this.ServerVersion)
|
||||
: DatabaseCompatibilityLevel.Current;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current ParseOptions
|
||||
/// </summary>
|
||||
public ParseOptions ParseOptions
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.parseOptions == null)
|
||||
{
|
||||
this.parseOptions = new ParseOptions(
|
||||
batchSeparator: LanguageService.DefaultBatchSeperator,
|
||||
isQuotedIdentifierSet: true,
|
||||
compatibilityLevel: DatabaseCompatibilityLevel,
|
||||
transactSqlVersion: TransactSqlVersion);
|
||||
}
|
||||
return this.parseOptions;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the database compatibility level from a server version
|
||||
/// </summary>
|
||||
/// <param name="serverVersion"></param>
|
||||
private static DatabaseCompatibilityLevel GetDatabaseCompatibilityLevel(ServerVersion serverVersion)
|
||||
{
|
||||
int versionMajor = Math.Max(serverVersion.Major, 8);
|
||||
|
||||
switch (versionMajor)
|
||||
{
|
||||
case 8:
|
||||
return DatabaseCompatibilityLevel.Version80;
|
||||
case 9:
|
||||
return DatabaseCompatibilityLevel.Version90;
|
||||
case 10:
|
||||
return DatabaseCompatibilityLevel.Version100;
|
||||
case 11:
|
||||
return DatabaseCompatibilityLevel.Version110;
|
||||
case 12:
|
||||
return DatabaseCompatibilityLevel.Version120;
|
||||
case 13:
|
||||
return DatabaseCompatibilityLevel.Version130;
|
||||
default:
|
||||
return DatabaseCompatibilityLevel.Current;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the transaction sql version from a server version
|
||||
/// </summary>
|
||||
/// <param name="serverVersion"></param>
|
||||
private static TransactSqlVersion GetTransactSqlVersion(ServerVersion serverVersion)
|
||||
{
|
||||
int versionMajor = Math.Max(serverVersion.Major, 9);
|
||||
|
||||
switch (versionMajor)
|
||||
{
|
||||
case 9:
|
||||
case 10:
|
||||
// In case of 10.0 we still use Version 10.5 as it is the closest available.
|
||||
return TransactSqlVersion.Version105;
|
||||
case 11:
|
||||
return TransactSqlVersion.Version110;
|
||||
case 12:
|
||||
return TransactSqlVersion.Version120;
|
||||
case 13:
|
||||
return TransactSqlVersion.Version130;
|
||||
default:
|
||||
return TransactSqlVersion.Current;
|
||||
}
|
||||
}
|
||||
public int BindingTimeout { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,13 +5,8 @@
|
||||
|
||||
using System;
|
||||
using System.Composition;
|
||||
using Microsoft.SqlServer.Management.SmoMetadataProvider;
|
||||
using Microsoft.SqlServer.Management.SqlParser.Binder;
|
||||
using Microsoft.SqlServer.Management.SqlParser.MetadataProvider;
|
||||
using Microsoft.Kusto.ServiceLayer.Connection;
|
||||
using Microsoft.Kusto.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.Kusto.ServiceLayer.SqlContext;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace;
|
||||
using Microsoft.Kusto.ServiceLayer.DataSource;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
@@ -23,21 +18,11 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
public class ConnectedBindingQueue : BindingQueue<ConnectedBindingContext>, IConnectedBindingQueue
|
||||
{
|
||||
internal const int DefaultBindingTimeout = 500;
|
||||
private readonly ISqlConnectionOpener _connectionOpener;
|
||||
private readonly IDataSourceFactory _dataSourceFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current settings
|
||||
/// </summary>
|
||||
private SqlToolsSettings CurrentSettings
|
||||
{
|
||||
get { return WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings; }
|
||||
}
|
||||
|
||||
[ImportingConstructor]
|
||||
public ConnectedBindingQueue(ISqlConnectionOpener sqlConnectionOpener, IDataSourceFactory dataSourceFactory)
|
||||
public ConnectedBindingQueue(IDataSourceFactory dataSourceFactory)
|
||||
{
|
||||
_connectionOpener = sqlConnectionOpener;
|
||||
_dataSourceFactory = dataSourceFactory;
|
||||
}
|
||||
|
||||
@@ -67,52 +52,6 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
return Uri.EscapeUriString(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a unique key based on the ConnectionInfo object
|
||||
/// </summary>
|
||||
/// <param name="serverName"></param>
|
||||
/// <param name="databaseName"></param>
|
||||
private string GetConnectionContextKey(string serverName, string databaseName)
|
||||
{
|
||||
return string.Format("{0}_{1}",
|
||||
serverName ?? "NULL",
|
||||
databaseName ?? "NULL");
|
||||
|
||||
}
|
||||
|
||||
public void CloseConnections(string serverName, string databaseName, int millisecondsTimeout)
|
||||
{
|
||||
string connectionKey = GetConnectionContextKey(serverName, databaseName);
|
||||
var contexts = GetBindingContexts(connectionKey);
|
||||
foreach (var bindingContext in contexts)
|
||||
{
|
||||
if (bindingContext.BindingLock.WaitOne(millisecondsTimeout))
|
||||
{
|
||||
bindingContext.ServerConnection.Disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenConnections(string serverName, string databaseName, int millisecondsTimeout)
|
||||
{
|
||||
string connectionKey = GetConnectionContextKey(serverName, databaseName);
|
||||
var contexts = GetBindingContexts(connectionKey);
|
||||
foreach (var bindingContext in contexts)
|
||||
{
|
||||
if (bindingContext.BindingLock.WaitOne(millisecondsTimeout))
|
||||
{
|
||||
try
|
||||
{
|
||||
bindingContext.ServerConnection.Connect();
|
||||
}
|
||||
catch
|
||||
{
|
||||
//TODO: remove the binding context?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveBindingContext(ConnectionInfo connInfo)
|
||||
{
|
||||
string connectionKey = GetConnectionContextKey(connInfo.ConnectionDetails);
|
||||
@@ -157,24 +96,10 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
try
|
||||
{
|
||||
bindingContext.BindingLock.Reset();
|
||||
|
||||
// populate the binding context to work with the SMO metadata provider
|
||||
bindingContext.ServerConnection = _connectionOpener.OpenServerConnection(connInfo, featureName);
|
||||
|
||||
|
||||
string connectionString = ConnectionService.BuildConnectionString(connInfo.ConnectionDetails);
|
||||
bindingContext.DataSource = _dataSourceFactory.Create(DataSourceType.Kusto, connectionString, connInfo.ConnectionDetails.AzureAccountToken);
|
||||
|
||||
if (needMetadata)
|
||||
{
|
||||
bindingContext.SmoMetadataProvider = SmoMetadataProvider.CreateConnectedProvider(bindingContext.ServerConnection);
|
||||
bindingContext.MetadataDisplayInfoProvider = new MetadataDisplayInfoProvider();
|
||||
bindingContext.MetadataDisplayInfoProvider.BuiltInCasing =
|
||||
this.CurrentSettings.SqlTools.IntelliSense.LowerCaseSuggestions.Value
|
||||
? CasingStyle.Lowercase : CasingStyle.Uppercase;
|
||||
bindingContext.Binder = BinderProvider.CreateBinder(bindingContext.SmoMetadataProvider);
|
||||
}
|
||||
|
||||
bindingContext.BindingTimeout = ConnectedBindingQueue.DefaultBindingTimeout;
|
||||
bindingContext.BindingTimeout = DefaultBindingTimeout;
|
||||
bindingContext.IsConnected = true;
|
||||
}
|
||||
catch (Exception)
|
||||
|
||||
@@ -4,12 +4,6 @@
|
||||
//
|
||||
|
||||
using System.Threading;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlServer.Management.SmoMetadataProvider;
|
||||
using Microsoft.SqlServer.Management.SqlParser.Binder;
|
||||
using Microsoft.SqlServer.Management.SqlParser.Common;
|
||||
using Microsoft.SqlServer.Management.SqlParser.MetadataProvider;
|
||||
using Microsoft.SqlServer.Management.SqlParser.Parser;
|
||||
using Microsoft.Kusto.ServiceLayer.DataSource;
|
||||
|
||||
|
||||
@@ -25,31 +19,11 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
/// </summary>
|
||||
bool IsConnected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the binding server connection
|
||||
/// </summary>
|
||||
ServerConnection ServerConnection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets data source interface
|
||||
/// </summary>
|
||||
IDataSource DataSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the metadata display info provider
|
||||
/// </summary>
|
||||
MetadataDisplayInfoProvider MetadataDisplayInfoProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the SMO metadata provider
|
||||
/// </summary>
|
||||
SmoMetadataProvider SmoMetadataProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the binder
|
||||
/// </summary>
|
||||
IBinder Binder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the binding lock object
|
||||
/// </summary>
|
||||
@@ -59,30 +33,5 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
/// Gets or sets the binding operation timeout in milliseconds
|
||||
/// </summary>
|
||||
int BindingTimeout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current connection parse options
|
||||
/// </summary>
|
||||
ParseOptions ParseOptions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current connection server version
|
||||
/// </summary>
|
||||
ServerVersion ServerVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the database engine type
|
||||
/// </summary>
|
||||
DatabaseEngineType DatabaseEngineType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the T-SQL version
|
||||
/// </summary>
|
||||
TransactSqlVersion TransactSqlVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the database compatibility level
|
||||
/// </summary>
|
||||
DatabaseCompatibilityLevel DatabaseCompatibilityLevel { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,7 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
public interface IConnectedBindingQueue
|
||||
{
|
||||
event BindingQueue<ConnectedBindingContext>.UnhandledExceptionDelegate OnUnhandledException;
|
||||
|
||||
void CloseConnections(string serverName, string databaseName, int millisecondsTimeout);
|
||||
void OpenConnections(string serverName, string databaseName, int millisecondsTimeout);
|
||||
|
||||
string AddConnectionContext(ConnectionInfo connInfo, bool needMetadata, string featureName = null, bool overwrite = false);
|
||||
void Dispose();
|
||||
bool IsBindingContextConnected(string key);
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
using Microsoft.Kusto.ServiceLayer.Connection;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
{
|
||||
public interface ISqlConnectionOpener
|
||||
{
|
||||
/// <summary>
|
||||
/// Virtual method used to support mocking and testing
|
||||
/// </summary>
|
||||
ServerConnection OpenServerConnection(ConnectionInfo connInfo, string featureName);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using System.Composition;
|
||||
using Microsoft.Kusto.ServiceLayer.Connection;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
{
|
||||
[Export(typeof(ISqlConnectionOpener))]
|
||||
public class SqlConnectionOpener : ISqlConnectionOpener
|
||||
{
|
||||
public ServerConnection OpenServerConnection(ConnectionInfo connInfo, string featureName)
|
||||
{
|
||||
return ConnectionService.OpenServerConnection(connInfo, featureName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -412,19 +412,7 @@ namespace Microsoft.Kusto.ServiceLayer.ObjectExplorer
|
||||
}
|
||||
response.Nodes = nodes;
|
||||
response.ErrorMessage = node.ErrorMessage;
|
||||
try
|
||||
{
|
||||
// SMO changes the database when getting sql objects. Make sure the database is changed back to the original one
|
||||
if (bindingContext.ServerConnection.CurrentDatabase != bindingContext.ServerConnection.DatabaseName)
|
||||
{
|
||||
bindingContext.ServerConnection.SqlConnectionObject.ChangeDatabase(bindingContext.ServerConnection.DatabaseName);
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Logger.Write(TraceEventType.Warning, $"Failed to change the database in OE connection. error: {ex.Message}");
|
||||
// We should just try to change the connection. If it fails, there's not much we can do
|
||||
}
|
||||
|
||||
return response;
|
||||
});
|
||||
|
||||
|
||||
@@ -66,9 +66,8 @@ namespace Microsoft.Kusto.ServiceLayer.UnitTests.LanguageServices
|
||||
[Test]
|
||||
public void AddConnectionContext_Returns_EmptyString_For_NullConnectionInfo()
|
||||
{
|
||||
var connectionOpenerMock = new Mock<ISqlConnectionOpener>();
|
||||
var dataSourceFactory = new Mock<IDataSourceFactory>();
|
||||
var connectedBindingQueue = new ConnectedBindingQueue(connectionOpenerMock.Object, dataSourceFactory.Object);
|
||||
var connectedBindingQueue = new ConnectedBindingQueue(dataSourceFactory.Object);
|
||||
var connectionKey = connectedBindingQueue.AddConnectionContext(null, false);
|
||||
|
||||
Assert.AreEqual(string.Empty, connectionKey);
|
||||
@@ -81,9 +80,8 @@ namespace Microsoft.Kusto.ServiceLayer.UnitTests.LanguageServices
|
||||
var connectionFactory = new Mock<IDataSourceConnectionFactory>();
|
||||
var connectionInfo = new ConnectionInfo(connectionFactory.Object, "ownerUri", connectionDetails);
|
||||
|
||||
var connectionOpenerMock = new Mock<ISqlConnectionOpener>();
|
||||
var dataSourceFactory = new Mock<IDataSourceFactory>();
|
||||
var connectedBindingQueue = new ConnectedBindingQueue(connectionOpenerMock.Object, dataSourceFactory.Object);
|
||||
var connectedBindingQueue = new ConnectedBindingQueue(dataSourceFactory.Object);
|
||||
var connectionKey = connectedBindingQueue.AddConnectionContext(connectionInfo, false, "featureName");
|
||||
|
||||
Assert.AreEqual("NULL_NULL_NULL_NULL", connectionKey);
|
||||
@@ -96,12 +94,6 @@ namespace Microsoft.Kusto.ServiceLayer.UnitTests.LanguageServices
|
||||
var connectionFactory = new Mock<IDataSourceConnectionFactory>();
|
||||
var connectionInfo = new ConnectionInfo(connectionFactory.Object, "ownerUri", connectionDetails);
|
||||
|
||||
var connectionOpenerMock = new Mock<ISqlConnectionOpener>();
|
||||
var fakeServerConnection = new ServerConnection();
|
||||
connectionOpenerMock
|
||||
.Setup(x => x.OpenServerConnection(It.IsAny<ConnectionInfo>(), It.IsAny<string>()))
|
||||
.Returns(fakeServerConnection);
|
||||
|
||||
var dataSourceFactory = new Mock<IDataSourceFactory>();
|
||||
var dataSourceMock = new Mock<IDataSource>();
|
||||
dataSourceFactory
|
||||
@@ -109,18 +101,14 @@ namespace Microsoft.Kusto.ServiceLayer.UnitTests.LanguageServices
|
||||
.Returns(dataSourceMock.Object);
|
||||
|
||||
var connectedBindingQueue =
|
||||
new ConnectedBindingQueue(connectionOpenerMock.Object, dataSourceFactory.Object);
|
||||
new ConnectedBindingQueue(dataSourceFactory.Object);
|
||||
var connectionKey =
|
||||
connectedBindingQueue.AddConnectionContext(connectionInfo, needsMetadata, "featureName");
|
||||
var bindingContext = connectedBindingQueue.GetOrCreateBindingContext(connectionKey);
|
||||
|
||||
Assert.AreEqual(fakeServerConnection, bindingContext.ServerConnection);
|
||||
|
||||
Assert.AreEqual(dataSourceMock.Object, bindingContext.DataSource);
|
||||
Assert.AreEqual(500, bindingContext.BindingTimeout);
|
||||
Assert.AreEqual(true, bindingContext.IsConnected);
|
||||
Assert.AreEqual(CasingStyle.Uppercase, bindingContext.MetadataDisplayInfoProvider.BuiltInCasing);
|
||||
Assert.IsNull(bindingContext.SmoMetadataProvider);
|
||||
Assert.IsNull(bindingContext.Binder);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -130,12 +118,10 @@ namespace Microsoft.Kusto.ServiceLayer.UnitTests.LanguageServices
|
||||
var connectionFactory = new Mock<IDataSourceConnectionFactory>();
|
||||
var connectionInfo = new ConnectionInfo(connectionFactory.Object, "ownerUri", connectionDetails);
|
||||
|
||||
var connectionOpenerMock = new Mock<ISqlConnectionOpener>();
|
||||
var dataSourceFactory = new Mock<IDataSourceFactory>();
|
||||
var connectedBindingQueue = new ConnectedBindingQueue(connectionOpenerMock.Object, dataSourceFactory.Object);
|
||||
var connectedBindingQueue = new ConnectedBindingQueue(dataSourceFactory.Object);
|
||||
var connectionKey = connectedBindingQueue.AddConnectionContext(connectionInfo, false, "featureName");
|
||||
|
||||
|
||||
connectedBindingQueue.RemoveBindingContext(connectionInfo);
|
||||
|
||||
Assert.IsFalse(connectedBindingQueue.BindingContextMap.ContainsKey(connectionKey));
|
||||
|
||||
Reference in New Issue
Block a user