mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-16 17:23:38 -05:00
Update docs (#200)
This is a documentation-only update so automerging. Please review the commit if there are any follow-ups requested. * Update .gitignore for docfx genertated files * Update documenation (part 1) * Update docs and add some samples * More doc updates
This commit is contained in:
102
docs/samples/jsonrpc/netcore/executequery/Driver/ClientDriver.cs
Normal file
102
docs/samples/jsonrpc/netcore/executequery/Driver/ClientDriver.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
|
||||
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Channel;
|
||||
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts;
|
||||
|
||||
namespace Microsoft.SqlTools.JsonRpc.Driver
|
||||
{
|
||||
/// <summary>
|
||||
/// Test driver for the service host
|
||||
/// </summary>
|
||||
public class ClientDriver : ClientDriverBase
|
||||
{
|
||||
public const string ServiceHostEnvironmentVariable = "SQLTOOLSSERVICE_EXE";
|
||||
|
||||
|
||||
private Process[] serviceProcesses;
|
||||
|
||||
private DateTime startTime;
|
||||
|
||||
public ClientDriver()
|
||||
{
|
||||
string serviceHostExecutable = Environment.GetEnvironmentVariable(ServiceHostEnvironmentVariable);
|
||||
string serviceHostArguments = "--enable-logging";
|
||||
if (string.IsNullOrWhiteSpace(serviceHostExecutable))
|
||||
{
|
||||
// Include a fallback value to for running tests within visual studio
|
||||
serviceHostExecutable = @"Microsoft.SqlTools.ServiceLayer.exe";
|
||||
}
|
||||
|
||||
// Make sure it exists before continuing
|
||||
if (!File.Exists(serviceHostExecutable))
|
||||
{
|
||||
throw new FileNotFoundException($"Failed to find Microsoft.SqlTools.ServiceLayer.exe at provided location '{serviceHostExecutable}'. " +
|
||||
"Please set SQLTOOLSERVICE_EXE environment variable to location of exe");
|
||||
}
|
||||
|
||||
this.clientChannel = new StdioClientChannel(serviceHostExecutable, serviceHostArguments);
|
||||
this.protocolClient = new ProtocolEndpoint(clientChannel, MessageProtocolType.LanguageServer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start the test driver, and launch the sqltoolsservice executable
|
||||
/// </summary>
|
||||
public async Task Start()
|
||||
{
|
||||
// Store the time we started
|
||||
startTime = DateTime.Now;
|
||||
|
||||
// Launch the process
|
||||
await this.protocolClient.Start();
|
||||
await Task.Delay(1000); // Wait for the service host to start
|
||||
|
||||
Console.WriteLine("Successfully launched service");
|
||||
|
||||
// Setup events to queue for testing
|
||||
this.QueueEventsForType(ConnectionCompleteNotification.Type);
|
||||
this.QueueEventsForType(IntelliSenseReadyNotification.Type);
|
||||
this.QueueEventsForType(QueryExecuteCompleteEvent.Type);
|
||||
this.QueueEventsForType(PublishDiagnosticsNotification.Type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop the test driver, and shutdown the sqltoolsservice executable
|
||||
/// </summary>
|
||||
public async Task Stop()
|
||||
{
|
||||
|
||||
await this.protocolClient.Stop();
|
||||
}
|
||||
|
||||
private async Task GetServiceProcess(CancellationToken token)
|
||||
{
|
||||
while (serviceProcesses == null && !token.IsCancellationRequested)
|
||||
{
|
||||
var processes = Process.GetProcessesByName("Microsoft.SqlTools.ServiceLayer")
|
||||
.Where(p => p.StartTime >= startTime).ToArray();
|
||||
|
||||
// Wait a second if we can't find the process
|
||||
if (processes.Any())
|
||||
{
|
||||
serviceProcesses = processes;
|
||||
}
|
||||
else
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(1), token);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
|
||||
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Channel;
|
||||
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||
|
||||
namespace Microsoft.SqlTools.JsonRpc.Driver
|
||||
{
|
||||
/// <summary>
|
||||
/// Wraps the ProtocolEndpoint class with queues to handle events/requests
|
||||
/// </summary>
|
||||
public class ClientDriverBase
|
||||
{
|
||||
protected ProtocolEndpoint protocolClient;
|
||||
|
||||
protected StdioClientChannel clientChannel;
|
||||
|
||||
private ConcurrentDictionary<string, AsyncQueue<object>> eventQueuePerType =
|
||||
new ConcurrentDictionary<string, AsyncQueue<object>>();
|
||||
|
||||
private ConcurrentDictionary<string, AsyncQueue<object>> requestQueuePerType =
|
||||
new ConcurrentDictionary<string, AsyncQueue<object>>();
|
||||
|
||||
public Process ServiceProcess
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return Process.GetProcessById(clientChannel.ProcessId);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Task<TResult> SendRequest<TParams, TResult>(
|
||||
RequestType<TParams, TResult> requestType,
|
||||
TParams requestParams)
|
||||
{
|
||||
return
|
||||
this.protocolClient.SendRequest(
|
||||
requestType,
|
||||
requestParams);
|
||||
}
|
||||
|
||||
public Task SendEvent<TParams>(EventType<TParams> eventType, TParams eventParams)
|
||||
{
|
||||
return
|
||||
this.protocolClient.SendEvent(
|
||||
eventType,
|
||||
eventParams);
|
||||
}
|
||||
|
||||
public void QueueEventsForType<TParams>(EventType<TParams> eventType)
|
||||
{
|
||||
var eventQueue =
|
||||
this.eventQueuePerType.AddOrUpdate(
|
||||
eventType.MethodName,
|
||||
new AsyncQueue<object>(),
|
||||
(key, queue) => queue);
|
||||
|
||||
this.protocolClient.SetEventHandler(
|
||||
eventType,
|
||||
(p, ctx) =>
|
||||
{
|
||||
return eventQueue.EnqueueAsync(p);
|
||||
});
|
||||
}
|
||||
|
||||
public async Task<TParams> WaitForEvent<TParams>(
|
||||
EventType<TParams> eventType,
|
||||
int timeoutMilliseconds = 5000)
|
||||
{
|
||||
Task<TParams> eventTask = null;
|
||||
|
||||
// Use the event queue if one has been registered
|
||||
AsyncQueue<object> eventQueue = null;
|
||||
if (this.eventQueuePerType.TryGetValue(eventType.MethodName, out eventQueue))
|
||||
{
|
||||
eventTask =
|
||||
eventQueue
|
||||
.DequeueAsync()
|
||||
.ContinueWith<TParams>(
|
||||
task => (TParams)task.Result);
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskCompletionSource<TParams> eventTaskSource = new TaskCompletionSource<TParams>();
|
||||
|
||||
this.protocolClient.SetEventHandler(
|
||||
eventType,
|
||||
(p, ctx) =>
|
||||
{
|
||||
if (!eventTaskSource.Task.IsCompleted)
|
||||
{
|
||||
eventTaskSource.SetResult(p);
|
||||
}
|
||||
|
||||
return Task.FromResult(true);
|
||||
},
|
||||
true); // Override any existing handler
|
||||
|
||||
eventTask = eventTaskSource.Task;
|
||||
}
|
||||
|
||||
await
|
||||
Task.WhenAny(
|
||||
eventTask,
|
||||
Task.Delay(timeoutMilliseconds));
|
||||
|
||||
if (!eventTask.IsCompleted)
|
||||
{
|
||||
throw new TimeoutException(
|
||||
string.Format(
|
||||
"Timed out waiting for '{0}' event!",
|
||||
eventType.MethodName));
|
||||
}
|
||||
|
||||
return await eventTask;
|
||||
}
|
||||
|
||||
public async Task<Tuple<TParams, RequestContext<TResponse>>> WaitForRequest<TParams, TResponse>(
|
||||
RequestType<TParams, TResponse> requestType,
|
||||
int timeoutMilliseconds = 5000)
|
||||
{
|
||||
Task<Tuple<TParams, RequestContext<TResponse>>> requestTask = null;
|
||||
|
||||
// Use the request queue if one has been registered
|
||||
AsyncQueue<object> requestQueue = null;
|
||||
if (this.requestQueuePerType.TryGetValue(requestType.MethodName, out requestQueue))
|
||||
{
|
||||
requestTask =
|
||||
requestQueue
|
||||
.DequeueAsync()
|
||||
.ContinueWith(
|
||||
task => (Tuple<TParams, RequestContext<TResponse>>)task.Result);
|
||||
}
|
||||
else
|
||||
{
|
||||
var requestTaskSource =
|
||||
new TaskCompletionSource<Tuple<TParams, RequestContext<TResponse>>>();
|
||||
|
||||
this.protocolClient.SetRequestHandler(
|
||||
requestType,
|
||||
(p, ctx) =>
|
||||
{
|
||||
if (!requestTaskSource.Task.IsCompleted)
|
||||
{
|
||||
requestTaskSource.SetResult(
|
||||
new Tuple<TParams, RequestContext<TResponse>>(p, ctx));
|
||||
}
|
||||
|
||||
return Task.FromResult(true);
|
||||
});
|
||||
|
||||
requestTask = requestTaskSource.Task;
|
||||
}
|
||||
|
||||
await
|
||||
Task.WhenAny(
|
||||
requestTask,
|
||||
Task.Delay(timeoutMilliseconds));
|
||||
|
||||
if (!requestTask.IsCompleted)
|
||||
{
|
||||
throw new TimeoutException(
|
||||
string.Format(
|
||||
"Timed out waiting for '{0}' request!",
|
||||
requestType.MethodName));
|
||||
}
|
||||
|
||||
return await requestTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
85
docs/samples/jsonrpc/netcore/executequery/Program.cs
Normal file
85
docs/samples/jsonrpc/netcore/executequery/Program.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.JsonRpc.Utility;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts;
|
||||
|
||||
namespace Microsoft.SqlTools.JsonRpc.ExecuteQuery
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple JSON-RPC API sample to connect to a database, execute a query, and print the results
|
||||
/// </summary>
|
||||
internal class Program
|
||||
{
|
||||
internal static void Main(string[] args)
|
||||
{
|
||||
// set SQLTOOLSSERVICE_EXE to location of SQL Tools Service executable
|
||||
Environment.SetEnvironmentVariable("SQLTOOLSSERVICE_EXE", @"Microsoft.SqlTools.ServiceLayer.exe");
|
||||
|
||||
// execute a query against localhost, master, with IntegratedAuth
|
||||
ExecuteQuery("SELECT * FROM sys.objects").Wait();
|
||||
}
|
||||
|
||||
internal static async Task ExecuteQuery(string query)
|
||||
{
|
||||
// create a temporary "workspace" file
|
||||
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
|
||||
// create the client helper which wraps the client driver objects
|
||||
using (ClientHelper testHelper = new ClientHelper())
|
||||
{
|
||||
// connnection details
|
||||
ConnectParams connectParams = new ConnectParams();
|
||||
connectParams.Connection = new ConnectionDetails();
|
||||
connectParams.Connection.ServerName = "localhost";
|
||||
connectParams.Connection.DatabaseName = "master";
|
||||
connectParams.Connection.AuthenticationType = "Integrated";
|
||||
|
||||
// connect to the database
|
||||
await testHelper.Connect(queryTempFile.FilePath, connectParams);
|
||||
|
||||
// execute the query
|
||||
QueryExecuteCompleteParams queryComplete =
|
||||
await testHelper.RunQuery(queryTempFile.FilePath, query);
|
||||
|
||||
if (queryComplete.BatchSummaries != null && queryComplete.BatchSummaries.Length > 0)
|
||||
{
|
||||
var batch = queryComplete.BatchSummaries[0];
|
||||
if (batch.ResultSetSummaries != null && batch.ResultSetSummaries.Length > 0)
|
||||
{
|
||||
var resultSet = batch.ResultSetSummaries[0];
|
||||
|
||||
// retrive the results
|
||||
QueryExecuteSubsetResult querySubset = await testHelper.ExecuteSubset(
|
||||
queryTempFile.FilePath, batch.Id,
|
||||
resultSet.Id, 0, (int)resultSet.RowCount);
|
||||
|
||||
// print the header
|
||||
foreach (var column in resultSet.ColumnInfo)
|
||||
{
|
||||
Console.Write(column.ColumnName + ", ");
|
||||
}
|
||||
Console.Write(Environment.NewLine);
|
||||
|
||||
// print the rows
|
||||
foreach (var row in querySubset.ResultSubset.Rows)
|
||||
{
|
||||
for (int i = 0; i < resultSet.ColumnInfo.Length; ++i)
|
||||
{
|
||||
Console.Write(row.GetValue(i) + ", ");
|
||||
}
|
||||
Console.Write(Environment.NewLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// close database connection
|
||||
await testHelper.Disconnect(queryTempFile.FilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.JsonRpc.Driver;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Credentials.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.SqlContext;
|
||||
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
|
||||
|
||||
namespace Microsoft.SqlTools.JsonRpc.Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for all test suites run by the test driver
|
||||
/// </summary>
|
||||
public sealed class ClientHelper : IDisposable
|
||||
{
|
||||
private bool isRunning = false;
|
||||
|
||||
public ClientHelper()
|
||||
{
|
||||
Driver = new ClientDriver();
|
||||
Driver.Start().Wait();
|
||||
this.isRunning = true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (this.isRunning)
|
||||
{
|
||||
WaitForExit();
|
||||
}
|
||||
}
|
||||
|
||||
public void WaitForExit()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.isRunning = false;
|
||||
Driver.Stop().Wait();
|
||||
Console.WriteLine("Successfully killed process.");
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Console.WriteLine($"Exception while waiting for service exit: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The driver object used to read/write data to the service
|
||||
/// </summary>
|
||||
public ClientDriver Driver
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
private object fileLock = new Object();
|
||||
|
||||
/// <summary>
|
||||
/// Request a new connection to be created
|
||||
/// </summary>
|
||||
/// <returns>True if the connection completed successfully</returns>
|
||||
public async Task<bool> Connect(string ownerUri, ConnectParams connectParams, int timeout = 15000)
|
||||
{
|
||||
connectParams.OwnerUri = ownerUri;
|
||||
var connectResult = await Driver.SendRequest(ConnectionRequest.Type, connectParams);
|
||||
if (connectResult)
|
||||
{
|
||||
var completeEvent = await Driver.WaitForEvent(ConnectionCompleteNotification.Type, timeout);
|
||||
return !string.IsNullOrEmpty(completeEvent.ConnectionId);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request a disconnect
|
||||
/// </summary>
|
||||
public async Task<bool> Disconnect(string ownerUri)
|
||||
{
|
||||
var disconnectParams = new DisconnectParams();
|
||||
disconnectParams.OwnerUri = ownerUri;
|
||||
|
||||
var disconnectResult = await Driver.SendRequest(DisconnectRequest.Type, disconnectParams);
|
||||
return disconnectResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request a cancel connect
|
||||
/// </summary>
|
||||
public async Task<bool> CancelConnect(string ownerUri)
|
||||
{
|
||||
var cancelParams = new CancelConnectParams();
|
||||
cancelParams.OwnerUri = ownerUri;
|
||||
|
||||
return await Driver.SendRequest(CancelConnectRequest.Type, cancelParams);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request a cancel connect
|
||||
/// </summary>
|
||||
public async Task<ListDatabasesResponse> ListDatabases(string ownerUri)
|
||||
{
|
||||
var listParams = new ListDatabasesParams();
|
||||
listParams.OwnerUri = ownerUri;
|
||||
|
||||
return await Driver.SendRequest(ListDatabasesRequest.Type, listParams);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request the active SQL script is parsed for errors
|
||||
/// </summary>
|
||||
public async Task<QueryExecuteSubsetResult> RequestQueryExecuteSubset(QueryExecuteSubsetParams subsetParams)
|
||||
{
|
||||
return await Driver.SendRequest(QueryExecuteSubsetRequest.Type, subsetParams);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request the active SQL script is parsed for errors
|
||||
/// </summary>
|
||||
public async Task RequestOpenDocumentNotification(DidOpenTextDocumentNotification openParams)
|
||||
{
|
||||
await Driver.SendEvent(DidOpenTextDocumentNotification.Type, openParams);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request a configuration change notification
|
||||
/// </summary>
|
||||
public async Task RequestChangeConfigurationNotification(DidChangeConfigurationParams<SqlToolsSettings> configParams)
|
||||
{
|
||||
await Driver.SendEvent(DidChangeConfigurationNotification<SqlToolsSettings>.Type, configParams);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// /// Request the active SQL script is parsed for errors
|
||||
/// </summary>
|
||||
public async Task RequestChangeTextDocumentNotification(DidChangeTextDocumentParams changeParams)
|
||||
{
|
||||
await Driver.SendEvent(DidChangeTextDocumentNotification.Type, changeParams);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request completion item resolve to look-up additional info
|
||||
/// </summary>
|
||||
public async Task<CompletionItem> RequestResolveCompletion(CompletionItem item)
|
||||
{
|
||||
var result = await Driver.SendRequest(CompletionResolveRequest.Type, item);
|
||||
return result;
|
||||
}
|
||||
|
||||
// /// <summary>
|
||||
// /// Request a Read Credential for given credential id
|
||||
// /// </summary>
|
||||
// public async Task<Credential> ReadCredential(string credentialId)
|
||||
// {
|
||||
// var credentialParams = new Credential();
|
||||
// credentialParams.CredentialId = credentialId;
|
||||
|
||||
// return await Driver.SendRequest(ReadCredentialRequest.Type, credentialParams);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Run a query using a given connection bound to a URI
|
||||
/// </summary>
|
||||
public async Task<QueryExecuteCompleteParams> RunQuery(string ownerUri, string query, int timeoutMilliseconds = 5000)
|
||||
{
|
||||
// Write the query text to a backing file
|
||||
WriteToFile(ownerUri, query);
|
||||
|
||||
var queryParams = new QueryExecuteParams
|
||||
{
|
||||
OwnerUri = ownerUri,
|
||||
QuerySelection = null
|
||||
};
|
||||
|
||||
var result = await Driver.SendRequest(QueryExecuteRequest.Type, queryParams);
|
||||
if (result != null && string.IsNullOrEmpty(result.Messages))
|
||||
{
|
||||
var eventResult = await Driver.WaitForEvent(QueryExecuteCompleteEvent.Type, timeoutMilliseconds);
|
||||
return eventResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request to save query results as CSV
|
||||
/// </summary>
|
||||
public async Task<SaveResultRequestResult> SaveAsCsv(string ownerUri, string filename, int batchIndex, int resultSetIndex)
|
||||
{
|
||||
var saveParams = new SaveResultsAsCsvRequestParams
|
||||
{
|
||||
OwnerUri = ownerUri,
|
||||
BatchIndex = batchIndex,
|
||||
ResultSetIndex = resultSetIndex,
|
||||
FilePath = filename
|
||||
};
|
||||
|
||||
var result = await Driver.SendRequest(SaveResultsAsCsvRequest.Type, saveParams);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request to save query results as JSON
|
||||
/// </summary>
|
||||
public async Task<SaveResultRequestResult> SaveAsJson(string ownerUri, string filename, int batchIndex, int resultSetIndex)
|
||||
{
|
||||
var saveParams = new SaveResultsAsJsonRequestParams
|
||||
{
|
||||
OwnerUri = ownerUri,
|
||||
BatchIndex = batchIndex,
|
||||
ResultSetIndex = resultSetIndex,
|
||||
FilePath = filename
|
||||
};
|
||||
|
||||
var result = await Driver.SendRequest(SaveResultsAsJsonRequest.Type, saveParams);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request a subset of results from a query
|
||||
/// </summary>
|
||||
public async Task<QueryExecuteSubsetResult> ExecuteSubset(string ownerUri, int batchIndex, int resultSetIndex, int rowStartIndex, int rowCount)
|
||||
{
|
||||
var subsetParams = new QueryExecuteSubsetParams();
|
||||
subsetParams.OwnerUri = ownerUri;
|
||||
subsetParams.BatchIndex = batchIndex;
|
||||
subsetParams.ResultSetIndex = resultSetIndex;
|
||||
subsetParams.RowsStartIndex = rowStartIndex;
|
||||
subsetParams.RowsCount = rowCount;
|
||||
|
||||
var result = await Driver.SendRequest(QueryExecuteSubsetRequest.Type, subsetParams);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void WriteToFile(string ownerUri, string query)
|
||||
{
|
||||
lock (fileLock)
|
||||
{
|
||||
System.IO.File.WriteAllText(ownerUri, query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Microsoft.SqlTools.JsonRpc.Utility
|
||||
{
|
||||
public class SelfCleaningTempFile : IDisposable
|
||||
{
|
||||
private bool disposed;
|
||||
|
||||
public SelfCleaningTempFile()
|
||||
{
|
||||
FilePath = Path.GetTempFileName();
|
||||
}
|
||||
|
||||
public string FilePath { get; private set; }
|
||||
|
||||
#region IDisposable Implementation
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposed && disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(FilePath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine($"Failed to cleanup {FilePath}");
|
||||
}
|
||||
}
|
||||
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
49
docs/samples/jsonrpc/netcore/executequery/project.json
Normal file
49
docs/samples/jsonrpc/netcore/executequery/project.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "Microsoft.SqlTools.JsonRpcTest.ExecuteQuery",
|
||||
"version": "1.0.0-*",
|
||||
"buildOptions": {
|
||||
"debugType": "portable",
|
||||
"emitEntryPoint": true
|
||||
},
|
||||
"dependencies": {
|
||||
"Microsoft.SqlTools.ServiceLayer": {
|
||||
"target": "project"
|
||||
},
|
||||
"Newtonsoft.Json": "9.0.1",
|
||||
"System.Data.Common": "4.1.0",
|
||||
"System.Data.SqlClient": "4.4.0-sqltools-24613-04",
|
||||
"Microsoft.SqlServer.Smo": "140.1.12",
|
||||
"System.Security.SecureString": "4.0.0",
|
||||
"System.Collections.Specialized": "4.0.1",
|
||||
"System.ComponentModel.TypeConverter": "4.1.0",
|
||||
"System.Diagnostics.Contracts": "4.0.1",
|
||||
"System.Diagnostics.TraceSource": "4.0.0",
|
||||
"NETStandard.Library": "1.6.0",
|
||||
"Microsoft.NETCore.Runtime.CoreCLR": "1.0.2",
|
||||
"Microsoft.NETCore.DotNetHostPolicy": "1.0.1",
|
||||
"System.Diagnostics.Process": "4.1.0",
|
||||
"System.Threading.Thread": "4.0.0"
|
||||
},
|
||||
"frameworks": {
|
||||
"netcoreapp1.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"version": "1.0.0"
|
||||
}
|
||||
},
|
||||
"imports": "dnxcore50"
|
||||
}
|
||||
},
|
||||
"runtimes": {
|
||||
"win7-x64": {},
|
||||
"win7-x86": {},
|
||||
"osx.10.11-x64": {},
|
||||
"ubuntu.14.04-x64": {},
|
||||
"ubuntu.16.04-x64": {},
|
||||
"centos.7-x64": {},
|
||||
"rhel.7.2-x64": {},
|
||||
"debian.8-x64": {},
|
||||
"fedora.23-x64": {},
|
||||
"opensuse.13.2-x64": {}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user