From 50195facedb1ab71c26971fb1623bf276458481b Mon Sep 17 00:00:00 2001 From: Sharon Ravindran Date: Fri, 3 Feb 2017 17:50:55 -0800 Subject: [PATCH] Fix to get the current database context for peek definition (#220) * Get db name from query connection * Add comments * Correct typos * revert changes to .sln * Add unit tests * Fix typo * Fix error due to a mistyped comment --- .../LanguageServices/PeekDefinition.cs | 22 ++++++-- .../LanguageServer/PeekDefinitionTests.cs | 51 ++++++++++++++++++- .../LanguageServer/PeekDefinitionTests.cs | 24 ++++----- 3 files changed, 81 insertions(+), 16 deletions(-) diff --git a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinition.cs b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinition.cs index 5c6d2e58..b6233ab2 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinition.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinition.cs @@ -7,7 +7,7 @@ using System.IO; using System.Linq; using System.Collections.Generic; using System.Collections.Specialized; -using System.Data.SqlClient; +using System.Data.Common; using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.SqlParser.Intellisense; @@ -19,6 +19,7 @@ using Microsoft.SqlTools.ServiceLayer.Utility; using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol; using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; using Location = Microsoft.SqlTools.ServiceLayer.Workspace.Contracts.Location; +using ConnectionType = Microsoft.SqlTools.ServiceLayer.Connection.ConnectionType; namespace Microsoft.SqlTools.ServiceLayer.LanguageServices { @@ -61,7 +62,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices Initialize(); } - private Database Database + internal Database Database { get { @@ -73,7 +74,22 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices { // Reuse existing connection Server server = new Server(this.serverConnection); - this.database = new Database(server, this.serverConnection.DatabaseName); + // The default database name is the database name of the server connection + string dbName = this.serverConnection.DatabaseName; + if (this.connectionInfo != null) + { + // If there is a query DbConnection, use that connection to get the database name + // This is preferred since it has the most current database name (in case of database switching) + DbConnection connection; + if (connectionInfo.TryGetConnection(ConnectionType.Query, out connection)) + { + if (!string.IsNullOrEmpty(connection.Database)) + { + dbName = connection.Database; + } + } + } + this.database = new Database(server, dbName); } catch (ConnectionFailureException cfe) { diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/LanguageServer/PeekDefinitionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/LanguageServer/PeekDefinitionTests.cs index 1def2e61..34c7e426 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/LanguageServer/PeekDefinitionTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/LanguageServer/PeekDefinitionTests.cs @@ -3,8 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // using System; +using System.Data.Common; using System.IO; using System.Threading; +using System.Threading.Tasks; using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.SqlParser.Intellisense; using Microsoft.SqlTools.ServiceLayer.Connection; @@ -14,6 +16,7 @@ using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; using Microsoft.SqlTools.Test.Utility; using Moq; using Xunit; +using ConnectionType = Microsoft.SqlTools.ServiceLayer.Connection.ConnectionType; using Location = Microsoft.SqlTools.ServiceLayer.Workspace.Contracts.Location; namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServices @@ -639,7 +642,7 @@ GO"; /// /// Test get definition using quickInfo text for a view object with active connection - /// Expect a non-null result with location + /// Expect a non-null result with location /// [Fact] public void GetDefinitionUsingQuickInfoTextWithNonexistentObjectTest() @@ -657,6 +660,52 @@ GO"; Assert.True(result.IsErrorResult); } + /// + /// Test if peek definition default database name is the default server connection database name + /// Given that there is no query connection + /// Expect database name to be "master" + /// + [Fact] + public void GetDatabaseWithNoQueryConnectionTest() + { + ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition(); + ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo); + DbConnection connection; + //Check if query connection is present + Assert.False(connInfo.TryGetConnection(ConnectionType.Query, out connection)); + + PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo); + //Check if database name is the default server connection database name + Assert.Equal(peekDefinition.Database.Name, "master"); + } + + /// + /// Test if the peek definition database name changes to the query connection database name + /// Give that there is a query connection + /// Expect database name to be query connection's database name + /// + [Fact] + public void GetDatabaseWithQueryConnectionTest() + { + ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition(); + ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo); + //Mock a query connection object + var mockQueryConnection = new Mock { CallBase = true }; + mockQueryConnection.SetupGet(x => x.Database).Returns("testdb"); + connInfo.ConnectionTypeToConnectionMap[ConnectionType.Query] = mockQueryConnection.Object; + DbConnection connection; + //Check if query connection is present + Assert.True(connInfo.TryGetConnection(ConnectionType.Query, out connection)); + + PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo); + //Check if database name is the database name in the query connection + Assert.Equal(peekDefinition.Database.Name, "testdb"); + + // remove mock from ConnectionInfo + Assert.True(connInfo.ConnectionTypeToConnectionMap.TryRemove(ConnectionType.Query, out connection)); + } + + /// /// Helper method to clean up script files /// diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs index d15aed2d..0309ba01 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs @@ -196,7 +196,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices } /// - /// Test Deletion of peek definition scripts for a valid temp folder that exists + /// Test deletion of peek definition scripts for a valid temp folder that exists /// [Fact] public void DeletePeekDefinitionScriptsTest() @@ -209,7 +209,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices } /// - /// Test Deletion of peek definition scripts for a temp folder that does not exist + /// Test deletion of peek definition scripts for a temp folder that does not exist /// [Fact] public void DeletePeekDefinitionScriptsWhenFolderDoesNotExistTest() @@ -223,7 +223,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices } /// - /// Test Extracting the full object name from quickInfoText. + /// Test extracting the full object name from quickInfoText. /// Given a valid object name string and a vaild quickInfo string containing the object name /// Expect the full object name (database.schema.objectName) /// @@ -239,7 +239,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices } /// - /// Test Extracting the full object name from quickInfoText. + /// Test extracting the full object name from quickInfoText. /// Given a null object name string and a vaild quickInfo string containing the object name( and vice versa) /// Expect null /// @@ -266,7 +266,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices } /// - /// Test Extracting the full object name from quickInfoText. + /// Test extracting the full object name from quickInfoText. /// Given a valid object name string and a vaild quickInfo string that does not contain the object name /// Expect null /// @@ -282,7 +282,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices } /// - /// Test Extracting the object type from quickInfoText. + /// Test extracting the object type from quickInfoText. /// Given a valid object name string and a vaild quickInfo string containing the object name /// Expect correct object type /// @@ -298,7 +298,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices } /// - /// Test Extracting theobject type from quickInfoText. + /// Test extracting theobject type from quickInfoText. /// Given a null object name string and a vaild quickInfo string containing the object name( and vice versa) /// Expect null /// @@ -325,7 +325,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices } /// - /// Test Extracting the object type from quickInfoText. + /// Test extracting the object type from quickInfoText. /// Given a valid object name string and a vaild quickInfo string that does not containthe object name /// Expect null /// @@ -341,8 +341,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices } /// - /// test Getting definition using quickInfo text without a live connection - /// Expect an error result( because you cannot script without a live connection) + /// Test getting definition using quickInfo text without a live connection + /// Expect an error result (because you cannot script without a live connection) /// [Fact] public void GetDefinitionUsingQuickInfoWithoutConnectionTest() @@ -356,8 +356,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices } /// - /// test Getting definition using declarration Type without a live connection - /// Expect an error result( because you cannot script without a live connection) + /// Test getting definition using declaration Type without a live connection + /// Expect an error result (because you cannot script without a live connection) /// [Fact] public void GetDefinitionUsingDeclarationItemWithoutConnectionTest()