mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-14 01:25:40 -05:00
This changes adds the following two notifications from the results processing within a batch. These new notifications allows a consumer to stream results from a resultset instead of getting them all at once after the entire resultset has been fetched. ResultsAvailable This is issued after at least 1 row has been fetched for this resultset. ResultsUpdated This is issued periodically as more rows are available on this resultset. The final send of this notification when all rows have been fetched has the property 'Complete' set to true in the ResultSummary object. Detailed Change Log: * Initial completed implementation of QueryResults stream feature. 3 unittests still need fixing * Fix for the 3 failing test. I will look into making MockBehavior strict again for the three tests later * Making GetReader/GetWriter use filestream objects in FileShare.ReadWrite mode so the file can be concurrently read and written * Changing resultsAvailable also to fire off on a timer instead of after 1st row * adding a project for clr TableValuedFunction to produce result set with delays after each row. This is helpful in end to end testing. * Fixing up some tests and simplifying implementation of result update timer * Address review comments * Some test fixes * Disabled flaky test verification
79 lines
2.5 KiB
C#
79 lines
2.5 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;
|
|
using System.Collections;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Data.Common;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Utility
|
|
{
|
|
public class TestResultSet : IEnumerable<object[]>
|
|
{
|
|
public List<DbColumn> Columns;
|
|
public List<object[]> Rows;
|
|
|
|
public static List<DbColumn> GetStandardColumns(int columnCount)
|
|
{
|
|
return Enumerable.Range(0, columnCount).Select(i => new TestDbColumn($"Col{i}")).Cast<DbColumn>().ToList();
|
|
}
|
|
|
|
/// <summary>
|
|
/// This creates a test result set object with specified number of columns and rows.
|
|
/// The implementation is done in parallel in multiple tasks if the number of rows is large so this method scales even to create millions of rows.
|
|
/// </summary>
|
|
/// <param name="columns"></param>
|
|
/// <param name="rows"></param>
|
|
public TestResultSet(int columns, int rows)
|
|
{
|
|
Columns = GetStandardColumns(columns);
|
|
Rows = new List<object[]>(rows);
|
|
if (rows > 100)
|
|
{
|
|
var partitioner = Partitioner.Create(0, rows);
|
|
Parallel.ForEach(partitioner, (range, loopState) => { AddRange(range); });
|
|
}
|
|
else if (rows > 0)
|
|
{
|
|
AddRange(new Tuple<int, int>(0, rows));
|
|
}
|
|
}
|
|
|
|
private void AddRange(Tuple<int, int> range)
|
|
{
|
|
for (int i = range.Item1; i < range.Item2; i++)
|
|
{
|
|
var rowIdx = i;
|
|
var row = Enumerable.Range(0, Columns.Count).Select(j => $"Cell{rowIdx}.{j}").Cast<object>()
|
|
.ToArray();
|
|
Rows.Add(row);
|
|
}
|
|
}
|
|
|
|
public TestResultSet(IEnumerable<DbColumn> columns, IEnumerable<object[]> rows)
|
|
{
|
|
Columns = new List<DbColumn>(columns);
|
|
Rows = new List<object[]>(rows);
|
|
}
|
|
|
|
#region IEnumerable<object[]> Impementation
|
|
|
|
public IEnumerator<object[]> GetEnumerator()
|
|
{
|
|
return (IEnumerator<object[]>) Rows.GetEnumerator();
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return GetEnumerator();
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|