Add more specific URI strings to Object Explorer (#1881)

* Added all non null properties to URI generator

* Added all options to URI for session

* added documentation comments

* added generated nodeTypes file

* added updated uri to connection store

* Added debug message for integrated test failure

* Revert "Added debug message for integrated test failure"

This reverts commit 026c53d1ed3fb16b0f37b7b6e0775402a2ef9281.

* added advanced options to table designer table

* removed connectionName from uri generation

* Revert "removed connectionName from uri generation"

This reverts commit 88eedbbc593a0279872edc6d4cbd1b7ca3d72ad0.

* added connectionname to connection details

* added connection name to near front of key
This commit is contained in:
Alex Ma
2023-04-17 14:24:12 -07:00
committed by GitHub
parent c15108808f
commit add216cc1e
4 changed files with 61 additions and 10 deletions

View File

@@ -586,6 +586,21 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.Contracts
} }
} }
/// <summary>
/// Gets or sets the connection name
/// </summary>
public string ConnectionName
{
get
{
return GetOptionValue<string>("connectionName");
}
set
{
SetOptionValue("connectionName", value);
}
}
/// <summary> /// <summary>
/// Gets or sets the database display name /// Gets or sets the database display name
/// </summary> /// </summary>

View File

@@ -6,6 +6,7 @@
#nullable disable #nullable disable
using System; using System;
using System.Collections.Generic;
using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.SmoMetadataProvider; using Microsoft.SqlServer.Management.SmoMetadataProvider;
using Microsoft.SqlServer.Management.SqlParser.Binder; using Microsoft.SqlServer.Management.SqlParser.Binder;
@@ -70,7 +71,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
public ConnectedBindingQueue() public ConnectedBindingQueue()
: this(true) : this(true)
{ {
} }
public ConnectedBindingQueue(bool needsMetadata) public ConnectedBindingQueue(bool needsMetadata)
@@ -90,7 +91,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
/// </summary> /// </summary>
/// <param name="connInfo"></param> /// <param name="connInfo"></param>
internal static string GetConnectionContextKey(ConnectionDetails details) internal static string GetConnectionContextKey(ConnectionDetails details)
{ {
string key = string.Format("{0}_{1}_{2}_{3}", string key = string.Format("{0}_{1}_{2}_{3}",
details.ServerName ?? "NULL", details.ServerName ?? "NULL",
details.DatabaseName ?? "NULL", details.DatabaseName ?? "NULL",
@@ -108,6 +109,39 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
key += "_" + details.GroupId; key += "_" + details.GroupId;
} }
if (!string.IsNullOrEmpty(details.ConnectionName))
{
key += "_" + details.ConnectionName;
}
// Additional properties that are used to distinguish the connection (besides password)
// These are so that multiple connections can connect to the same target, with different settings.
foreach (KeyValuePair<string, object> entry in details.Options)
{
// Filter out properties we already have or don't want (password)
if (entry.Key != "server" && entry.Key != "database" && entry.Key != "user"
&& entry.Key != "authenticationType" && entry.Key != "databaseDisplayName"
&& entry.Key != "groupId" && entry.Key != "password" && entry.Key != "connectionName")
{
// Boolean values are explicitly labeled true or false instead of undefined.
if (entry.Value is bool)
{
if ((bool)entry.Value)
{
key += "_" + entry.Key + ":true";
}
else
{
key += "_" + entry.Key + ":false";
}
}
else if (!string.IsNullOrEmpty(entry.Value as String))
{
key += "_" + entry.Key + ":" + entry.Value;
}
}
}
return Uri.EscapeUriString(key); return Uri.EscapeUriString(key);
} }
@@ -120,7 +154,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
return string.Format("{0}_{1}", return string.Format("{0}_{1}",
serverName ?? "NULL", serverName ?? "NULL",
databaseName ?? "NULL"); databaseName ?? "NULL");
} }
public void CloseConnections(string serverName, string databaseName, int millisecondsTimeout) public void CloseConnections(string serverName, string databaseName, int millisecondsTimeout)
@@ -198,7 +232,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
try try
{ {
bindingContext.BindingLock.Reset(); bindingContext.BindingLock.Reset();
// populate the binding context to work with the SMO metadata provider // populate the binding context to work with the SMO metadata provider
bindingContext.ServerConnection = connectionOpener.OpenServerConnection(connInfo, featureName); bindingContext.ServerConnection = connectionOpener.OpenServerConnection(connInfo, featureName);
@@ -210,19 +244,19 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
this.CurrentSettings.SqlTools.IntelliSense.LowerCaseSuggestions.Value this.CurrentSettings.SqlTools.IntelliSense.LowerCaseSuggestions.Value
? CasingStyle.Lowercase : CasingStyle.Uppercase; ? CasingStyle.Lowercase : CasingStyle.Uppercase;
bindingContext.Binder = BinderProvider.CreateBinder(bindingContext.SmoMetadataProvider); bindingContext.Binder = BinderProvider.CreateBinder(bindingContext.SmoMetadataProvider);
} }
bindingContext.BindingTimeout = ConnectedBindingQueue.DefaultBindingTimeout; bindingContext.BindingTimeout = ConnectedBindingQueue.DefaultBindingTimeout;
bindingContext.IsConnected = true; bindingContext.IsConnected = true;
} }
catch (Exception) catch (Exception)
{ {
bindingContext.IsConnected = false; bindingContext.IsConnected = false;
} }
finally finally
{ {
bindingContext.BindingLock.Set(); bindingContext.BindingLock.Set();
} }
} }
return connectionKey; return connectionKey;

View File

@@ -1830,9 +1830,11 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner
private void UpdateTableTitleInfo(TableInfo tableInfo) private void UpdateTableTitleInfo(TableInfo tableInfo)
{ {
var td = GetTableDesigner(tableInfo); var td = GetTableDesigner(tableInfo);
var advancedOpsIndex = tableInfo.Tooltip.LastIndexOf('[');
var advancedOps = tableInfo.Tooltip.Substring(advancedOpsIndex);
tableInfo.Title = td.TableViewModel.FullName; tableInfo.Title = td.TableViewModel.FullName;
var tableParent = tableInfo.Server == null ? tableInfo.ProjectFilePath : string.Format("{0} - {1}", tableInfo.Server, tableInfo.Database); var tableParent = tableInfo.Server == null ? tableInfo.ProjectFilePath : string.Format("{0} - {1}", tableInfo.Server, tableInfo.Database);
tableInfo.Tooltip = string.Format("{0} - {1}", tableParent, tableInfo.Title); tableInfo.Tooltip = string.Format("{0} - {1} {2}", tableParent, tableInfo.Title, advancedOps);
} }
private Dictionary<string, string> GetMetadata(TableInfo tableInfo) private Dictionary<string, string> GetMetadata(TableInfo tableInfo)

View File

@@ -56,7 +56,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer
ConnectedBindingContext connectedBindingContext = new ConnectedBindingContext(); ConnectedBindingContext connectedBindingContext = new ConnectedBindingContext();
connectedBindingContext.ServerConnection = new ServerConnection(new SqlConnection(fakeConnectionString)); connectedBindingContext.ServerConnection = new ServerConnection(new SqlConnection(fakeConnectionString));
connectedBindingQueue = new ConnectedBindingQueue(false); connectedBindingQueue = new ConnectedBindingQueue(false);
connectedBindingQueue.BindingContextMap.Add($"{details.ServerName}_{details.DatabaseName}_{details.UserName}_NULL", connectedBindingContext); connectedBindingQueue.BindingContextMap.Add($"{details.ServerName}_{details.DatabaseName}_{details.UserName}_NULL_persistSecurityInfo:true", connectedBindingContext);
connectedBindingQueue.BindingContextTasks.Add(connectedBindingContext, Task.Run(() => null)); connectedBindingQueue.BindingContextTasks.Add(connectedBindingContext, Task.Run(() => null));
mockConnectionOpener = new Mock<SqlConnectionOpener>(); mockConnectionOpener = new Mock<SqlConnectionOpener>();
connectedBindingQueue.SetConnectionOpener(mockConnectionOpener.Object); connectedBindingQueue.SetConnectionOpener(mockConnectionOpener.Object);