Remove extra connection in User dialog (#2033)

* Remove extra connection in User dialog

* Remove a couple unneeded queries
This commit is contained in:
Karl Burtram
2023-04-27 09:03:18 -07:00
committed by GitHub
parent 537c78dbb0
commit ccad4e1f8f
2 changed files with 28 additions and 44 deletions

View File

@@ -278,17 +278,17 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
/// <param name="context"></param> /// <param name="context"></param>
private void LoadRoleMembership(CDataContainer context, UserInfo? userInfo) private void LoadRoleMembership(CDataContainer context, UserInfo? userInfo)
{ {
Urn objUrn = new Urn(context.ObjectUrn); Database? parentDb = context.Server.GetSmoObject(context.ParentUrn) as Database;
Urn databaseUrn = objUrn.Parent;
Database? parentDb = context.Server.GetSmoObject(databaseUrn) as Database;
if (parentDb == null) if (parentDb == null)
{ {
return; return;
} }
string userName = userInfo?.Name ?? objUrn.GetNameForType("User"); User? existingUser = null;
User existingUser = context.Server.Databases[parentDb.Name].Users[userName]; if (!string.IsNullOrEmpty(userInfo?.Name))
{
existingUser = context.Server.Databases[parentDb.Name].Users[userInfo?.Name];
}
foreach (DatabaseRole dbRole in parentDb.Roles) foreach (DatabaseRole dbRole in parentDb.Roles)
{ {
@@ -316,18 +316,18 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
private void LoadSchemaData(CDataContainer context, UserInfo? userInfo) private void LoadSchemaData(CDataContainer context, UserInfo? userInfo)
{ {
Urn objUrn = new Urn(context.ObjectUrn); Database? parentDb = context.Server.GetSmoObject(context.ParentUrn) as Database;
Urn databaseUrn = objUrn.Parent;
Database? parentDb = context.Server.GetSmoObject(databaseUrn) as Database;
if (parentDb == null) if (parentDb == null)
{ {
return; return;
} }
string userName = userInfo?.Name ?? objUrn.GetNameForType("User"); User? existingUser = null;
User existingUser = context.Server.Databases[parentDb.Name].Users[userName]; if (!string.IsNullOrEmpty(userInfo?.Name))
{
existingUser = context.Server.Databases[parentDb.Name].Users[userInfo?.Name];
}
if (!SqlMgmtUtils.IsYukonOrAbove(context.Server) if (!SqlMgmtUtils.IsYukonOrAbove(context.Server)
|| parentDb.CompatibilityLevel <= CompatibilityLevel.Version80) || parentDb.CompatibilityLevel <= CompatibilityLevel.Version80)

View File

@@ -13,7 +13,6 @@ using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Sdk.Sfc; using Microsoft.SqlServer.Management.Sdk.Sfc;
using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
using Microsoft.SqlTools.ServiceLayer.Management; using Microsoft.SqlTools.ServiceLayer.Management;
using Microsoft.SqlTools.ServiceLayer.Utility; using Microsoft.SqlTools.ServiceLayer.Utility;
@@ -49,26 +48,20 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
throw new ArgumentException("Invalid connection URI '{0}'", parameters.ConnectionUri); throw new ArgumentException("Invalid connection URI '{0}'", parameters.ConnectionUri);
} }
string originalDatabaseName = originalConnInfo.ConnectionDetails.DatabaseName; string originalDatabaseName = originalConnInfo.ConnectionDetails.DatabaseName;
originalConnInfo.ConnectionDetails.DatabaseName = parameters.Database;
// create a default user data context and database object
CDataContainer dataContainer;
try try
{ {
originalConnInfo.ConnectionDetails.DatabaseName = parameters.Database; ServerConnection serverConnection = ConnectionService.OpenServerConnection(originalConnInfo, "DataContainer");
ConnectParams connectParams = new ConnectParams dataContainer = CreateUserDataContainer(serverConnection, null, ConfigAction.Create, parameters.Database);
{
OwnerUri = parameters.ContextId,
Connection = originalConnInfo.ConnectionDetails,
Type = Connection.ConnectionType.Default
};
await this.ConnectionService.Connect(connectParams);
} }
finally finally
{ {
originalConnInfo.ConnectionDetails.DatabaseName = originalDatabaseName; originalConnInfo.ConnectionDetails.DatabaseName = originalDatabaseName;
} }
ConnectionInfo connInfo;
this.ConnectionService.TryFindConnection(parameters.ContextId, out connInfo);
// create a default user data context and database object
CDataContainer dataContainer = CreateUserDataContainer(connInfo, null, ConfigAction.Create, parameters.Database);
string databaseUrn = string.Format(System.Globalization.CultureInfo.InvariantCulture, string databaseUrn = string.Format(System.Globalization.CultureInfo.InvariantCulture,
"Server/Database[@Name='{0}']", Urn.EscapeString(parameters.Database)); "Server/Database[@Name='{0}']", Urn.EscapeString(parameters.Database));
Database parentDb = dataContainer.Server.GetSmoObject(databaseUrn) as Database; Database parentDb = dataContainer.Server.GetSmoObject(databaseUrn) as Database;
@@ -122,8 +115,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
defaultSchema = defaultSchemaPrototype.DefaultSchema; defaultSchema = defaultSchemaPrototype.DefaultSchema;
} }
ServerConnection serverConnection = dataContainer.ServerConnection; bool isSqlAzure = dataContainer.ServerConnection.DatabaseEngineType == DatabaseEngineType.SqlAzureDatabase;
bool isSqlAzure = serverConnection.DatabaseEngineType == DatabaseEngineType.SqlAzureDatabase;
bool supportsContainedUser = isSqlAzure || UserActions.IsParentDatabaseContained(parentDb); bool supportsContainedUser = isSqlAzure || UserActions.IsParentDatabaseContained(parentDb);
// set the fake password placeholder when editing an existing user // set the fake password placeholder when editing an existing user
@@ -196,17 +188,17 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
SupportSQLAuthentication = true, SupportSQLAuthentication = true,
Languages = languageOptionsList.ToArray(), Languages = languageOptionsList.ToArray(),
Schemas = currentUserPrototype.SchemaNames.ToArray(), Schemas = currentUserPrototype.SchemaNames.ToArray(),
Logins = DatabaseUtils.LoadSqlLogins(serverConnection), Logins = DatabaseUtils.LoadSqlLogins(dataContainer.ServerConnection),
DatabaseRoles = currentUserPrototype.DatabaseRoleNames.ToArray() DatabaseRoles = currentUserPrototype.DatabaseRoleNames.ToArray()
}; };
var context = new UserViewContext(parameters, serverConnection, currentUserPrototype.CurrentState); var context = new UserViewContext(parameters, dataContainer.ServerConnection, currentUserPrototype.CurrentState);
return new InitializeViewResult { ViewInfo = userViewInfo, Context = context }; return new InitializeViewResult { ViewInfo = userViewInfo, Context = context };
} }
public override Task Save(UserViewContext context, UserInfo obj) public override Task Save(UserViewContext context, UserInfo obj)
{ {
ConfigureUser( ConfigureUser(
context.Parameters.ContextId, context.Connection,
obj, obj,
context.Parameters.IsNewObject ? ConfigAction.Create : ConfigAction.Update, context.Parameters.IsNewObject ? ConfigAction.Create : ConfigAction.Update,
RunType.RunNow, RunType.RunNow,
@@ -218,7 +210,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
public override Task<string> Script(UserViewContext context, UserInfo obj) public override Task<string> Script(UserViewContext context, UserInfo obj)
{ {
var script = ConfigureUser( var script = ConfigureUser(
context.Parameters.ContextId, context.Connection,
obj, obj,
context.Parameters.IsNewObject ? ConfigAction.Create : ConfigAction.Update, context.Parameters.IsNewObject ? ConfigAction.Create : ConfigAction.Update,
RunType.ScriptToWindow, RunType.ScriptToWindow,
@@ -227,9 +219,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
return Task.FromResult(script); return Task.FromResult(script);
} }
internal CDataContainer CreateUserDataContainer(ConnectionInfo connInfo, UserInfo user, ConfigAction configAction, string databaseName) internal CDataContainer CreateUserDataContainer(ServerConnection serverConnection, UserInfo user, ConfigAction configAction, string databaseName)
{ {
var serverConnection = ConnectionService.OpenServerConnection(connInfo, "DataContainer");
var connectionInfoWithConnection = new SqlConnectionInfoWithConnection(); var connectionInfoWithConnection = new SqlConnectionInfoWithConnection();
connectionInfoWithConnection.ServerConnection = serverConnection; connectionInfoWithConnection.ServerConnection = serverConnection;
@@ -254,17 +245,10 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
return CDataContainer.CreateDataContainer(connectionInfoWithConnection, xmlDoc); return CDataContainer.CreateDataContainer(connectionInfoWithConnection, xmlDoc);
} }
internal string ConfigureUser(string ownerUri, UserInfo user, ConfigAction configAction, RunType runType, string databaseName, UserPrototypeData originalData) internal string ConfigureUser(ServerConnection serverConnection, UserInfo user, ConfigAction configAction, RunType runType, string databaseName, UserPrototypeData originalData)
{ {
ConnectionInfo connInfo;
this.ConnectionService.TryFindConnection(ownerUri, out connInfo);
if (connInfo == null)
{
throw new ArgumentException("Invalid connection URI '{0}'", ownerUri);
}
string sqlScript = string.Empty; string sqlScript = string.Empty;
CDataContainer dataContainer = CreateUserDataContainer(connInfo, user, configAction, databaseName); CDataContainer dataContainer = CreateUserDataContainer(serverConnection, user, configAction, databaseName);
using (var actions = new UserActions(dataContainer, configAction, user, originalData)) using (var actions = new UserActions(dataContainer, configAction, user, originalData))
{ {
var executionHandler = new ExecutonHandler(actions); var executionHandler = new ExecutonHandler(actions);