mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-16 18:47:57 -05:00
FIx intellisense cache not refreshing (#831)
* FIx intellisense cache not refreshing * Remove extra newlines * Output label to provide more useful information in case of error
This commit is contained in:
@@ -26,7 +26,7 @@ namespace Microsoft.SqlTools.Hosting.Protocol
|
|||||||
this.messageWriter = messageWriter;
|
this.messageWriter = messageWriter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendEvent<TParams>(
|
public virtual async Task SendEvent<TParams>(
|
||||||
EventType<TParams> eventType,
|
EventType<TParams> eventType,
|
||||||
TParams eventParams)
|
TParams eventParams)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -628,6 +628,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
{
|
{
|
||||||
await Task.Run(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
|
// Get the current ScriptInfo if one exists so we can lock it while we're rebuilding the cache
|
||||||
ScriptParseInfo scriptInfo = GetScriptParseInfo(connInfo.OwnerUri, createIfNotExists: false);
|
ScriptParseInfo scriptInfo = GetScriptParseInfo(connInfo.OwnerUri, createIfNotExists: false);
|
||||||
if (scriptInfo != null && scriptInfo.IsConnected &&
|
if (scriptInfo != null && scriptInfo.IsConnected &&
|
||||||
Monitor.TryEnter(scriptInfo.BuildingMetadataLock, LanguageService.OnConnectionWaitTimeout))
|
Monitor.TryEnter(scriptInfo.BuildingMetadataLock, LanguageService.OnConnectionWaitTimeout))
|
||||||
@@ -635,6 +636,8 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.BindingQueue.AddConnectionContext(connInfo, featureName: "LanguageService", overwrite: true);
|
this.BindingQueue.AddConnectionContext(connInfo, featureName: "LanguageService", overwrite: true);
|
||||||
|
RemoveScriptParseInfo(rebuildParams.OwnerUri);
|
||||||
|
UpdateLanguageServiceOnConnection(connInfo).Wait();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
|
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
|
||||||
@@ -157,5 +158,63 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer
|
|||||||
Assert.True(LanguageService.Instance.BindingQueue.BindingContextMap.ContainsKey(connectionKey));
|
Assert.True(LanguageService.Instance.BindingQueue.BindingContextMap.ContainsKey(connectionKey));
|
||||||
Assert.False(object.ReferenceEquals(LanguageService.Instance.BindingQueue.BindingContextMap[connectionKey].ServerConnection, orgServerConnection));
|
Assert.False(object.ReferenceEquals(LanguageService.Instance.BindingQueue.BindingContextMap[connectionKey].ServerConnection, orgServerConnection));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that clearing the Intellisense cache correctly refreshes the cache with new info from the DB.
|
||||||
|
/// </summary>
|
||||||
|
[Fact]
|
||||||
|
public async Task RebuildIntellisenseCacheClearsScriptParseInfoCorrectly()
|
||||||
|
{
|
||||||
|
var testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, null, null, "LangSvcTest");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var connectionInfoResult = LiveConnectionHelper.InitLiveConnectionInfo(testDb.DatabaseName);
|
||||||
|
|
||||||
|
var langService = LanguageService.Instance;
|
||||||
|
await langService.UpdateLanguageServiceOnConnection(connectionInfoResult.ConnectionInfo);
|
||||||
|
var queryText = "SELECT * FROM dbo.";
|
||||||
|
connectionInfoResult.ScriptFile.SetFileContents(queryText);
|
||||||
|
|
||||||
|
var textDocumentPosition =
|
||||||
|
connectionInfoResult.TextDocumentPosition ??
|
||||||
|
new TextDocumentPosition()
|
||||||
|
{
|
||||||
|
TextDocument = new TextDocumentIdentifier
|
||||||
|
{
|
||||||
|
Uri = connectionInfoResult.ScriptFile.ClientFilePath
|
||||||
|
},
|
||||||
|
Position = new Position
|
||||||
|
{
|
||||||
|
Line = 0,
|
||||||
|
Character = queryText.Length
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// First check that we don't have any items in the completion list as expected
|
||||||
|
var initialCompletionItems = langService.GetCompletionItems(
|
||||||
|
textDocumentPosition, connectionInfoResult.ScriptFile, connectionInfoResult.ConnectionInfo);
|
||||||
|
|
||||||
|
Assert.True(initialCompletionItems.Length == 0, $"Should not have any completion items initially. Actual : [{string.Join(',', initialCompletionItems.Select(ci => ci.Label))}]");
|
||||||
|
|
||||||
|
// Now create a table that should show up in the completion list
|
||||||
|
testDb.RunQuery("CREATE TABLE dbo.foo(col1 int)");
|
||||||
|
|
||||||
|
// And refresh the cache
|
||||||
|
await langService.HandleRebuildIntelliSenseNotification(
|
||||||
|
new RebuildIntelliSenseParams() { OwnerUri = connectionInfoResult.ScriptFile.ClientFilePath },
|
||||||
|
new TestEventContext());
|
||||||
|
|
||||||
|
// Now we should expect to see the item show up in the completion list
|
||||||
|
var afterTableCreationCompletionItems = langService.GetCompletionItems(
|
||||||
|
textDocumentPosition, connectionInfoResult.ScriptFile, connectionInfoResult.ConnectionInfo);
|
||||||
|
|
||||||
|
Assert.True(afterTableCreationCompletionItems.Length == 1, $"Should only have a single completion item after rebuilding Intellisense cache. Actual : [{string.Join(',', initialCompletionItems.Select(ci => ci.Label))}]");
|
||||||
|
Assert.True(afterTableCreationCompletionItems[0].InsertText == "foo", $"Expected single completion item 'foo'. Actual : [{string.Join(',', initialCompletionItems.Select(ci => ci.Label))}]");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
testDb.Cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.SqlTools.Hosting.Protocol;
|
||||||
|
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
||||||
|
|
||||||
|
namespace Microsoft.SqlTools.ServiceLayer.Test.Common
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Simple EventContext for testing that just swallows all events.
|
||||||
|
/// </summary>
|
||||||
|
public class TestEventContext : EventContext
|
||||||
|
{
|
||||||
|
public override async Task SendEvent<TParams>(
|
||||||
|
EventType<TParams> eventType,
|
||||||
|
TParams eventParams)
|
||||||
|
{
|
||||||
|
await Task.FromResult(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user