From ccad4e1f8fa6fcd20bf4b499a4ebf94637f92272 Mon Sep 17 00:00:00 2001 From: Karl Burtram Date: Thu, 27 Apr 2023 09:03:18 -0700 Subject: [PATCH] Remove extra connection in User dialog (#2033) * Remove extra connection in User dialog * Remove a couple unneeded queries --- .../ObjectTypes/Security/UserData.cs | 26 +++++------ .../ObjectTypes/User/UserHandler.cs | 46 ++++++------------- 2 files changed, 28 insertions(+), 44 deletions(-) diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Security/UserData.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Security/UserData.cs index 47b84186..ee90fafa 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Security/UserData.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Security/UserData.cs @@ -278,17 +278,17 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement /// private void LoadRoleMembership(CDataContainer context, UserInfo? userInfo) { - Urn objUrn = new Urn(context.ObjectUrn); - Urn databaseUrn = objUrn.Parent; - - Database? parentDb = context.Server.GetSmoObject(databaseUrn) as Database; + Database? parentDb = context.Server.GetSmoObject(context.ParentUrn) as Database; if (parentDb == null) { return; } - string userName = userInfo?.Name ?? objUrn.GetNameForType("User"); - User existingUser = context.Server.Databases[parentDb.Name].Users[userName]; + User? existingUser = null; + if (!string.IsNullOrEmpty(userInfo?.Name)) + { + existingUser = context.Server.Databases[parentDb.Name].Users[userInfo?.Name]; + } foreach (DatabaseRole dbRole in parentDb.Roles) { @@ -316,18 +316,18 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement /// /// private void LoadSchemaData(CDataContainer context, UserInfo? userInfo) - { - Urn objUrn = new Urn(context.ObjectUrn); - Urn databaseUrn = objUrn.Parent; - - Database? parentDb = context.Server.GetSmoObject(databaseUrn) as Database; + { + Database? parentDb = context.Server.GetSmoObject(context.ParentUrn) as Database; if (parentDb == null) { return; } - string userName = userInfo?.Name ?? objUrn.GetNameForType("User"); - User existingUser = context.Server.Databases[parentDb.Name].Users[userName]; + User? existingUser = null; + if (!string.IsNullOrEmpty(userInfo?.Name)) + { + existingUser = context.Server.Databases[parentDb.Name].Users[userInfo?.Name]; + } if (!SqlMgmtUtils.IsYukonOrAbove(context.Server) || parentDb.CompatibilityLevel <= CompatibilityLevel.Version80) diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/User/UserHandler.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/User/UserHandler.cs index d07e504e..45e7e949 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/User/UserHandler.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/User/UserHandler.cs @@ -13,7 +13,6 @@ using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.Sdk.Sfc; using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlTools.ServiceLayer.Connection; -using Microsoft.SqlTools.ServiceLayer.Connection.Contracts; using Microsoft.SqlTools.ServiceLayer.Management; using Microsoft.SqlTools.ServiceLayer.Utility; @@ -49,26 +48,20 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement throw new ArgumentException("Invalid connection URI '{0}'", parameters.ConnectionUri); } string originalDatabaseName = originalConnInfo.ConnectionDetails.DatabaseName; + originalConnInfo.ConnectionDetails.DatabaseName = parameters.Database; + + // create a default user data context and database object + CDataContainer dataContainer; try { - originalConnInfo.ConnectionDetails.DatabaseName = parameters.Database; - ConnectParams connectParams = new ConnectParams - { - OwnerUri = parameters.ContextId, - Connection = originalConnInfo.ConnectionDetails, - Type = Connection.ConnectionType.Default - }; - await this.ConnectionService.Connect(connectParams); + ServerConnection serverConnection = ConnectionService.OpenServerConnection(originalConnInfo, "DataContainer"); + dataContainer = CreateUserDataContainer(serverConnection, null, ConfigAction.Create, parameters.Database); } finally { 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, "Server/Database[@Name='{0}']", Urn.EscapeString(parameters.Database)); Database parentDb = dataContainer.Server.GetSmoObject(databaseUrn) as Database; @@ -122,8 +115,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement defaultSchema = defaultSchemaPrototype.DefaultSchema; } - ServerConnection serverConnection = dataContainer.ServerConnection; - bool isSqlAzure = serverConnection.DatabaseEngineType == DatabaseEngineType.SqlAzureDatabase; + bool isSqlAzure = dataContainer.ServerConnection.DatabaseEngineType == DatabaseEngineType.SqlAzureDatabase; bool supportsContainedUser = isSqlAzure || UserActions.IsParentDatabaseContained(parentDb); // set the fake password placeholder when editing an existing user @@ -196,17 +188,17 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement SupportSQLAuthentication = true, Languages = languageOptionsList.ToArray(), Schemas = currentUserPrototype.SchemaNames.ToArray(), - Logins = DatabaseUtils.LoadSqlLogins(serverConnection), + Logins = DatabaseUtils.LoadSqlLogins(dataContainer.ServerConnection), 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 }; } public override Task Save(UserViewContext context, UserInfo obj) { ConfigureUser( - context.Parameters.ContextId, + context.Connection, obj, context.Parameters.IsNewObject ? ConfigAction.Create : ConfigAction.Update, RunType.RunNow, @@ -218,7 +210,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement public override Task Script(UserViewContext context, UserInfo obj) { var script = ConfigureUser( - context.Parameters.ContextId, + context.Connection, obj, context.Parameters.IsNewObject ? ConfigAction.Create : ConfigAction.Update, RunType.ScriptToWindow, @@ -227,9 +219,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement 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(); connectionInfoWithConnection.ServerConnection = serverConnection; @@ -254,17 +245,10 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement return CDataContainer.CreateDataContainer(connectionInfoWithConnection, xmlDoc); } - internal string ConfigureUser(string ownerUri, 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); - } - + internal string ConfigureUser(ServerConnection serverConnection, UserInfo user, ConfigAction configAction, RunType runType, string databaseName, UserPrototypeData originalData) + { 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)) { var executionHandler = new ExecutonHandler(actions);