mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-18 01:25:41 -05:00
Feature: Writing Execute Results to Temp File (#35)
* WIP for buffering in temporary file * Adding support for writing to disk for buffering * WIP - Adding file reader, factory for reader/writer * Making long list use generics and implement IEnumerable * Reading/Writing from file is working * Removing unused 'skipValue' logic * More tweaks to file buffer Adding logic for cleaning up the temp files Adding fix for empty/null column names * Adding comments and cleanup * Unit tests for FileStreamWrapper * WIP adding more unit tests, and finishing up wiring up the output writers * Finishing up initial unit tests * Fixing bugs with long fields * Squashed commit of the following: commit df0ffc12a46cb286d801d08689964eac08ad71dd Author: Benjamin Russell <beruss@microsoft.com> Date: Wed Sep 7 14:45:39 2016 -0700 Removing last bit of async for file writing. We're seeing a 8x improvement of file write speeds! commit 08a4b9f32e825512ca24d5dc03ef5acbf7cc6d94 Author: Benjamin Russell <beruss@microsoft.com> Date: Wed Sep 7 11:23:06 2016 -0700 Removing async wrappers * Rolling back test code for Program.cs * Changes as per code review * Fixing broken unit tests * More fixes for codereview
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
//
|
||||
//
|
||||
// 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.Generic;
|
||||
@@ -11,18 +10,60 @@ using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.EditorServices.Utility;
|
||||
using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents a batch within a query
|
||||
/// </summary>
|
||||
public class Batch
|
||||
public class Batch : IDisposable
|
||||
{
|
||||
private const string RowsAffectedFormat = "({0} row(s) affected)";
|
||||
|
||||
#region Member Variables
|
||||
|
||||
/// <summary>
|
||||
/// For IDisposable implementation, whether or not this has been disposed
|
||||
/// </summary>
|
||||
private bool disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Factory for creating readers/writrs for the output of the batch
|
||||
/// </summary>
|
||||
private readonly IFileStreamFactory outputFileFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Internal representation of the messages so we can modify internally
|
||||
/// </summary>
|
||||
private readonly List<string> resultMessages;
|
||||
|
||||
/// <summary>
|
||||
/// Internal representation of the result sets so we can modify internally
|
||||
/// </summary>
|
||||
private readonly List<ResultSet> resultSets;
|
||||
|
||||
#endregion
|
||||
|
||||
internal Batch(string batchText, int startLine, IFileStreamFactory outputFileFactory)
|
||||
{
|
||||
// Sanity check for input
|
||||
Validate.IsNotNullOrEmptyString(nameof(batchText), batchText);
|
||||
Validate.IsNotNull(nameof(outputFileFactory), outputFileFactory);
|
||||
|
||||
// Initialize the internal state
|
||||
BatchText = batchText;
|
||||
StartLine = startLine - 1; // -1 to make sure that the line number of the batch is 0-indexed, since SqlParser gives 1-indexed line numbers
|
||||
HasExecuted = false;
|
||||
resultSets = new List<ResultSet>();
|
||||
resultMessages = new List<string>();
|
||||
this.outputFileFactory = outputFileFactory;
|
||||
}
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// The text of batch that will be executed
|
||||
/// </summary>
|
||||
@@ -38,11 +79,6 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
/// </summary>
|
||||
public bool HasExecuted { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Internal representation of the messages so we can modify internally
|
||||
/// </summary>
|
||||
private List<string> resultMessages;
|
||||
|
||||
/// <summary>
|
||||
/// Messages that have come back from the server
|
||||
/// </summary>
|
||||
@@ -51,11 +87,6 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
get { return resultMessages; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal representation of the result sets so we can modify internally
|
||||
/// </summary>
|
||||
private List<ResultSet> resultSets;
|
||||
|
||||
/// <summary>
|
||||
/// The result sets of the batch execution
|
||||
/// </summary>
|
||||
@@ -75,7 +106,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
{
|
||||
ColumnInfo = set.Columns,
|
||||
Id = index,
|
||||
RowCount = set.Rows.Count
|
||||
RowCount = set.RowCount
|
||||
}).ToArray();
|
||||
}
|
||||
}
|
||||
@@ -87,21 +118,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
|
||||
#endregion
|
||||
|
||||
public Batch(string batchText, int startLine)
|
||||
{
|
||||
// Sanity check for input
|
||||
if (string.IsNullOrEmpty(batchText))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(batchText), "Query text cannot be null");
|
||||
}
|
||||
|
||||
// Initialize the internal state
|
||||
BatchText = batchText;
|
||||
StartLine = startLine - 1; // -1 to make sure that the line number of the batch is 0-indexed, since SqlParser gives 1-indexed line numbers
|
||||
HasExecuted = false;
|
||||
resultSets = new List<ResultSet>();
|
||||
resultMessages = new List<string>();
|
||||
}
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Executes this batch and captures any server messages that are returned.
|
||||
@@ -148,23 +165,14 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
}
|
||||
|
||||
// Read until we hit the end of the result set
|
||||
ResultSet resultSet = new ResultSet();
|
||||
while (await reader.ReadAsync(cancellationToken))
|
||||
{
|
||||
resultSet.AddRow(reader);
|
||||
}
|
||||
|
||||
// Read off the column schema information
|
||||
if (reader.CanGetColumnSchema())
|
||||
{
|
||||
resultSet.Columns = reader.GetColumnSchema().ToArray();
|
||||
}
|
||||
ResultSet resultSet = new ResultSet(reader, outputFileFactory);
|
||||
await resultSet.ReadResultToEnd(cancellationToken);
|
||||
|
||||
// Add the result set to the results of the query
|
||||
resultSets.Add(resultSet);
|
||||
|
||||
// Add a message for the number of rows the query returned
|
||||
resultMessages.Add(string.Format(RowsAffectedFormat, resultSet.Rows.Count));
|
||||
resultMessages.Add(string.Format(RowsAffectedFormat, resultSet.RowCount));
|
||||
} while (await reader.NextResultAsync(cancellationToken));
|
||||
}
|
||||
}
|
||||
@@ -200,7 +208,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
/// <param name="startRow">The starting row of the results</param>
|
||||
/// <param name="rowCount">How many rows to retrieve</param>
|
||||
/// <returns>A subset of results</returns>
|
||||
public ResultSetSubset GetSubset(int resultSetIndex, int startRow, int rowCount)
|
||||
public Task<ResultSetSubset> GetSubset(int resultSetIndex, int startRow, int rowCount)
|
||||
{
|
||||
// Sanity check to make sure we have valid numbers
|
||||
if (resultSetIndex < 0 || resultSetIndex >= resultSets.Count)
|
||||
@@ -213,6 +221,8 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
return resultSets[resultSetIndex].GetSubset(startRow, rowCount);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Helpers
|
||||
|
||||
/// <summary>
|
||||
@@ -259,5 +269,33 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable Implementation
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
foreach (ResultSet r in ResultSets)
|
||||
{
|
||||
r.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user