mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-14 01:25:40 -05:00
Execute SQL statement at cursor location (#412)
* Stage changes to other machine * Parse sql statement from script document * Fix a few typos and minor changes * Fix bug
This commit is contained in:
@@ -1679,5 +1679,42 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
||||
FileUtilities.SafeDirectoryDelete(FileUtilities.PeekDefinitionTempFolder, true);
|
||||
}
|
||||
}
|
||||
|
||||
internal string ParseStatementAtPosition(string sql, int line, int column)
|
||||
{
|
||||
// adjust from 0-based to 1-based index
|
||||
int parserLine = line + 1;
|
||||
int parserColumn = column + 1;
|
||||
|
||||
// parse current SQL file contents to retrieve a list of errors
|
||||
ParseResult parseResult = Parser.Parse(sql, this.DefaultParseOptions);
|
||||
if (parseResult != null && parseResult.Script != null && parseResult.Script.Batches != null)
|
||||
{
|
||||
foreach (var batch in parseResult.Script.Batches)
|
||||
{
|
||||
if (batch.Statements == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if the batch matches parameters
|
||||
if (batch.StartLocation.LineNumber <= parserLine
|
||||
&& batch.EndLocation.LineNumber >= parserLine)
|
||||
{
|
||||
foreach (var statement in batch.Statements)
|
||||
{
|
||||
// check if the statement matches parameters
|
||||
if (statement.StartLocation.LineNumber <= parserLine
|
||||
&& statement.EndLocation.LineNumber >= parserLine)
|
||||
{
|
||||
return statement.Sql;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts.ExecuteRequests
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters for executing a query from a document open in the workspace
|
||||
/// </summary>
|
||||
public class ExecuteDocumentStatementParams : ExecuteRequestParamsBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Line in the document for the location of the SQL statement
|
||||
/// </summary>
|
||||
public int Line { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Column in the document for the location of the SQL statement
|
||||
/// </summary>
|
||||
public int Column { get; set; }
|
||||
}
|
||||
|
||||
public class ExecuteDocumentStatementRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<ExecuteDocumentStatementParams, ExecuteRequestResult> Type =
|
||||
RequestType<ExecuteDocumentStatementParams, ExecuteRequestResult>.Create("query/executedocumentstatement");
|
||||
}
|
||||
}
|
||||
@@ -129,6 +129,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
{
|
||||
// Register handlers for requests
|
||||
serviceHost.SetRequestHandler(ExecuteDocumentSelectionRequest.Type, HandleExecuteRequest);
|
||||
serviceHost.SetRequestHandler(ExecuteDocumentStatementRequest.Type, HandleExecuteRequest);
|
||||
serviceHost.SetRequestHandler(ExecuteStringRequest.Type, HandleExecuteRequest);
|
||||
serviceHost.SetRequestHandler(SubsetRequest.Type, HandleResultSubsetRequest);
|
||||
serviceHost.SetRequestHandler(QueryDisposeRequest.Type, HandleDisposeRequest);
|
||||
@@ -691,32 +692,14 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
ExecuteDocumentSelectionParams docRequest = request as ExecuteDocumentSelectionParams;
|
||||
if (docRequest != null)
|
||||
{
|
||||
// Get the document from the parameters
|
||||
ScriptFile queryFile = WorkspaceService.Workspace.GetFile(docRequest.OwnerUri);
|
||||
if (queryFile == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
// If a selection was not provided, use the entire document
|
||||
if (docRequest.QuerySelection == null)
|
||||
{
|
||||
return queryFile.Contents;
|
||||
}
|
||||
return GetSqlTextFromSelectionData(docRequest.OwnerUri, docRequest.QuerySelection);
|
||||
}
|
||||
|
||||
// A selection was provided, so get the lines in the selected range
|
||||
string[] queryTextArray = queryFile.GetLinesInRange(
|
||||
new BufferRange(
|
||||
new BufferPosition(
|
||||
docRequest.QuerySelection.StartLine + 1,
|
||||
docRequest.QuerySelection.StartColumn + 1
|
||||
),
|
||||
new BufferPosition(
|
||||
docRequest.QuerySelection.EndLine + 1,
|
||||
docRequest.QuerySelection.EndColumn + 1
|
||||
)
|
||||
)
|
||||
);
|
||||
return string.Join(Environment.NewLine, queryTextArray);
|
||||
// If it is a document statement, we'll retrieve the text from the document
|
||||
ExecuteDocumentStatementParams stmtRequest = request as ExecuteDocumentStatementParams;
|
||||
if (stmtRequest != null)
|
||||
{
|
||||
return GetSqlStatementAtPosition(stmtRequest.OwnerUri, stmtRequest.Line, stmtRequest.Column);
|
||||
}
|
||||
|
||||
// If it is an ExecuteStringParams, return the text as is
|
||||
@@ -730,6 +713,55 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
throw new InvalidCastException("Invalid request type");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return portion of document corresponding to the selection range
|
||||
/// </summary>
|
||||
internal string GetSqlTextFromSelectionData(string ownerUri, SelectionData selection)
|
||||
{
|
||||
// Get the document from the parameters
|
||||
ScriptFile queryFile = WorkspaceService.Workspace.GetFile(ownerUri);
|
||||
if (queryFile == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
// If a selection was not provided, use the entire document
|
||||
if (selection == null)
|
||||
{
|
||||
return queryFile.Contents;
|
||||
}
|
||||
|
||||
// A selection was provided, so get the lines in the selected range
|
||||
string[] queryTextArray = queryFile.GetLinesInRange(
|
||||
new BufferRange(
|
||||
new BufferPosition(
|
||||
selection.StartLine + 1,
|
||||
selection.StartColumn + 1
|
||||
),
|
||||
new BufferPosition(
|
||||
selection.EndLine + 1,
|
||||
selection.EndColumn + 1
|
||||
)
|
||||
)
|
||||
);
|
||||
return string.Join(Environment.NewLine, queryTextArray);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return portion of document corresponding to the statement at the line and column
|
||||
/// </summary>
|
||||
internal string GetSqlStatementAtPosition(string ownerUri, int line, int column)
|
||||
{
|
||||
// Get the document from the parameters
|
||||
ScriptFile queryFile = WorkspaceService.Workspace.GetFile(ownerUri);
|
||||
if (queryFile == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return LanguageServices.LanguageService.Instance.ParseStatementAtPosition(
|
||||
queryFile.Contents, line, column);
|
||||
}
|
||||
|
||||
/// Internal for testing purposes
|
||||
internal Task UpdateSettings(SqlToolsSettings newSettings, SqlToolsSettings oldSettings, EventContext eventContext)
|
||||
{
|
||||
|
||||
@@ -21,6 +21,20 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.Execution
|
||||
|
||||
#region Get SQL Tests
|
||||
|
||||
[Fact]
|
||||
public void ExecuteDocumentStatementTest()
|
||||
{
|
||||
string query = string.Format("{0}{1}GO{1}{0}", Constants.StandardQuery, Environment.NewLine);
|
||||
var workspaceService = GetDefaultWorkspaceService(query);
|
||||
var queryService = new QueryExecutionService(null, workspaceService);
|
||||
|
||||
var queryParams = new ExecuteDocumentStatementParams { OwnerUri = Constants.OwnerUri, Line = 0, Column = 0 };
|
||||
var queryText = queryService.GetSqlText(queryParams);
|
||||
|
||||
// The text should match the standard query
|
||||
Assert.Equal(queryText, Constants.StandardQuery);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetSqlTextFromDocumentRequestFull()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user