Progressive Results Part 2: Result Completion Event (#134)

The main change in this pull request is to add a new event that will be fired upon completion of a resultset but before the completion of a batch. This event will only fire if a resultset is available and generated.

Changes:
* ConnectionService - Slight changes to enable mocking, cleanup 
* Batch - Moving summary generation into ResultSet class, adding generation of ordinals for resultset and locking of result set list (which needs further refinement, but would be outside scope of this change)
* Adding new event and associated parameters for completion of a resultset. Params return the resultset summary
* Adding logic for assigning the event a handler in the query execution service
* Adding unit tests for testing the new event /making sure the existing tests work
* Refactoring some private properties into member variables

* Refactor to remove SectionData class in favor of BufferRange

* Adding callback for batch completion that will let the extension know that a batch has completed execution

* Refactoring to make progressive results work as per async query execution

* Allowing retrieval of batch results while query is in progress

* reverting global.json, whoops

* Adding a few missing comments, and fixing a couple code style bugs

* Using SelectionData everywhere again

* One more missing comment

* Adding new notification type for result set completion

* Plumbing event for result set completion

* Unit tests for result set events

This includes a fairly substantial change to create a mock of the
ConnectionService and to create separate memorystream storage arrays. It
preserves more correct behavior with a integration test, fixes an issue
where the test db reader will return n-1 rows because the Reliable
Connection Helper steals a record.

* Adding locking to ResultSets for thread safety

* Adding/fixing unit tests

* Adding batch ID to result set summary
This commit is contained in:
Benjamin Russell
2016-11-22 17:37:27 -08:00
committed by GitHub
parent 0841ad7cf4
commit d9efb95386
17 changed files with 585 additions and 190 deletions

View File

@@ -4,6 +4,7 @@
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
@@ -20,9 +21,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution
#region ResultSet Class Tests
[Theory]
[InlineData(0,2)]
[InlineData(0,20)]
[InlineData(1,2)]
[InlineData(0, 2)]
[InlineData(0, 20)]
[InlineData(1, 2)]
public void ResultSetValidTest(int startRow, int rowCount)
{
// Setup:
@@ -57,6 +58,17 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution
Assert.ThrowsAsync<ArgumentOutOfRangeException>(() => rs.GetSubset(rowStartIndex, rowCount)).Wait();
}
[Fact]
public async Task ResultSetNotReadTest()
{
// If:
// ... I have a resultset that hasn't been executed and I request a valid result set from it
// Then:
// ... It should throw an exception for having not been read
ResultSet rs = new ResultSet(new TestDbDataReader(null), Common.Ordinal, Common.Ordinal, Common.GetFileStreamFactory(new Dictionary<string, byte[]>()));
await Assert.ThrowsAsync<InvalidOperationException>(() => rs.GetSubset(0, 1));
}
#endregion
#region Batch Class Tests
@@ -92,21 +104,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution
Assert.ThrowsAsync<ArgumentOutOfRangeException>(() => b.GetSubset(resultSetIndex, 0, 2)).Wait();
}
[Fact]
public async Task BatchSubsetIncompleteTest()
{
// If:
// ... I have a batch that hasn't completed execution
Batch b = new Batch(Common.StandardQuery, Common.WholeDocument, Common.Ordinal, Common.GetFileStreamFactory(null));
Assert.False(b.HasExecuted);
// ... And I ask for a subset
// Then:
// ... It should throw an exception
await Assert.ThrowsAsync<InvalidOperationException>(() => b.GetSubset(Common.Ordinal, 0, 2));
}
#endregion
#region Query Class Tests
@@ -142,7 +139,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution
await queryService.ActiveQueries[Common.OwnerUri].ExecutionTask;
// ... And I then ask for a valid set of results from it
var subsetParams = new QueryExecuteSubsetParams {OwnerUri = Common.OwnerUri, RowsCount = 1, ResultSetIndex = 0, RowsStartIndex = 0};
var subsetParams = new QueryExecuteSubsetParams { OwnerUri = Common.OwnerUri, RowsCount = 1, ResultSetIndex = 0, RowsStartIndex = 0 };
QueryExecuteSubsetResult result = null;
var subsetRequest = GetQuerySubsetResultContextMock(qesr => result = qesr, null);
await queryService.HandleResultSubsetRequest(subsetParams, subsetRequest.Object);
@@ -157,7 +154,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution
}
[Fact]
public async void SubsetServiceMissingQueryTest()
public async Task SubsetServiceMissingQueryTest()
{
// If:
// ... I ask for a set of results for a file that hasn't executed a query
@@ -178,7 +175,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution
}
[Fact]
public async void SubsetServiceUnexecutedQueryTest()
public async Task SubsetServiceUnexecutedQueryTest()
{
// If:
// ... I have a query that hasn't finished executing (doesn't matter what)
@@ -188,13 +185,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution
var executeRequest = RequestContextMocks.Create<QueryExecuteResult>(null);
await queryService.HandleExecuteRequest(executeParams, executeRequest.Object);
await queryService.ActiveQueries[Common.OwnerUri].ExecutionTask;
queryService.ActiveQueries[Common.OwnerUri].HasExecuted = false;
queryService.ActiveQueries[Common.OwnerUri].Batches[0].ResultSets[0].hasBeenRead = false;
// ... And I then ask for a valid set of results from it
var subsetParams = new QueryExecuteSubsetParams { OwnerUri = Common.OwnerUri, RowsCount = 1, ResultSetIndex = 0, RowsStartIndex = 0 };
QueryExecuteSubsetResult result = null;
var subsetRequest = GetQuerySubsetResultContextMock(qesr => result = qesr, null);
queryService.HandleResultSubsetRequest(subsetParams, subsetRequest.Object).Wait();
await queryService.HandleResultSubsetRequest(subsetParams, subsetRequest.Object);
// Then:
// ... I should get an error result
@@ -207,7 +204,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution
[Fact]
public async void SubsetServiceOutOfRangeSubsetTest()
{
{
// If:
// ... I have a query that doesn't have any result sets
var workspaceService = Common.GetPrimedWorkspaceService(Common.StandardQuery);