mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-09 09:42:35 -05:00
120 lines
4.4 KiB
C#
120 lines
4.4 KiB
C#
//
|
|
// Copyright (c) Microsoft. All rights reserved.
|
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
//
|
|
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Data.Common;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.SqlTools.ServiceLayer.Connection;
|
|
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
|
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
|
|
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
|
|
|
|
namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|
{
|
|
|
|
internal class IntellisenseCache
|
|
{
|
|
// connection used to query for intellisense info
|
|
private DbConnection connection;
|
|
|
|
// number of documents (URI's) that are using the cache for the same database
|
|
// the autocomplete service uses this to remove unreferenced caches
|
|
public int ReferenceCount { get; set; }
|
|
|
|
public IntellisenseCache(ISqlConnectionFactory connectionFactory, ConnectionDetails connectionDetails)
|
|
{
|
|
ReferenceCount = 0;
|
|
DatabaseInfo = connectionDetails.Clone();
|
|
|
|
// TODO error handling on this. Intellisense should catch or else the service should handle
|
|
connection = connectionFactory.CreateSqlConnection(ConnectionService.BuildConnectionString(connectionDetails));
|
|
connection.Open();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Used to identify a database for which this cache is used
|
|
/// </summary>
|
|
public ConnectionSummary DatabaseInfo
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
/// <summary>
|
|
/// Gets the current autocomplete candidate list
|
|
/// </summary>
|
|
public IEnumerable<string> AutoCompleteList { get; private set; }
|
|
|
|
public async Task UpdateCache()
|
|
{
|
|
DbCommand command = connection.CreateCommand();
|
|
command.CommandText = "SELECT name FROM sys.tables";
|
|
command.CommandTimeout = 15;
|
|
command.CommandType = CommandType.Text;
|
|
var reader = await command.ExecuteReaderAsync();
|
|
|
|
List<string> results = new List<string>();
|
|
while (await reader.ReadAsync())
|
|
{
|
|
results.Add(reader[0].ToString());
|
|
}
|
|
|
|
AutoCompleteList = results;
|
|
await Task.FromResult(0);
|
|
}
|
|
|
|
public List<CompletionItem> GetAutoCompleteItems(TextDocumentPosition textDocumentPosition)
|
|
{
|
|
List<CompletionItem> completions = new List<CompletionItem>();
|
|
|
|
int i = 0;
|
|
|
|
// Take a reference to the list at a point in time in case we update and replace the list
|
|
var suggestions = AutoCompleteList;
|
|
// the completion list will be null is user not connected to server
|
|
if (this.AutoCompleteList != null)
|
|
{
|
|
|
|
foreach (var autoCompleteItem in suggestions)
|
|
{
|
|
// convert the completion item candidates into CompletionItems
|
|
completions.Add(new CompletionItem()
|
|
{
|
|
Label = autoCompleteItem,
|
|
Kind = CompletionItemKind.Keyword,
|
|
Detail = autoCompleteItem + " details",
|
|
Documentation = autoCompleteItem + " documentation",
|
|
TextEdit = new TextEdit
|
|
{
|
|
NewText = autoCompleteItem,
|
|
Range = new Range
|
|
{
|
|
Start = new Position
|
|
{
|
|
Line = textDocumentPosition.Position.Line,
|
|
Character = textDocumentPosition.Position.Character
|
|
},
|
|
End = new Position
|
|
{
|
|
Line = textDocumentPosition.Position.Line,
|
|
Character = textDocumentPosition.Position.Character + 5
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// only show 50 items
|
|
if (++i == 50)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return completions;
|
|
}
|
|
}
|
|
}
|