diff --git a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinition.cs b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinition.cs
index b6233ab2..edfcd694 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinition.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinition.cs
@@ -72,10 +72,10 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
{
try
{
- // Reuse existing connection
+ // Reuse existing connection
Server server = new Server(this.serverConnection);
// The default database name is the database name of the server connection
- string dbName = this.serverConnection.DatabaseName;
+ string dbName = this.serverConnection.DatabaseName;
if (this.connectionInfo != null)
{
// If there is a query DbConnection, use that connection to get the database name
@@ -86,10 +86,11 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
if (!string.IsNullOrEmpty(connection.Database))
{
dbName = connection.Database;
- }
- }
+ }
+ }
}
this.database = new Database(server, dbName);
+ this.database.Refresh();
}
catch (ConnectionFailureException cfe)
{
@@ -146,8 +147,13 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
{
continue;
}
- // if declarartionItem matches the selected token, script SMO using that type
- if (declarationItem.Title.Equals(tokenText))
+ if (this.Database == null)
+ {
+ return GetDefinitionErrorResult(SR.PeekDefinitionDatabaseError);
+ }
+ StringComparison caseSensitivity = this.Database.CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
+ // if declarationItem matches the selected token, script SMO using that type
+ if (declarationItem.Title.Equals (tokenText, caseSensitivity))
{
return GetDefinitionUsingDeclarationType(declarationItem.Type, declarationItem.DatabaseQualifiedName, tokenText, schemaName);
}
@@ -172,7 +178,12 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
///
internal DefinitionResult GetDefinitionUsingQuickInfoText(string quickInfoText, string tokenText, string schemaName)
{
- string tokenType = GetTokenTypeFromQuickInfo(quickInfoText, tokenText);
+ if (this.Database == null)
+ {
+ return GetDefinitionErrorResult(SR.PeekDefinitionDatabaseError);
+ }
+ StringComparison caseSensitivity = this.Database.CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
+ string tokenType = GetTokenTypeFromQuickInfo(quickInfoText, tokenText, caseSensitivity);
if (tokenType != null)
{
if (sqlScriptGettersFromQuickInfo.ContainsKey(tokenType.ToLowerInvariant()))
@@ -183,7 +194,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
// If all fails, the default schema name is assumed to be "dbo"
if ((connectionInfo != null && connectionInfo.ConnectionDetails.AuthenticationType.Equals(Constants.SqlLoginAuthenticationType)) && string.IsNullOrEmpty(schemaName))
{
- string fullObjectName = this.GetFullObjectNameFromQuickInfo(quickInfoText, tokenText);
+ string fullObjectName = this.GetFullObjectNameFromQuickInfo(quickInfoText, tokenText, caseSensitivity);
schemaName = this.GetSchemaFromDatabaseQualifiedName(fullObjectName, tokenText);
}
Location[] locations = GetSqlObjectDefinition(
@@ -377,8 +388,9 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
///
/// QuickInfo Text for this token
/// Token Text
+ /// StringComparison enum
///
- internal string GetFullObjectNameFromQuickInfo(string quickInfoText, string tokenText)
+ internal string GetFullObjectNameFromQuickInfo(string quickInfoText, string tokenText, StringComparison caseSensitivity)
{
if (string.IsNullOrEmpty(quickInfoText) || string.IsNullOrEmpty(tokenText))
{
@@ -386,7 +398,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
}
// extract full object name from quickInfo text
string[] tokens = quickInfoText.Split(' ');
- List tokenList = tokens.Where(el => el.Contains(tokenText)).ToList();
+ List tokenList = tokens.Where(el => el.IndexOf(tokenText, caseSensitivity) >= 0).ToList();
return (tokenList?.Count() > 0) ? tokenList[0] : null;
}
@@ -395,8 +407,9 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
///
/// QuickInfo Text for this token
///
+ /// StringComparison enum
///
- internal string GetTokenTypeFromQuickInfo(string quickInfoText, string tokenText)
+ internal string GetTokenTypeFromQuickInfo(string quickInfoText, string tokenText, StringComparison caseSensitivity)
{
if (string.IsNullOrEmpty(quickInfoText) || string.IsNullOrEmpty(tokenText))
{
@@ -404,7 +417,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
}
// extract string denoting the token type from quickInfo text
string[] tokens = quickInfoText.Split(' ');
- List indexList = tokens.Select((s, i) => new { i, s }).Where(el => (el.s).Contains(tokenText)).Select(el => el.i).ToList();
+ List indexList = tokens.Select((s, i) => new { i, s }).Where(el => (el.s).IndexOf(tokenText, caseSensitivity) >= 0 ).Select(el => el.i).ToList();
return (indexList?.Count() > 0) ? String.Join(" ", tokens.Take(indexList[0])) : null;
}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/sr.cs b/src/Microsoft.SqlTools.ServiceLayer/sr.cs
index 78d207e2..f45c58a1 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/sr.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/sr.cs
@@ -381,6 +381,14 @@ namespace Microsoft.SqlTools.ServiceLayer
}
}
+ public static string PeekDefinitionDatabaseError
+ {
+ get
+ {
+ return Keys.GetString(Keys.PeekDefinitionDatabaseError);
+ }
+ }
+
public static string PeekDefinitionNotConnectedError
{
get
@@ -643,6 +651,9 @@ namespace Microsoft.SqlTools.ServiceLayer
public const string PeekDefinitionNoResultsError = "PeekDefinitionNoResultsError";
+ public const string PeekDefinitionDatabaseError = "PeekDefinitionDatabaseError";
+
+
public const string PeekDefinitionNotConnectedError = "PeekDefinitionNotConnectedError";
diff --git a/src/Microsoft.SqlTools.ServiceLayer/sr.resx b/src/Microsoft.SqlTools.ServiceLayer/sr.resx
index 49f0cd01..f50b8318 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/sr.resx
+++ b/src/Microsoft.SqlTools.ServiceLayer/sr.resx
@@ -343,6 +343,10 @@
No results were found.
+
+ No database object was retrieved.
+
+
Please connect to a server.
diff --git a/src/Microsoft.SqlTools.ServiceLayer/sr.strings b/src/Microsoft.SqlTools.ServiceLayer/sr.strings
index ff627a91..13a58333 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/sr.strings
+++ b/src/Microsoft.SqlTools.ServiceLayer/sr.strings
@@ -160,6 +160,8 @@ PeekDefinitionError(string errorMessage) = An unexpected error occurred during P
PeekDefinitionNoResultsError = No results were found.
+PeekDefinitionDatabaseError = No database object was retrieved.
+
PeekDefinitionNotConnectedError = Please connect to a server.
PeekDefinitionTimedoutError = Operation timed out.
diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/LanguageServer/PeekDefinitionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/LanguageServer/PeekDefinitionTests.cs
index 34c7e426..65f0fa72 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/LanguageServer/PeekDefinitionTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/LanguageServer/PeekDefinitionTests.cs
@@ -29,24 +29,24 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServices
private const string OwnerUri = "testFile1";
private const string ReturnTableFunctionName = "pd_returnTable";
private const string ReturnTableTableFunctionQuery = @"
-CREATE FUNCTION [dbo].[" + ReturnTableFunctionName + @"] ()
-RETURNS TABLE
-AS
-RETURN
-(
- select * from master.dbo.spt_monitor
-);
+CREATE FUNCTION [dbo].[" + ReturnTableFunctionName + @"] ()
+RETURNS TABLE
+AS
+RETURN
+(
+ select * from master.dbo.spt_monitor
+);
GO";
private const string AddTwoFunctionName = "pd_addTwo";
private const string AddTwoFunctionQuery = @"
-CREATE FUNCTION[dbo].[" + AddTwoFunctionName + @"](@number int)
+CREATE FUNCTION[dbo].[" + AddTwoFunctionName + @"](@number int)
RETURNS int
-AS
+AS
BEGIN
RETURN @number + 2;
- END;
+ END;
GO";
@@ -147,11 +147,14 @@ GO";
/// Test GetDefinition with an unsupported type(schema - dbo). Expect a error result.
///
[Fact]
- public void GetUnsupportedDefinitionErrorTest()
+ public async Task GetUnsupportedDefinitionErrorTest()
{
+ TestConnectionResult connectionResult = TestObjects.InitLiveConnectionInfo();
+ connectionResult.ScriptFile.Contents = "select * from dbo.func ()";
+ string ownerUri = connectionResult.ScriptFile.ClientFilePath;
TextDocumentPosition textDocument = new TextDocumentPosition
{
- TextDocument = new TextDocumentIdentifier { Uri = OwnerUri },
+ TextDocument = new TextDocumentIdentifier { Uri = ownerUri },
Position = new Position
{
Line = 0,
@@ -159,17 +162,16 @@ GO";
Character = 15
}
};
-
- TestConnectionResult connectionResult = TestObjects.InitLiveConnectionInfo();
- connectionResult.ScriptFile.Contents = "select * from dbo.func ()";
- var languageService = new LanguageService();
- ScriptParseInfo scriptInfo = new ScriptParseInfo { IsConnected = true };
- languageService.ScriptParseInfoMap.Add(OwnerUri, scriptInfo);
+ connectionResult.TextDocumentPosition = textDocument;
+ var languageService = LanguageService.Instance;
+ await languageService.UpdateLanguageServiceOnConnection(connectionResult.ConnectionInfo);
+ ScriptParseInfo parseInfo = languageService.GetScriptParseInfo(connectionResult.ScriptFile.ClientFilePath);
+ Assert.NotNull(parseInfo);
// When I call the language service
var result = languageService.GetDefinition(textDocument, connectionResult.ScriptFile, connectionResult.ConnectionInfo);
- // Then I expect null locations and an error to be reported
+ // Then I expect non null result with error flag set
Assert.NotNull(result);
Assert.True(result.IsErrorResult);
}
@@ -642,7 +644,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()
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs
index 0309ba01..e75948b9 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs
@@ -233,7 +233,23 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
PeekDefinition peekDefinition = new PeekDefinition(null, null);
string objectName = "testTable";
string quickInfoText = "table master.dbo.testTable";
- string result = peekDefinition.GetFullObjectNameFromQuickInfo(quickInfoText, objectName);
+ string result = peekDefinition.GetFullObjectNameFromQuickInfo(quickInfoText, objectName, StringComparison.Ordinal);
+ string expected = "master.dbo.testTable";
+ Assert.Equal(expected, result);
+ }
+
+ ///
+ /// Test extracting the full object name from quickInfoText with case insensitive comparison.
+ /// Given a valid object name string and a vaild quickInfo string containing the object name
+ /// Expect the full object name (database.schema.objectName)
+ ///
+ [Fact]
+ public void GetFullObjectNameFromQuickInfoWithValidStringsandIgnoreCaseTest()
+ {
+ PeekDefinition peekDefinition = new PeekDefinition(null, null);
+ string objectName = "testtable";
+ string quickInfoText = "table master.dbo.testTable";
+ string result = peekDefinition.GetFullObjectNameFromQuickInfo(quickInfoText, objectName, StringComparison.OrdinalIgnoreCase);
string expected = "master.dbo.testTable";
Assert.Equal(expected, result);
}
@@ -251,17 +267,17 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
string objectName = null;
string quickInfoText = "table master.dbo.testTable";
- string result = peekDefinition.GetFullObjectNameFromQuickInfo(quickInfoText, objectName);
+ string result = peekDefinition.GetFullObjectNameFromQuickInfo(quickInfoText, objectName, StringComparison.Ordinal);
Assert.Equal(expected, result);
quickInfoText = null;
objectName = "tableName";
- result = peekDefinition.GetFullObjectNameFromQuickInfo(quickInfoText, objectName);
+ result = peekDefinition.GetFullObjectNameFromQuickInfo(quickInfoText, objectName, StringComparison.Ordinal);
Assert.Equal(expected, result);
quickInfoText = null;
objectName = null;
- result = peekDefinition.GetFullObjectNameFromQuickInfo(quickInfoText, objectName);
+ result = peekDefinition.GetFullObjectNameFromQuickInfo(quickInfoText, objectName, StringComparison.Ordinal);
Assert.Equal(expected, result);
}
@@ -276,7 +292,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
PeekDefinition peekDefinition = new PeekDefinition(null, null);
string objectName = "test";
string quickInfoText = "table master.dbo.tableName";
- string result = peekDefinition.GetFullObjectNameFromQuickInfo(quickInfoText, objectName);
+ string result = peekDefinition.GetFullObjectNameFromQuickInfo(quickInfoText, objectName, StringComparison.Ordinal);
string expected = null;
Assert.Equal(expected, result);
}
@@ -292,7 +308,24 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
PeekDefinition peekDefinition = new PeekDefinition(null, null);
string objectName = "tableName";
string quickInfoText = "table master.dbo.tableName";
- string result = peekDefinition.GetTokenTypeFromQuickInfo(quickInfoText, objectName);
+ string result = peekDefinition.GetTokenTypeFromQuickInfo(quickInfoText, objectName, StringComparison.Ordinal);
+ string expected = "table";
+ Assert.Equal(expected, result);
+ }
+
+
+ ///
+ /// Test extracting the object type from quickInfoText with case insensitive comparison.
+ /// Given a valid object name string and a vaild quickInfo string containing the object name
+ /// Expect correct object type
+ ///
+ [Fact]
+ public void GetTokenTypeFromQuickInfoWithValidStringsandIgnoreCaseTest()
+ {
+ PeekDefinition peekDefinition = new PeekDefinition(null, null);
+ string objectName = "tablename";
+ string quickInfoText = "table master.dbo.tableName";
+ string result = peekDefinition.GetTokenTypeFromQuickInfo(quickInfoText, objectName, StringComparison.OrdinalIgnoreCase);
string expected = "table";
Assert.Equal(expected, result);
}
@@ -310,17 +343,17 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
string objectName = null;
string quickInfoText = "table master.dbo.testTable";
- string result = peekDefinition.GetTokenTypeFromQuickInfo(quickInfoText, objectName);
+ string result = peekDefinition.GetTokenTypeFromQuickInfo(quickInfoText, objectName, StringComparison.Ordinal);
Assert.Equal(expected, result);
quickInfoText = null;
objectName = "tableName";
- result = peekDefinition.GetTokenTypeFromQuickInfo(quickInfoText, objectName);
+ result = peekDefinition.GetTokenTypeFromQuickInfo(quickInfoText, objectName, StringComparison.Ordinal);
Assert.Equal(expected, result);
quickInfoText = null;
objectName = null;
- result = peekDefinition.GetTokenTypeFromQuickInfo(quickInfoText, objectName);
+ result = peekDefinition.GetTokenTypeFromQuickInfo(quickInfoText, objectName, StringComparison.Ordinal);
Assert.Equal(expected, result);
}
@@ -335,7 +368,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
PeekDefinition peekDefinition = new PeekDefinition(null, null);
string objectName = "test";
string quickInfoText = "table master.dbo.tableName";
- string result = peekDefinition.GetTokenTypeFromQuickInfo(quickInfoText, objectName);
+ string result = peekDefinition.GetTokenTypeFromQuickInfo(quickInfoText, objectName, StringComparison.Ordinal);
string expected = null;
Assert.Equal(expected, result);
}