diff --git a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Batch.cs b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Batch.cs
index 295e6df9..d44b78f8 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Batch.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Batch.cs
@@ -58,7 +58,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
///
/// Special action which this batch performed
///
- private SpecialAction specialAction;
+ private readonly SpecialAction specialAction;
#endregion
@@ -128,7 +128,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
/// Localized timestamp for when the execution completed.
/// Stored in UTC ISO 8601 format; should be localized before displaying to any user
///
- public string ExecutionEndTimeStamp { get { return executionEndTime.ToString("o"); } }
+ public string ExecutionEndTimeStamp => executionEndTime.ToString("o");
///
/// Localized timestamp for how long it took for the execution to complete
@@ -146,7 +146,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
/// Localized timestamp for when the execution began.
/// Stored in UTC ISO 8601 format; should be localized before displaying to any user
///
- public string ExecutionStartTimeStamp { get { return executionStartTime.ToString("o"); } }
+ public string ExecutionStartTimeStamp => executionStartTime.ToString("o");
///
/// Whether or not this batch encountered an error that halted execution
@@ -161,15 +161,12 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
///
/// Ordinal of the batch in the query
///
- public int Id { get; private set; }
+ public int Id { get; }
///
/// The result sets of the batch execution
///
- public IList ResultSets
- {
- get { return resultSets; }
- }
+ public IList ResultSets => resultSets;
///
/// Property for generating a set result set summaries from the result sets
@@ -381,7 +378,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
/// Generates an execution plan
///
/// The index for selecting the result set
- /// An exeuction plan object
+ /// An execution plan object
public Task GetExecutionPlan(int resultSetIndex)
{
ResultSet targetResultSet;
diff --git a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/SaveAsCsvFileStreamFactory.cs b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/SaveAsCsvFileStreamFactory.cs
index ebfe173e..69d625e0 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/SaveAsCsvFileStreamFactory.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/SaveAsCsvFileStreamFactory.cs
@@ -6,6 +6,7 @@
using System;
using System.IO;
using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts;
+using Microsoft.SqlTools.ServiceLayer.SqlContext;
namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
{
@@ -17,6 +18,11 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
{
#region Properties
+ ///
+ /// Settings for query execution
+ ///
+ public QueryExecutionSettings QueryExecutionSettings { get; set; }
+
///
/// Parameters for the save as CSV request
///
@@ -41,7 +47,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
/// Stream reader
public IFileStreamReader GetReader(string fileName)
{
- return new ServiceBufferFileStreamReader(new FileStream(fileName, FileMode.Open, FileAccess.Read));
+ return new ServiceBufferFileStreamReader(new FileStream(fileName, FileMode.Open, FileAccess.Read), QueryExecutionSettings);
}
///
diff --git a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/SaveAsJsonFileStreamFactory.cs b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/SaveAsJsonFileStreamFactory.cs
index 02cde694..dc79686d 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/SaveAsJsonFileStreamFactory.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/SaveAsJsonFileStreamFactory.cs
@@ -6,6 +6,7 @@
using System;
using System.IO;
using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts;
+using Microsoft.SqlTools.ServiceLayer.SqlContext;
namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
{
@@ -14,6 +15,11 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
#region Properties
+ ///
+ /// Settings for query execution
+ ///
+ public QueryExecutionSettings QueryExecutionSettings { get; set; }
+
///
/// Parameters for the save as JSON request
///
@@ -28,7 +34,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
[Obsolete]
public string CreateFile()
{
- throw new NotImplementedException();
+ throw new InvalidOperationException();
}
///
@@ -38,7 +44,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
/// Stream reader
public IFileStreamReader GetReader(string fileName)
{
- return new ServiceBufferFileStreamReader(new FileStream(fileName, FileMode.Open, FileAccess.Read));
+ return new ServiceBufferFileStreamReader(new FileStream(fileName, FileMode.Open, FileAccess.Read), QueryExecutionSettings);
}
///
diff --git a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/ServiceBufferFileStreamFactory.cs b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/ServiceBufferFileStreamFactory.cs
index 60b819a6..9fd915c8 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/ServiceBufferFileStreamFactory.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/ServiceBufferFileStreamFactory.cs
@@ -4,6 +4,7 @@
//
using System.IO;
+using Microsoft.SqlTools.ServiceLayer.SqlContext;
namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
{
@@ -15,14 +16,9 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
#region Properties
///
- /// The maximum number of characters to store from long text fields
+ /// The settings for query execution
///
- public int MaxCharsToStore { get; set; }
-
- ///
- /// The maximum number of characters to store from xml fields
- ///
- public int MaxXmlCharsToStore { get; set; }
+ public QueryExecutionSettings ExecutionSettings { get; set; }
#endregion
@@ -43,7 +39,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
/// A
public IFileStreamReader GetReader(string fileName)
{
- return new ServiceBufferFileStreamReader(new FileStream(fileName, FileMode.Open, FileAccess.Read));
+ return new ServiceBufferFileStreamReader(new FileStream(fileName, FileMode.Open, FileAccess.Read), ExecutionSettings);
}
///
@@ -54,7 +50,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
/// A
public IFileStreamWriter GetWriter(string fileName)
{
- return new ServiceBufferFileStreamWriter(new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite), MaxCharsToStore, MaxXmlCharsToStore);
+ return new ServiceBufferFileStreamWriter(new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite), ExecutionSettings);
}
///
diff --git a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/ServiceBufferFileStreamReader.cs b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/ServiceBufferFileStreamReader.cs
index e8bb72cf..f836e74d 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/ServiceBufferFileStreamReader.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/ServiceBufferFileStreamReader.cs
@@ -9,6 +9,8 @@ using System.Data.SqlTypes;
using System.IO;
using System.Text;
using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts;
+using Microsoft.SqlTools.ServiceLayer.SqlContext;
+using Microsoft.SqlTools.ServiceLayer.Utility;
namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
{
@@ -30,6 +32,8 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
private byte[] buffer;
+ private readonly QueryExecutionSettings executionSettings;
+
private readonly Stream fileStream;
private readonly Dictionary> readMethods;
@@ -40,8 +44,12 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
/// Constructs a new ServiceBufferFileStreamReader and initializes its state
///
/// The filestream to read from
- public ServiceBufferFileStreamReader(Stream stream)
- {
+ /// The query execution settings
+ public ServiceBufferFileStreamReader(Stream stream, QueryExecutionSettings settings)
+ {
+ Validate.IsNotNull(nameof(stream), stream);
+ Validate.IsNotNull(nameof(settings), settings);
+
// Open file for reading/writing
if (!stream.CanRead || !stream.CanSeek)
{
@@ -49,6 +57,8 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
}
fileStream = stream;
+ executionSettings = settings;
+
// Create internal buffer
buffer = new byte[DefaultBufferSize];
@@ -259,7 +269,11 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
/// A bool
internal FileStreamReadResult ReadBoolean(long fileOffset)
{
- return ReadCellHelper(fileOffset, length => buffer[0] == 0x1);
+ // Override the stringifier with numeric values if the user prefers that
+ return ReadCellHelper(fileOffset, length => buffer[0] == 0x1,
+ toStringFunc: val => executionSettings.DisplayBitAsNumber
+ ? val ? "1" : "0"
+ : val.ToString());
}
///
@@ -505,10 +519,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
///
/// +
///
- public int TotalLength
- {
- get { return LengthLength + ValueLength; }
- }
+ public int TotalLength => LengthLength + ValueLength;
}
#region IDisposable Implementation
diff --git a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/ServiceBufferFileStreamWriter.cs b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/ServiceBufferFileStreamWriter.cs
index e46d1227..c56d43e1 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/ServiceBufferFileStreamWriter.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/ServiceBufferFileStreamWriter.cs
@@ -10,6 +10,7 @@ using System.Diagnostics;
using System.IO;
using System.Text;
using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts;
+using Microsoft.SqlTools.ServiceLayer.SqlContext;
using Microsoft.SqlTools.ServiceLayer.Utility;
namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
@@ -24,8 +25,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
#region Member Variables
private readonly Stream fileStream;
- private readonly int maxCharsToStore;
- private readonly int maxXmlCharsToStore;
+ private readonly QueryExecutionSettings executionSettings;
private byte[] byteBuffer;
private readonly short[] shortBuffer;
@@ -46,16 +46,19 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
/// Constructs a new writer
///
/// The file wrapper to use as the underlying file stream
- /// Maximum number of characters to store for long text fields
- /// Maximum number of characters to store for XML fields
- public ServiceBufferFileStreamWriter(Stream stream, int maxCharsToStore, int maxXmlCharsToStore)
+ /// The query execution settings
+ public ServiceBufferFileStreamWriter(Stream stream, QueryExecutionSettings settings)
{
+ Validate.IsNotNull(nameof(stream), stream);
+ Validate.IsNotNull(nameof(settings), settings);
+
// open file for reading/writing
if (!stream.CanWrite || !stream.CanSeek)
{
throw new InvalidOperationException("Stream must be writable and seekable.");
}
fileStream = stream;
+ executionSettings = settings;
// create internal buffer
byteBuffer = new byte[DefaultBufferLength];
@@ -69,10 +72,6 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
doubleBuffer = new double[1];
floatBuffer = new float[1];
- // Store max chars to store
- this.maxCharsToStore = maxCharsToStore;
- this.maxXmlCharsToStore = maxXmlCharsToStore;
-
// Define what methods to use to write a type to the file
writeMethods = new Dictionary>
{
@@ -145,18 +144,18 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
// this is a long field
if (ci.IsBytes)
{
- values[i] = reader.GetBytesWithMaxCapacity(i, maxCharsToStore);
+ values[i] = reader.GetBytesWithMaxCapacity(i, executionSettings.MaxCharsToStore);
}
else if (ci.IsChars)
{
- Debug.Assert(maxCharsToStore > 0);
- values[i] = reader.GetCharsWithMaxCapacity(i,
- ci.IsXml ? maxXmlCharsToStore : maxCharsToStore);
+ int maxChars = ci.IsXml
+ ? executionSettings.MaxXmlCharsToStore
+ : executionSettings.MaxCharsToStore;
+ values[i] = reader.GetCharsWithMaxCapacity(i, maxChars);
}
else if (ci.IsXml)
{
- Debug.Assert(maxXmlCharsToStore > 0);
- values[i] = reader.GetXmlWithMaxCapacity(i, maxXmlCharsToStore);
+ values[i] = reader.GetXmlWithMaxCapacity(i, executionSettings.MaxXmlCharsToStore);
}
else
{
diff --git a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Query.cs b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Query.cs
index 702cabb0..e6db27ec 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Query.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Query.cs
@@ -53,16 +53,6 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
///
private bool hasExecuteBeenCalled;
- ///
- /// Settings for query runtime
- ///
- private QueryExecutionSettings querySettings;
-
- ///
- /// Streaming output factory for the query
- ///
- private IFileStreamFactory streamOutputFactory;
-
///
/// Name of the new database if the database name was changed in the query
///
@@ -109,8 +99,6 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
QueryText = queryText;
editorConnection = connection;
cancellationSource = new CancellationTokenSource();
- querySettings = settings;
- streamOutputFactory = outputFactory;
// Process the query into batches
BatchParserWrapper parser = new BatchParserWrapper();
@@ -135,16 +123,16 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
if (DoesSupportExecutionPlan(connection))
{
// Checking settings for execution plan options
- if (querySettings.ExecutionPlanOptions.IncludeEstimatedExecutionPlanXml)
+ if (settings.ExecutionPlanOptions.IncludeEstimatedExecutionPlanXml)
{
// Enable set showplan xml
- addBatch(string.Format(SetShowPlanXml, On), BeforeBatches, streamOutputFactory);
- addBatch(string.Format(SetShowPlanXml, Off), AfterBatches, streamOutputFactory);
+ AddBatch(string.Format(SetShowPlanXml, On), BeforeBatches, outputFactory);
+ AddBatch(string.Format(SetShowPlanXml, Off), AfterBatches, outputFactory);
}
- else if (querySettings.ExecutionPlanOptions.IncludeActualExecutionPlanXml)
+ else if (settings.ExecutionPlanOptions.IncludeActualExecutionPlanXml)
{
- addBatch(string.Format(SetStatisticsXml, On), BeforeBatches, streamOutputFactory);
- addBatch(string.Format(SetStatisticsXml, Off), AfterBatches, streamOutputFactory);
+ AddBatch(string.Format(SetStatisticsXml, On), BeforeBatches, outputFactory);
+ AddBatch(string.Format(SetStatisticsXml, Off), AfterBatches, outputFactory);
}
}
}
@@ -182,11 +170,6 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
///
public event QueryAsyncEventHandler QueryFailed;
- ///
- /// Callback for when the query connection has failed
- ///
- public event QueryAsyncErrorEventHandler QueryConnectionException;
-
///
/// Event to be called when a resultset has completed.
///
@@ -459,7 +442,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
///
/// Function to add a new batch to a Batch set
///
- private void addBatch(string query, List batchSet, IFileStreamFactory outputFactory)
+ private static void AddBatch(string query, ICollection batchSet, IFileStreamFactory outputFactory)
{
batchSet.Add(new Batch(query, null, batchSet.Count, outputFactory));
}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/QueryExecutionService.cs b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/QueryExecutionService.cs
index 999c126d..da9816d8 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/QueryExecutionService.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/QueryExecutionService.cs
@@ -64,11 +64,14 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
{
get
{
- return BufferFileStreamFactory ?? (BufferFileStreamFactory = new ServiceBufferFileStreamFactory
+ if (BufferFileStreamFactory == null)
{
- MaxCharsToStore = Settings.SqlTools.QueryExecutionSettings.MaxCharsToStore,
- MaxXmlCharsToStore = Settings.SqlTools.QueryExecutionSettings.MaxXmlCharsToStore
- });
+ BufferFileStreamFactory = new ServiceBufferFileStreamFactory
+ {
+ ExecutionSettings = Settings.QueryExecutionSettings
+ };
+ }
+ return BufferFileStreamFactory;
}
}
@@ -295,7 +298,8 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
// Use the default CSV file factory if we haven't overridden it
IFileStreamFactory csvFactory = CsvFileFactory ?? new SaveAsCsvFileStreamFactory
{
- SaveRequestParams = saveParams
+ SaveRequestParams = saveParams,
+ QueryExecutionSettings = Settings.QueryExecutionSettings
};
await SaveResultsHelper(saveParams, requestContext, csvFactory);
}
@@ -309,7 +313,8 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
// Use the default JSON file factory if we haven't overridden it
IFileStreamFactory jsonFactory = JsonFileFactory ?? new SaveAsJsonFileStreamFactory
{
- SaveRequestParams = saveParams
+ SaveRequestParams = saveParams,
+ QueryExecutionSettings = Settings.QueryExecutionSettings
};
await SaveResultsHelper(saveParams, requestContext, jsonFactory);
}
@@ -452,20 +457,8 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
await eventSender.SendEvent(QueryCompleteEvent.Type, eventParams);
};
- Query.QueryAsyncErrorEventHandler errorCallback = async errorMessage =>
- {
- // Send back the error message
- QueryCompleteParams eventParams = new QueryCompleteParams
- {
- OwnerUri = ownerUri,
- //Message = errorMessage
- };
- await eventSender.SendEvent(QueryCompleteEvent.Type, eventParams);
- };
-
query.QueryCompleted += callback;
query.QueryFailed += callback;
- query.QueryConnectionException += errorCallback;
// Setup the batch callbacks
Batch.BatchAsyncEventHandler batchStartCallback = async b =>
diff --git a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/ResultSet.cs b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/ResultSet.cs
index cf0e8b67..b6adeb33 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/ResultSet.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/ResultSet.cs
@@ -25,8 +25,8 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
#region Constants
// Column names of 'for xml' and 'for json' queries
- private const string NameOfForXMLColumn = "XML_F52E2B61-18A1-11d1-B105-00805F49916B";
- private const string NameOfForJSONColumn = "JSON_F52E2B61-18A1-11d1-B105-00805F49916B";
+ private const string NameOfForXmlColumn = "XML_F52E2B61-18A1-11d1-B105-00805F49916B";
+ private const string NameOfForJsonColumn = "JSON_F52E2B61-18A1-11d1-B105-00805F49916B";
private const string YukonXmlShowPlanColumn = "Microsoft SQL Server 2005 XML Showplan";
#endregion
@@ -72,7 +72,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
///
/// The special action which applied to this result set
///
- private SpecialAction specialAction;
+ private readonly SpecialAction specialAction;
#endregion
@@ -251,7 +251,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
/// An execution plan object
public Task GetExecutionPlan()
{
- // Proccess the action just incase is hasn't been yet
+ // Process the action just incase is hasn't been yet
ProcessSpecialAction();
// Sanity check to make sure that the results have been read beforehand
@@ -260,7 +260,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
throw new InvalidOperationException(SR.QueryServiceResultSetNotRead);
}
// Check that we this result set contains a showplan
- else if (!specialAction.ExpectYukonXMLShowPlan)
+ if (!specialAction.ExpectYukonXMLShowPlan)
{
throw new Exception(SR.QueryServiceExecutionPlanNotFound);
}
@@ -268,7 +268,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
return Task.Factory.StartNew(() =>
{
- string content = null;
+ string content;
string format = null;
using (IFileStreamReader fileStreamReader = fileStreamFactory.GetReader(outputFileName))
@@ -333,6 +333,15 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
}
}
+ ///
+ /// Saves the contents of this result set to a file using the IFileStreamFactory provided
+ ///
+ /// Parameters for saving the results to a file
+ ///
+ /// Factory for creating a stream reader/writer combo for writing results to disk
+ ///
+ /// Handler for a successful write of all rows
+ /// Handler for unsuccessful write of all rows
public void SaveAs(SaveResultsRequestParams saveParams, IFileStreamFactory fileFactory,
SaveAsAsyncEventHandler successHandler, SaveAsFailureAsyncEventHandler failureHandler)
{
@@ -475,13 +484,13 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
if (Columns?.Length == 1 && RowCount != 0)
{
- if (Columns[0].ColumnName.Equals(NameOfForXMLColumn, StringComparison.Ordinal))
+ if (Columns[0].ColumnName.Equals(NameOfForXmlColumn, StringComparison.Ordinal))
{
Columns[0].IsXml = true;
isSingleColumnXmlJsonResultSet = true;
RowCount = 1;
}
- else if (Columns[0].ColumnName.Equals(NameOfForJSONColumn, StringComparison.Ordinal))
+ else if (Columns[0].ColumnName.Equals(NameOfForJsonColumn, StringComparison.Ordinal))
{
Columns[0].IsJson = true;
isSingleColumnXmlJsonResultSet = true;
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlContext/QueryExecutionSettings.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlContext/QueryExecutionSettings.cs
index cd269758..5dccf800 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SqlContext/QueryExecutionSettings.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SqlContext/QueryExecutionSettings.cs
@@ -2,6 +2,7 @@
// 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.ServiceLayer.QueryExecution.Contracts;
namespace Microsoft.SqlTools.ServiceLayer.SqlContext
@@ -33,12 +34,17 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlContext
/// Default selection of returning an actual XML showplan with all batches
/// Do not return any execution plan by default
///
- private ExecutionPlanOptions DefaultExecutionPlanOptions = new ExecutionPlanOptions()
+ private static readonly ExecutionPlanOptions DefaultExecutionPlanOptions = new ExecutionPlanOptions
{
IncludeActualExecutionPlanXml = false,
IncludeEstimatedExecutionPlanXml = false
};
+ ///
+ /// Default option for displaying a bit column as a number. (defacto standard as per SSMS)
+ ///
+ private const bool DefaultDisplayBitAsNumber = true;
+
#endregion
#region Member Variables
@@ -51,6 +57,8 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlContext
private ExecutionPlanOptions? executionPlanOptions;
+ private bool? displayBitAsNumber;
+
#endregion
#region Properties
@@ -64,24 +72,46 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlContext
set { batchSeparator = value; }
}
+ ///
+ /// Maximum number of characters to store in temp file for long character fields and binary
+ /// fields. Will use a default if a value was not configured.
+ ///
public int MaxCharsToStore
{
get { return maxCharsToStore ?? DefaultMaxCharsToStore; }
set { maxCharsToStore = value; }
}
+ ///
+ /// Maximum number of characters to store in temp file for XML columns. Will use a default
+ /// value if one was not configured.
+ ///
public int MaxXmlCharsToStore
{
get { return maxXmlCharsToStore ?? DefaultMaxXmlCharsToStore; }
set { maxXmlCharsToStore = value; }
}
+ ///
+ /// Options for returning execution plans when executing queries
+ ///
public ExecutionPlanOptions ExecutionPlanOptions
{
get { return executionPlanOptions ?? DefaultExecutionPlanOptions; }
set { executionPlanOptions = value; }
}
+ ///
+ /// Determines how to generate display value for bit columns. If true, bit columns
+ /// will be rendered as "1" or "0". If false, bit columns will be rendered as
+ /// "true" or "false"
+ ///
+ public bool DisplayBitAsNumber
+ {
+ get { return displayBitAsNumber ?? DefaultDisplayBitAsNumber; }
+ set { displayBitAsNumber = value; }
+ }
+
#endregion
#region Public Methods
@@ -96,6 +126,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlContext
MaxCharsToStore = newSettings.MaxCharsToStore;
MaxXmlCharsToStore = newSettings.MaxXmlCharsToStore;
ExecutionPlanOptions = newSettings.ExecutionPlanOptions;
+ DisplayBitAsNumber = newSettings.DisplayBitAsNumber;
}
#endregion
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestServiceProvider.cs b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestServiceProvider.cs
index 1ed51b65..a9f1e4f7 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestServiceProvider.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestServiceProvider.cs
@@ -111,9 +111,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
return fileName;
});
mock.Setup(fsf => fsf.GetReader(It.IsAny()))
- .Returns(output => new ServiceBufferFileStreamReader(new MemoryStream(storage[output])));
+ .Returns(output => new ServiceBufferFileStreamReader(new MemoryStream(storage[output]), new QueryExecutionSettings()));
mock.Setup(fsf => fsf.GetWriter(It.IsAny()))
- .Returns(output => new ServiceBufferFileStreamWriter(new MemoryStream(storage[output]), 1024, 1024));
+ .Returns(output => new ServiceBufferFileStreamWriter(new MemoryStream(storage[output]), new QueryExecutionSettings()));
return mock.Object;
}
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Common.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Common.cs
index 53fe76ec..0cd1b691 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Common.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Common.cs
@@ -148,9 +148,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution
return fileName;
});
mock.Setup(fsf => fsf.GetReader(It.IsAny()))
- .Returns(output => new ServiceBufferFileStreamReader(new MemoryStream(storage[output])));
+ .Returns(output => new ServiceBufferFileStreamReader(new MemoryStream(storage[output]), new QueryExecutionSettings()));
mock.Setup(fsf => fsf.GetWriter(It.IsAny()))
- .Returns(output => new ServiceBufferFileStreamWriter(new MemoryStream(storage[output]), 1024, 1024));
+ .Returns(output => new ServiceBufferFileStreamWriter(new MemoryStream(storage[output]), new QueryExecutionSettings()));
return mock.Object;
}
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/DataStorage/ServiceBufferFileStreamReaderWriterTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/DataStorage/ServiceBufferFileStreamReaderWriterTests.cs
index d7c2e9b3..43f776b7 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/DataStorage/ServiceBufferFileStreamReaderWriterTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/DataStorage/ServiceBufferFileStreamReaderWriterTests.cs
@@ -12,6 +12,7 @@ using System.Text;
using System.Text.RegularExpressions;
using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts;
using Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage;
+using Microsoft.SqlTools.ServiceLayer.SqlContext;
using Microsoft.SqlTools.ServiceLayer.Test.Utility;
using Moq;
using Xunit;
@@ -20,6 +21,22 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.DataStorage
{
public class ReaderWriterPairTest
{
+ [Fact]
+ public void ReaderStreamNull()
+ {
+ // If: I create a service buffer file stream reader with a null stream
+ // Then: It should throw an exception
+ Assert.Throws(() => new ServiceBufferFileStreamReader(null, new QueryExecutionSettings()));
+ }
+
+ [Fact]
+ public void ReaderSettingsNull()
+ {
+ // If: I create a service buffer file stream reader with null settings
+ // Then: It should throw an exception
+ Assert.Throws(() => new ServiceBufferFileStreamReader(Stream.Null, null));
+ }
+
[Fact]
public void ReaderInvalidStreamCannotRead()
{
@@ -30,7 +47,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.DataStorage
invalidStream.SetupGet(s => s.CanSeek).Returns(true);
Assert.Throws(() =>
{
- ServiceBufferFileStreamReader obj = new ServiceBufferFileStreamReader(invalidStream.Object);
+ ServiceBufferFileStreamReader obj = new ServiceBufferFileStreamReader(invalidStream.Object, new QueryExecutionSettings());
obj.Dispose();
});
}
@@ -45,11 +62,27 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.DataStorage
invalidStream.SetupGet(s => s.CanSeek).Returns(false);
Assert.Throws(() =>
{
- ServiceBufferFileStreamReader obj = new ServiceBufferFileStreamReader(invalidStream.Object);
+ ServiceBufferFileStreamReader obj = new ServiceBufferFileStreamReader(invalidStream.Object, new QueryExecutionSettings());
obj.Dispose();
});
}
+ [Fact]
+ public void WriterStreamNull()
+ {
+ // If: I create a service buffer file stream writer with a null stream
+ // Then: It should throw an exception
+ Assert.Throws(() => new ServiceBufferFileStreamWriter(null, new QueryExecutionSettings()));
+ }
+
+ [Fact]
+ public void WriterSettingsNull()
+ {
+ // If: I create a service buffer file stream writer with null settings
+ // Then: It should throw an exception
+ Assert.Throws(() => new ServiceBufferFileStreamWriter(Stream.Null, null));
+ }
+
[Fact]
public void WriterInvalidStreamCannotWrite()
{
@@ -60,7 +93,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.DataStorage
invalidStream.SetupGet(s => s.CanSeek).Returns(true);
Assert.Throws(() =>
{
- ServiceBufferFileStreamWriter obj = new ServiceBufferFileStreamWriter(invalidStream.Object, 1024, 1024);
+ ServiceBufferFileStreamWriter obj = new ServiceBufferFileStreamWriter(invalidStream.Object, new QueryExecutionSettings());
obj.Dispose();
});
}
@@ -75,20 +108,24 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.DataStorage
invalidStream.SetupGet(s => s.CanSeek).Returns(false);
Assert.Throws(() =>
{
- ServiceBufferFileStreamWriter obj = new ServiceBufferFileStreamWriter(invalidStream.Object, 1024, 1024);
+ ServiceBufferFileStreamWriter obj = new ServiceBufferFileStreamWriter(invalidStream.Object, new QueryExecutionSettings());
obj.Dispose();
});
}
[SuppressMessage("ReSharper", "UnusedParameter.Local")]
- private static string VerifyReadWrite(int valueLength, T value, Func writeFunc, Func readFunc)
+ private static string VerifyReadWrite(int valueLength, T value,
+ Func writeFunc,
+ Func readFunc,
+ QueryExecutionSettings overrideSettings = null)
{
// Setup: Create a mock file stream
byte[] storage = new byte[8192];
+ overrideSettings = overrideSettings ?? new QueryExecutionSettings();
// If:
// ... I write a type T to the writer
- using (ServiceBufferFileStreamWriter writer = new ServiceBufferFileStreamWriter(new MemoryStream(storage), 10, 10))
+ using (ServiceBufferFileStreamWriter writer = new ServiceBufferFileStreamWriter(new MemoryStream(storage), overrideSettings))
{
int writtenBytes = writeFunc(writer, value);
Assert.Equal(valueLength, writtenBytes);
@@ -96,7 +133,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.DataStorage
// ... And read the type T back
FileStreamReadResult outValue;
- using (ServiceBufferFileStreamReader reader = new ServiceBufferFileStreamReader(new MemoryStream(storage)))
+ using (ServiceBufferFileStreamReader reader = new ServiceBufferFileStreamReader(new MemoryStream(storage), overrideSettings))
{
outValue = readFunc(reader);
}
@@ -166,11 +203,29 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.DataStorage
}
[Theory]
- [InlineData(true)]
- [InlineData(false)]
- public void Boolean(bool value)
+ [InlineData(true, true)]
+ [InlineData(false, true)]
+ [InlineData(true, false)]
+ [InlineData(false, false)]
+ public void Boolean(bool value, bool preferNumeric)
{
- VerifyReadWrite(sizeof(bool) + 1, value, (writer, val) => writer.WriteBoolean(val), reader => reader.ReadBoolean(0));
+ string displayValue = VerifyReadWrite(sizeof(bool) + 1, value,
+ (writer, val) => writer.WriteBoolean(val),
+ reader => reader.ReadBoolean(0),
+ new QueryExecutionSettings {DisplayBitAsNumber = preferNumeric}
+ );
+
+ // Validate the display value
+ if (preferNumeric)
+ {
+ int output;
+ Assert.True(int.TryParse(displayValue, out output));
+ }
+ else
+ {
+ bool output;
+ Assert.True(bool.TryParse(displayValue, out output));
+ }
}
[Theory]
@@ -396,7 +451,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.DataStorage
{
// If:
// ... I write null as a string to the writer
- using (ServiceBufferFileStreamWriter writer = new ServiceBufferFileStreamWriter(stream, 10, 10))
+ using (ServiceBufferFileStreamWriter writer = new ServiceBufferFileStreamWriter(stream, new QueryExecutionSettings()))
{
// Then:
// ... I should get an argument null exception
@@ -433,7 +488,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.DataStorage
{
// If:
// ... I write null as a string to the writer
- using (ServiceBufferFileStreamWriter writer = new ServiceBufferFileStreamWriter(stream, 10, 10))
+ using (ServiceBufferFileStreamWriter writer = new ServiceBufferFileStreamWriter(stream, new QueryExecutionSettings()))
{
// Then:
// ... I should get an argument null exception
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SaveResults/ServiceIntegrationTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SaveResults/ServiceIntegrationTests.cs
index 05b0393e..80cb655a 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SaveResults/ServiceIntegrationTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SaveResults/ServiceIntegrationTests.cs
@@ -269,7 +269,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.SaveResults
{
Mock mock = new Mock();
mock.Setup(fsf => fsf.GetReader(It.IsAny()))
- .Returns(output => new ServiceBufferFileStreamReader(new MemoryStream(storage[output])));
+ .Returns(output => new ServiceBufferFileStreamReader(new MemoryStream(storage[output]), new QueryExecutionSettings()));
mock.Setup(fsf => fsf.GetWriter(It.IsAny()))
.Returns(output =>
{
@@ -284,7 +284,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.SaveResults
{
Mock mock = new Mock();
mock.Setup(fsf => fsf.GetReader(It.IsAny()))
- .Returns(output => new ServiceBufferFileStreamReader(new MemoryStream(storage[output])));
+ .Returns(output => new ServiceBufferFileStreamReader(new MemoryStream(storage[output]), new QueryExecutionSettings()));
mock.Setup(fsf => fsf.GetWriter(It.IsAny()))
.Returns(output =>
{