mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-16 18:47:57 -05:00
Inital SMO autocomplete commit
This commit is contained in:
@@ -7,6 +7,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data.SqlClient;
|
using System.Data.SqlClient;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.SqlServer.Management.Common;
|
||||||
using Microsoft.SqlTools.EditorServices.Utility;
|
using Microsoft.SqlTools.EditorServices.Utility;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
|
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
|
||||||
@@ -291,5 +292,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
|||||||
}
|
}
|
||||||
return connectionBuilder.ToString();
|
return connectionBuilder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ServerConnection GetServerConnection(ConnectionInfo connection)
|
||||||
|
{
|
||||||
|
string connectionString = BuildConnectionString(connection.ConnectionDetails);
|
||||||
|
var sqlConnection = new SqlConnection(connectionString);
|
||||||
|
return new ServerConnection(sqlConnection);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using System.Collections.Generic;
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.SqlServer.Management.SqlParser.Intellisense;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||||
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
|
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
|
||||||
@@ -72,10 +73,22 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
{
|
{
|
||||||
List<CompletionItem> completions = new List<CompletionItem>();
|
List<CompletionItem> completions = new List<CompletionItem>();
|
||||||
|
|
||||||
|
// Take a reference to the list at a point in time in case we update and replace the list
|
||||||
|
//var suggestions = AutoCompleteList;
|
||||||
|
if (!LanguageService.Instance.ScriptParseInfoMap.ContainsKey(textDocumentPosition.Uri))
|
||||||
|
{
|
||||||
|
return completions;
|
||||||
|
}
|
||||||
|
|
||||||
|
var scriptParseInfo = LanguageService.Instance.ScriptParseInfoMap[textDocumentPosition.Uri];
|
||||||
|
var suggestions = Resolver.FindCompletions(
|
||||||
|
scriptParseInfo.ParseResult,
|
||||||
|
textDocumentPosition.Position.Line,
|
||||||
|
textDocumentPosition.Position.Character,
|
||||||
|
scriptParseInfo.MetadataDisplayInfoProvider);
|
||||||
|
|
||||||
int i = 0;
|
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
|
// the completion list will be null is user not connected to server
|
||||||
if (this.AutoCompleteList != null)
|
if (this.AutoCompleteList != null)
|
||||||
{
|
{
|
||||||
@@ -85,13 +98,13 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
// convert the completion item candidates into CompletionItems
|
// convert the completion item candidates into CompletionItems
|
||||||
completions.Add(new CompletionItem()
|
completions.Add(new CompletionItem()
|
||||||
{
|
{
|
||||||
Label = autoCompleteItem,
|
Label = autoCompleteItem.Title,
|
||||||
Kind = CompletionItemKind.Keyword,
|
Kind = CompletionItemKind.Keyword,
|
||||||
Detail = autoCompleteItem + " details",
|
Detail = autoCompleteItem.Title + " details",
|
||||||
Documentation = autoCompleteItem + " documentation",
|
Documentation = autoCompleteItem.Title + " documentation",
|
||||||
TextEdit = new TextEdit
|
TextEdit = new TextEdit
|
||||||
{
|
{
|
||||||
NewText = autoCompleteItem,
|
NewText = autoCompleteItem.Title,
|
||||||
Range = new Range
|
Range = new Range
|
||||||
{
|
{
|
||||||
Start = new Position
|
Start = new Position
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ using System.Linq;
|
|||||||
using Microsoft.SqlServer.Management.SqlParser.Parser;
|
using Microsoft.SqlServer.Management.SqlParser.Parser;
|
||||||
using Location = Microsoft.SqlTools.ServiceLayer.Workspace.Contracts.Location;
|
using Location = Microsoft.SqlTools.ServiceLayer.Workspace.Contracts.Location;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||||
|
using Microsoft.SqlServer.Management.SqlParser.Binder;
|
||||||
|
using Microsoft.SqlServer.Management.SmoMetadataProvider;
|
||||||
|
using Microsoft.SqlServer.Management.Common;
|
||||||
|
using Microsoft.SqlServer.Management.SqlParser.MetadataProvider;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
||||||
{
|
{
|
||||||
@@ -33,6 +37,28 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
|
|
||||||
private static readonly Lazy<LanguageService> instance = new Lazy<LanguageService>(() => new LanguageService());
|
private static readonly Lazy<LanguageService> instance = new Lazy<LanguageService>(() => new LanguageService());
|
||||||
|
|
||||||
|
private Lazy<Dictionary<string, ScriptParseInfo>> scriptParseInfoMap
|
||||||
|
= new Lazy<Dictionary<string, ScriptParseInfo>>(() => new Dictionary<string, ScriptParseInfo>());
|
||||||
|
|
||||||
|
internal class ScriptParseInfo
|
||||||
|
{
|
||||||
|
public IBinder Binder { get; set; }
|
||||||
|
|
||||||
|
public ParseResult ParseResult { get; set; }
|
||||||
|
|
||||||
|
public SmoMetadataProvider MetadataProvider { get; set; }
|
||||||
|
|
||||||
|
public MetadataDisplayInfoProvider MetadataDisplayInfoProvider { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Dictionary<string, ScriptParseInfo> ScriptParseInfoMap
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.scriptParseInfoMap.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static LanguageService Instance
|
public static LanguageService Instance
|
||||||
{
|
{
|
||||||
get { return instance.Value; }
|
get { return instance.Value; }
|
||||||
@@ -125,6 +151,36 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
// save previous result for next incremental parse
|
// save previous result for next incremental parse
|
||||||
this.prevParseResult = parseResult;
|
this.prevParseResult = parseResult;
|
||||||
|
|
||||||
|
ConnectionInfo connInfo;
|
||||||
|
bool isConnected = ConnectionService.Instance.TryFindConnection(scriptFile.ClientFilePath, out connInfo);
|
||||||
|
if (isConnected)
|
||||||
|
{
|
||||||
|
if (!this.ScriptParseInfoMap.ContainsKey(scriptFile.ClientFilePath))
|
||||||
|
{
|
||||||
|
var srvConn = ConnectionService.GetServerConnection(connInfo);
|
||||||
|
var metadataProvider = SmoMetadataProvider.CreateConnectedProvider(srvConn);
|
||||||
|
var binder = BinderProvider.CreateBinder(metadataProvider);
|
||||||
|
var displayInfoProvider = new MetadataDisplayInfoProvider();
|
||||||
|
|
||||||
|
this.ScriptParseInfoMap.Add(scriptFile.ClientFilePath,
|
||||||
|
new ScriptParseInfo()
|
||||||
|
{
|
||||||
|
Binder = binder,
|
||||||
|
ParseResult = parseResult,
|
||||||
|
MetadataProvider = metadataProvider,
|
||||||
|
MetadataDisplayInfoProvider = displayInfoProvider
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptParseInfo parseInfo = this.ScriptParseInfoMap[scriptFile.ClientFilePath];
|
||||||
|
List<ParseResult> parseResults = new List<ParseResult>();
|
||||||
|
parseResults.Add(parseResult);
|
||||||
|
parseInfo.Binder.Bind(
|
||||||
|
parseResults,
|
||||||
|
connInfo.ConnectionDetails.DatabaseName,
|
||||||
|
BindMode.Batch);
|
||||||
|
}
|
||||||
|
|
||||||
// build a list of SQL script file markers from the errors
|
// build a list of SQL script file markers from the errors
|
||||||
List<ScriptFileMarker> markers = new List<ScriptFileMarker>();
|
List<ScriptFileMarker> markers = new List<ScriptFileMarker>();
|
||||||
foreach (var error in parseResult.Errors)
|
foreach (var error in parseResult.Errors)
|
||||||
|
|||||||
@@ -9,7 +9,11 @@
|
|||||||
"Newtonsoft.Json": "9.0.1",
|
"Newtonsoft.Json": "9.0.1",
|
||||||
"Microsoft.SqlServer.SqlParser": "140.1.4",
|
"Microsoft.SqlServer.SqlParser": "140.1.4",
|
||||||
"System.Data.Common": "4.1.0",
|
"System.Data.Common": "4.1.0",
|
||||||
"System.Data.SqlClient": "4.1.0"
|
"System.Data.SqlClient": "4.1.0",
|
||||||
|
"Microsoft.SqlServer.Smo": "140.1.2",
|
||||||
|
"System.Security.SecureString": "4.0.0",
|
||||||
|
"System.Collections.Specialized": "4.0.1",
|
||||||
|
"System.ComponentModel.TypeConverter": "4.1.0"
|
||||||
},
|
},
|
||||||
"frameworks": {
|
"frameworks": {
|
||||||
"netcoreapp1.0": {
|
"netcoreapp1.0": {
|
||||||
|
|||||||
@@ -3,10 +3,21 @@
|
|||||||
// 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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.SqlServer.Management.Common;
|
||||||
|
using Microsoft.SqlServer.Management.Smo;
|
||||||
|
using Microsoft.SqlServer.Management.SmoMetadataProvider;
|
||||||
|
using Microsoft.SqlServer.Management.SqlParser;
|
||||||
|
using Microsoft.SqlServer.Management.SqlParser.Binder;
|
||||||
|
using Microsoft.SqlServer.Management.SqlParser.Intellisense;
|
||||||
|
using Microsoft.SqlServer.Management.SqlParser.MetadataProvider;
|
||||||
|
using Microsoft.SqlServer.Management.SqlParser.Parser;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||||
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
|
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
|
||||||
@@ -26,6 +37,85 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
|
|||||||
{
|
{
|
||||||
#region "Diagnostics tests"
|
#region "Diagnostics tests"
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestSmo()
|
||||||
|
{
|
||||||
|
SqlConnectionStringBuilder connectionBuilder = new SqlConnectionStringBuilder();
|
||||||
|
connectionBuilder["Data Source"] = "sqltools11";
|
||||||
|
connectionBuilder["Integrated Security"] = false;
|
||||||
|
connectionBuilder["User Id"] = "sa";
|
||||||
|
connectionBuilder["Password"] = "Yukon900";
|
||||||
|
connectionBuilder["Initial Catalog"] = "master";
|
||||||
|
string connectionString = connectionBuilder.ToString();
|
||||||
|
|
||||||
|
var conn = new SqlConnection(connectionString);
|
||||||
|
var sqlConn = new ServerConnection(conn);
|
||||||
|
|
||||||
|
var server = new Server(sqlConn);
|
||||||
|
string s = "";
|
||||||
|
foreach (Database db2 in server.Databases)
|
||||||
|
{
|
||||||
|
s += db2.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
var metadata = SmoMetadataProvider.CreateConnectedProvider(sqlConn);
|
||||||
|
var db = metadata.Server.Databases["master"];
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestSmoMetadataProvider()
|
||||||
|
{
|
||||||
|
SqlConnectionStringBuilder connectionBuilder = new SqlConnectionStringBuilder();
|
||||||
|
//connectionBuilder["Data Source"] = "sqltools11";
|
||||||
|
connectionBuilder["Data Source"] = "localhost";
|
||||||
|
connectionBuilder["Integrated Security"] = false;
|
||||||
|
connectionBuilder["User Id"] = "sa";
|
||||||
|
connectionBuilder["Password"] = "Yukon900";
|
||||||
|
connectionBuilder["Initial Catalog"] = "master";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var sqlConnection = new SqlConnection(connectionBuilder.ToString());
|
||||||
|
var connection = new ServerConnection(sqlConnection);
|
||||||
|
var metadataProvider = SmoMetadataProvider.CreateConnectedProvider(connection);
|
||||||
|
var binder = BinderProvider.CreateBinder(metadataProvider);
|
||||||
|
var displayInfoProvider = new MetadataDisplayInfoProvider();
|
||||||
|
|
||||||
|
//string sql = @"SELECT * FROM sys.objects;";
|
||||||
|
|
||||||
|
string sql = @"SELECT ";
|
||||||
|
|
||||||
|
ParseOptions parseOptions = new ParseOptions();
|
||||||
|
ParseResult parseResult = Parser.IncrementalParse(
|
||||||
|
sql,
|
||||||
|
null,
|
||||||
|
parseOptions);
|
||||||
|
|
||||||
|
List<ParseResult> parseResults = new List<ParseResult>();
|
||||||
|
parseResults.Add(parseResult);
|
||||||
|
binder.Bind(parseResults, "master", BindMode.Batch);
|
||||||
|
|
||||||
|
var comp = Resolver.FindCompletions(parseResult, 1, 8, displayInfoProvider);
|
||||||
|
comp.Add(null);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Check if we failed to create a binder object. If so, we temporarely
|
||||||
|
// use a no-op binder which has the effect of turning off binding. We
|
||||||
|
// also set a timer that after the specified timeout expires removes
|
||||||
|
// the no-op timer (object becomes dead) which would give clients of
|
||||||
|
// this class an opportunity to remove it and create a new one.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// [Fact]
|
||||||
|
// public void TestAltParse()
|
||||||
|
// {
|
||||||
|
// var ls = new LanguageService();
|
||||||
|
// ls.AltParse();
|
||||||
|
// }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Verify that the latest SqlParser (2016 as of this writing) is used by default
|
/// Verify that the latest SqlParser (2016 as of this writing) is used by default
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -318,3 +408,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,10 @@
|
|||||||
"System.Runtime.Serialization.Primitives": "4.1.1",
|
"System.Runtime.Serialization.Primitives": "4.1.1",
|
||||||
"System.Data.Common": "4.1.0",
|
"System.Data.Common": "4.1.0",
|
||||||
"System.Data.SqlClient": "4.1.0",
|
"System.Data.SqlClient": "4.1.0",
|
||||||
|
"Microsoft.SqlServer.Smo": "140.1.2",
|
||||||
|
"System.Security.SecureString": "4.0.0",
|
||||||
|
"System.Collections.Specialized": "4.0.1",
|
||||||
|
"System.ComponentModel.TypeConverter": "4.1.0",
|
||||||
"xunit": "2.1.0",
|
"xunit": "2.1.0",
|
||||||
"dotnet-test-xunit": "1.0.0-rc2-192208-24",
|
"dotnet-test-xunit": "1.0.0-rc2-192208-24",
|
||||||
"moq.netcore": "4.4.0-beta8",
|
"moq.netcore": "4.4.0-beta8",
|
||||||
|
|||||||
Reference in New Issue
Block a user