mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-16 01:25:41 -05:00
Query execution settings support (#812)
* WIP * WIP 3 * WIP 3 * Additional query settings updates * Add settings tets * Address code review feeback * Updates from testing
This commit is contained in:
@@ -20,6 +20,7 @@ using Microsoft.SqlTools.ServiceLayer.BatchParser.ExecutionEngineCode;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
{
|
||||
@@ -94,7 +95,13 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
/// <param name="connection">The information of the connection to use to execute the query</param>
|
||||
/// <param name="settings">Settings for how to execute the query, from the user</param>
|
||||
/// <param name="outputFactory">Factory for creating output files</param>
|
||||
public Query(string queryText, ConnectionInfo connection, QueryExecutionSettings settings, IFileStreamFactory outputFactory, bool getFullColumnSchema = false)
|
||||
public Query(
|
||||
string queryText,
|
||||
ConnectionInfo connection,
|
||||
QueryExecutionSettings settings,
|
||||
IFileStreamFactory outputFactory,
|
||||
bool getFullColumnSchema = false,
|
||||
bool applyExecutionSettings = false)
|
||||
{
|
||||
// Sanity check for input
|
||||
Validate.IsNotNull(nameof(queryText), queryText);
|
||||
@@ -129,20 +136,9 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
BeforeBatches = new List<Batch>();
|
||||
AfterBatches = new List<Batch>();
|
||||
|
||||
if (DoesSupportExecutionPlan(connection))
|
||||
if (applyExecutionSettings)
|
||||
{
|
||||
// Checking settings for execution plan options
|
||||
if (settings.ExecutionPlanOptions.IncludeEstimatedExecutionPlanXml)
|
||||
{
|
||||
// Enable set showplan xml
|
||||
AddBatch(string.Format(SetShowPlanXml, On), BeforeBatches, outputFactory);
|
||||
AddBatch(string.Format(SetShowPlanXml, Off), AfterBatches, outputFactory);
|
||||
}
|
||||
else if (settings.ExecutionPlanOptions.IncludeActualExecutionPlanXml)
|
||||
{
|
||||
AddBatch(string.Format(SetStatisticsXml, On), BeforeBatches, outputFactory);
|
||||
AddBatch(string.Format(SetStatisticsXml, Off), AfterBatches, outputFactory);
|
||||
}
|
||||
ApplyExecutionSettings(connection, settings, outputFactory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -509,6 +505,118 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
batchSet.Add(new Batch(query, null, batchSet.Count, outputFactory, 1));
|
||||
}
|
||||
|
||||
private void ApplyExecutionSettings(
|
||||
ConnectionInfo connection,
|
||||
QueryExecutionSettings settings,
|
||||
IFileStreamFactory outputFactory)
|
||||
{
|
||||
QuerySettingsHelper helper = new QuerySettingsHelper(settings);
|
||||
|
||||
// set query execution plan options
|
||||
if (DoesSupportExecutionPlan(connection))
|
||||
{
|
||||
// Checking settings for execution plan options
|
||||
if (settings.ExecutionPlanOptions.IncludeEstimatedExecutionPlanXml)
|
||||
{
|
||||
// Enable set showplan xml
|
||||
AddBatch(string.Format(SetShowPlanXml, On), BeforeBatches, outputFactory);
|
||||
AddBatch(string.Format(SetShowPlanXml, Off), AfterBatches, outputFactory);
|
||||
}
|
||||
else if (settings.ExecutionPlanOptions.IncludeActualExecutionPlanXml)
|
||||
{
|
||||
AddBatch(string.Format(SetStatisticsXml, On), BeforeBatches, outputFactory);
|
||||
AddBatch(string.Format(SetStatisticsXml, Off), AfterBatches, outputFactory);
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder builderBefore = new StringBuilder(512);
|
||||
StringBuilder builderAfter = new StringBuilder(512);
|
||||
|
||||
if (!connection.IsSqlDW)
|
||||
{
|
||||
// "set noexec off" should be the very first command, cause everything after
|
||||
// corresponding "set noexec on" is not executed until "set noexec off"
|
||||
// is encounted
|
||||
if (!settings.NoExec)
|
||||
{
|
||||
builderBefore.AppendFormat("{0} ", helper.SetNoExecString);
|
||||
}
|
||||
|
||||
if (settings.StatisticsIO)
|
||||
{
|
||||
builderBefore.AppendFormat("{0} ", helper.GetSetStatisticsIOString(true));
|
||||
builderAfter.AppendFormat("{0} ", helper.GetSetStatisticsIOString (false));
|
||||
}
|
||||
|
||||
if (settings.StatisticsTime)
|
||||
{
|
||||
builderBefore.AppendFormat("{0} ", helper.GetSetStatisticsTimeString (true));
|
||||
builderAfter.AppendFormat("{0} ", helper.GetSetStatisticsTimeString(false));
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.ParseOnly)
|
||||
{
|
||||
builderBefore.AppendFormat("{0} ", helper.GetSetParseOnlyString(true));
|
||||
builderAfter.AppendFormat("{0} ", helper.GetSetParseOnlyString(false));
|
||||
}
|
||||
|
||||
// append first part of exec options
|
||||
builderBefore.AppendFormat("{0} {1} {2}",
|
||||
helper.SetRowCountString, helper.SetTextSizeString, helper.SetNoCountString);
|
||||
|
||||
if (!connection.IsSqlDW)
|
||||
{
|
||||
// append second part of exec options
|
||||
builderBefore.AppendFormat(" {0} {1} {2} {3} {4} {5} {6}",
|
||||
helper.SetConcatenationNullString,
|
||||
helper.SetArithAbortString,
|
||||
helper.SetLockTimeoutString,
|
||||
helper.SetQueryGovernorCostString,
|
||||
helper.SetDeadlockPriorityString,
|
||||
helper.SetTransactionIsolationLevelString,
|
||||
// We treat XACT_ABORT special in that we don't add anything if the option
|
||||
// isn't checked. This is because we don't want to be overwriting the server
|
||||
// if it has a default of ON since that's something people would specifically
|
||||
// set and having a client change it could be dangerous (the reverse is much
|
||||
// less risky)
|
||||
|
||||
// The full fix would probably be to make the options tri-state instead of
|
||||
// just on/off, where the default is to use the servers default. Until that
|
||||
// happens though this is the best solution we came up with. See TFS#7937925
|
||||
|
||||
// Note that users can always specifically add SET XACT_ABORT OFF to their
|
||||
// queries if they do truly want to set it off. We just don't want to
|
||||
// do it silently (since the default is going to be off)
|
||||
settings.XactAbortOn ? helper.SetXactAbortString : string.Empty);
|
||||
|
||||
// append Ansi options
|
||||
builderBefore.AppendFormat(" {0} {1} {2} {3} {4} {5} {6}",
|
||||
helper.SetAnsiNullsString, helper.SetAnsiNullDefaultString, helper.SetAnsiPaddingString,
|
||||
helper.SetAnsiWarningsString, helper.SetCursorCloseOnCommitString,
|
||||
helper.SetImplicitTransactionString, helper.SetQuotedIdentifierString);
|
||||
|
||||
// "set noexec on" should be the very last command, cause everything after it is not
|
||||
// being executed unitl "set noexec off" is encounered
|
||||
if (settings.NoExec)
|
||||
{
|
||||
builderBefore.AppendFormat("{0} ", helper.SetNoExecString);
|
||||
}
|
||||
}
|
||||
|
||||
// add connection option statements before query execution
|
||||
if (builderBefore.Length > 0)
|
||||
{
|
||||
AddBatch(builderBefore.ToString(), BeforeBatches, outputFactory);
|
||||
}
|
||||
|
||||
// add connection option statements after query execution
|
||||
if (builderAfter.Length > 0)
|
||||
{
|
||||
AddBatch(builderAfter.ToString(), AfterBatches, outputFactory);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable Implementation
|
||||
@@ -541,7 +649,8 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
/// <summary>
|
||||
/// Does this connection support XML Execution plans
|
||||
/// </summary>
|
||||
private bool DoesSupportExecutionPlan(ConnectionInfo connectionInfo) {
|
||||
private bool DoesSupportExecutionPlan(ConnectionInfo connectionInfo)
|
||||
{
|
||||
// Determining which execution plan options may be applied (may be added to for pre-yukon support)
|
||||
return (!connectionInfo.IsSqlDW && connectionInfo.MajorVersion >= 9);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// 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.Hosting.Protocol.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.SqlContext;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters for the query execution options request
|
||||
/// </summary>
|
||||
public class QueryExecutionOptionsParams
|
||||
{
|
||||
public string OwnerUri { get; set; }
|
||||
|
||||
public QueryExecutionSettings Options { get; set; }
|
||||
}
|
||||
|
||||
public class QueryExecutionOptionsRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<QueryExecutionOptionsParams, bool> Type =
|
||||
RequestType<QueryExecutionOptionsParams, bool>.Create("query/setexecutionoptions");
|
||||
}
|
||||
}
|
||||
@@ -109,6 +109,11 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
/// </summary>
|
||||
internal ConcurrentDictionary<string, Query> ActiveQueries => queries.Value;
|
||||
|
||||
/// <summary>
|
||||
/// The collection of query execution options
|
||||
/// </summary>
|
||||
internal ConcurrentDictionary<string, QueryExecutionSettings> ActiveQueryExecutionSettings => queryExecutionSettings.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Internal task for testability
|
||||
/// </summary>
|
||||
@@ -127,6 +132,12 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
private readonly Lazy<ConcurrentDictionary<string, Query>> queries =
|
||||
new Lazy<ConcurrentDictionary<string, Query>>(() => new ConcurrentDictionary<string, Query>());
|
||||
|
||||
/// <summary>
|
||||
/// Internal storage of active query settings
|
||||
/// </summary>
|
||||
private readonly Lazy<ConcurrentDictionary<string, QueryExecutionSettings>> queryExecutionSettings =
|
||||
new Lazy<ConcurrentDictionary<string, QueryExecutionSettings>>(() => new ConcurrentDictionary<string, QueryExecutionSettings>());
|
||||
|
||||
/// <summary>
|
||||
/// Settings that will be used to execute queries. Internal for unit testing
|
||||
/// </summary>
|
||||
@@ -165,6 +176,10 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
serviceHost.SetRequestHandler(SaveResultsAsXmlRequest.Type, HandleSaveResultsAsXmlRequest);
|
||||
serviceHost.SetRequestHandler(QueryExecutionPlanRequest.Type, HandleExecutionPlanRequest);
|
||||
serviceHost.SetRequestHandler(SimpleExecuteRequest.Type, HandleSimpleExecuteRequest);
|
||||
serviceHost.SetRequestHandler(QueryExecutionOptionsRequest.Type, HandleQueryExecutionOptionsRequest);
|
||||
|
||||
// Register the file open update handler
|
||||
WorkspaceService<SqlToolsSettings>.Instance.RegisterTextDocCloseCallback(HandleDidCloseTextDocumentNotification);
|
||||
|
||||
// Register handler for shutdown event
|
||||
serviceHost.RegisterShutdownTask((shutdownParams, requestContext) =>
|
||||
@@ -203,7 +218,15 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
// Use the internal handler to launch the query
|
||||
WorkTask = Task.Run(async () =>
|
||||
{
|
||||
await InterServiceExecuteQuery(executeParams, null, requestContext, queryCreateSuccessAction, queryCreateFailureAction, null, null);
|
||||
await InterServiceExecuteQuery(
|
||||
executeParams,
|
||||
null,
|
||||
requestContext,
|
||||
queryCreateSuccessAction,
|
||||
queryCreateFailureAction,
|
||||
null,
|
||||
null,
|
||||
isQueryEditor(executeParams.OwnerUri));
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -351,6 +374,33 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Handles a request to set query execution options
|
||||
/// </summary>
|
||||
internal async Task HandleQueryExecutionOptionsRequest(QueryExecutionOptionsParams queryExecutionOptionsParams,
|
||||
RequestContext<bool> requestContext)
|
||||
{
|
||||
try
|
||||
{
|
||||
string uri = queryExecutionOptionsParams.OwnerUri;
|
||||
if (ActiveQueryExecutionSettings.ContainsKey(uri))
|
||||
{
|
||||
QueryExecutionSettings settings;
|
||||
ActiveQueryExecutionSettings.TryRemove(uri, out settings);
|
||||
}
|
||||
|
||||
ActiveQueryExecutionSettings.TryAdd(uri, queryExecutionOptionsParams.Options);
|
||||
|
||||
await requestContext.SendResult(true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// This was unexpected, so send back as error
|
||||
await requestContext.SendError(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles a request to get an execution plan
|
||||
/// </summary>
|
||||
@@ -524,7 +574,8 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
Func<Query, Task<bool>> queryCreateSuccessFunc,
|
||||
Func<string, Task> queryCreateFailFunc,
|
||||
Query.QueryAsyncEventHandler querySuccessFunc,
|
||||
Query.QueryAsyncErrorEventHandler queryFailureFunc)
|
||||
Query.QueryAsyncErrorEventHandler queryFailureFunc,
|
||||
bool applyExecutionSettings = false)
|
||||
{
|
||||
Validate.IsNotNull(nameof(executeParams), executeParams);
|
||||
Validate.IsNotNull(nameof(queryEventSender), queryEventSender);
|
||||
@@ -533,7 +584,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
try
|
||||
{
|
||||
// Get a new active query
|
||||
newQuery = CreateQuery(executeParams, connInfo);
|
||||
newQuery = CreateQuery(executeParams, connInfo, applyExecutionSettings);
|
||||
if (queryCreateSuccessFunc != null && !await queryCreateSuccessFunc(newQuery))
|
||||
{
|
||||
// The callback doesn't want us to continue, for some reason
|
||||
@@ -615,19 +666,49 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
subsetParams.RowsStartIndex, subsetParams.RowsCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle the file open notification
|
||||
/// </summary>
|
||||
/// <param name="scriptFile"></param>
|
||||
/// <param name="eventContext"></param>
|
||||
/// <returns></returns>
|
||||
public async Task HandleDidCloseTextDocumentNotification(
|
||||
string uri,
|
||||
ScriptFile scriptFile,
|
||||
EventContext eventContext)
|
||||
{
|
||||
try
|
||||
{
|
||||
// remove any query execution settings when an editor is closed
|
||||
if (this.ActiveQueryExecutionSettings.ContainsKey(uri))
|
||||
{
|
||||
QueryExecutionSettings settings;
|
||||
this.ActiveQueryExecutionSettings.TryRemove(uri, out settings);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(TraceEventType.Error, "Unknown error " + ex.ToString());
|
||||
}
|
||||
await Task.FromResult(true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Helpers
|
||||
|
||||
|
||||
|
||||
private Query CreateQuery(ExecuteRequestParamsBase executeParams, ConnectionInfo connInfo)
|
||||
private Query CreateQuery(
|
||||
ExecuteRequestParamsBase executeParams,
|
||||
ConnectionInfo connInfo,
|
||||
bool applyExecutionSettings)
|
||||
{
|
||||
// Attempt to get the connection for the editor
|
||||
ConnectionInfo connectionInfo;
|
||||
if (connInfo != null) {
|
||||
if (connInfo != null)
|
||||
{
|
||||
connectionInfo = connInfo;
|
||||
} else if (!ConnectionService.TryFindConnection(executeParams.OwnerUri, out connectionInfo))
|
||||
}
|
||||
else if (!ConnectionService.TryFindConnection(executeParams.OwnerUri, out connectionInfo))
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(executeParams.OwnerUri), SR.QueryServiceQueryInvalidOwnerUri);
|
||||
}
|
||||
@@ -643,15 +724,39 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
oldQuery.Dispose();
|
||||
ActiveQueries.TryRemove(executeParams.OwnerUri, out oldQuery);
|
||||
}
|
||||
|
||||
// Retrieve the current settings for executing the query with
|
||||
QueryExecutionSettings settings = Settings.QueryExecutionSettings;
|
||||
|
||||
// Apply execution parameter settings
|
||||
settings.ExecutionPlanOptions = executeParams.ExecutionPlanOptions;
|
||||
|
||||
// check if there are active query execution settings for the editor, otherwise, use the global settings
|
||||
QueryExecutionSettings settings;
|
||||
if (this.ActiveQueryExecutionSettings.TryGetValue(executeParams.OwnerUri, out settings))
|
||||
{
|
||||
// special-case handling for query plan options to maintain compat with query execution API parameters
|
||||
// the logic is that if either the query execute API parameters or the active query setttings
|
||||
// request a plan then enable the query option
|
||||
ExecutionPlanOptions executionPlanOptions = executeParams.ExecutionPlanOptions;
|
||||
if (settings.IncludeActualExecutionPlanXml)
|
||||
{
|
||||
executionPlanOptions.IncludeActualExecutionPlanXml = settings.IncludeActualExecutionPlanXml;
|
||||
}
|
||||
if (settings.IncludeEstimatedExecutionPlanXml)
|
||||
{
|
||||
executionPlanOptions.IncludeEstimatedExecutionPlanXml = settings.IncludeEstimatedExecutionPlanXml;
|
||||
}
|
||||
settings.ExecutionPlanOptions = executionPlanOptions;
|
||||
}
|
||||
else
|
||||
{
|
||||
settings = Settings.QueryExecutionSettings;
|
||||
settings.ExecutionPlanOptions = executeParams.ExecutionPlanOptions;
|
||||
}
|
||||
|
||||
// If we can't add the query now, it's assumed the query is in progress
|
||||
Query newQuery = new Query(GetSqlText(executeParams), connectionInfo, settings, BufferFileFactory, executeParams.GetFullColumnSchema);
|
||||
Query newQuery = new Query(
|
||||
GetSqlText(executeParams),
|
||||
connectionInfo,
|
||||
settings,
|
||||
BufferFileFactory,
|
||||
executeParams.GetFullColumnSchema,
|
||||
applyExecutionSettings);
|
||||
if (!ActiveQueries.TryAdd(executeParams.OwnerUri, newQuery))
|
||||
{
|
||||
newQuery.Dispose();
|
||||
@@ -949,6 +1054,18 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify if the URI maps to a query editor document
|
||||
/// </summary>
|
||||
/// <param name="uri"></param>
|
||||
/// <returns></returns>
|
||||
private bool isQueryEditor(string uri)
|
||||
{
|
||||
return (!string.IsNullOrWhiteSpace(uri)
|
||||
&& (uri.StartsWith("untitled:")
|
||||
|| uri.StartsWith("file:")));
|
||||
}
|
||||
|
||||
~QueryExecutionService()
|
||||
{
|
||||
Dispose(false);
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
//
|
||||
// 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 Microsoft.SqlTools.ServiceLayer.SqlContext;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
{
|
||||
/// <summary>
|
||||
/// Service for executing queries
|
||||
/// </summary>
|
||||
public class QuerySettingsHelper
|
||||
{
|
||||
//strings for various "SET <option> ON/OFF" statements
|
||||
private static readonly string s_On = "ON";
|
||||
private static readonly string s_Off = "OFF";
|
||||
private static readonly string s_Low = "LOW";
|
||||
private static readonly string s_Normal = "NORMAL";
|
||||
private static readonly string s_SetNoCount = "SET NOCOUNT {0}";
|
||||
private static readonly string s_SetConcatenationNull = "SET CONCAT_NULL_YIELDS_NULL {0}";
|
||||
private static readonly string s_SetNumericAbort = "SET NUMERIC_ROUNDABORT {0}";
|
||||
private static readonly string s_SetXACTAbort = "SET XACT_ABORT {0}";
|
||||
private static readonly string s_SetArithAbort = "SET ARITHABORT {0}";
|
||||
private static readonly string s_SetRowCount = "SET ROWCOUNT {0}";
|
||||
private static readonly string s_SetLockTimeout = "SET LOCK_TIMEOUT {0}";
|
||||
private static readonly string s_SetTextSize = "SET TEXTSIZE {0}";
|
||||
private static readonly string s_SetQueryGovernorCost = "SET QUERY_GOVERNOR_COST_LIMIT {0}";
|
||||
private static readonly string s_SetDeadlockPriority = "SET DEADLOCK_PRIORITY {0}";
|
||||
private static readonly string s_SetTranIsolationLevel = "SET TRANSACTION ISOLATION LEVEL {0}";
|
||||
private static readonly string s_SetAnsiNulls = "SET ANSI_NULLS {0}";
|
||||
private static readonly string s_SetAnsiNullDefault = "SET ANSI_NULL_DFLT_ON {0}";
|
||||
private static readonly string s_SetAnsiPadding = "SET ANSI_PADDING {0}";
|
||||
private static readonly string s_SetAnsiWarnings = "SET ANSI_WARNINGS {0}";
|
||||
private static readonly string s_SetCursorCloseOnCommit = "SET CURSOR_CLOSE_ON_COMMIT {0}";
|
||||
private static readonly string s_SetImplicitTransaction = "SET IMPLICIT_TRANSACTIONS {0}";
|
||||
private static readonly string s_SetQuotedIdentifier = "SET QUOTED_IDENTIFIER {0}";
|
||||
private static readonly string s_SetNoExec = "SET NOEXEC {0}";
|
||||
private static readonly string s_SetStatisticsTime = "SET STATISTICS TIME {0}";
|
||||
private static readonly string s_SetStatisticsIO = "SET STATISTICS IO {0}";
|
||||
private static readonly string s_SetParseOnly = "SET PARSEONLY {0}";
|
||||
|
||||
private QueryExecutionSettings settings;
|
||||
|
||||
public QuerySettingsHelper(QueryExecutionSettings settings)
|
||||
{
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public string SetNoCountString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetNoCount, (this.settings.NoCount ? s_On : s_Off));
|
||||
}
|
||||
}
|
||||
|
||||
public string SetConcatenationNullString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetConcatenationNull, (this.settings.ConcatNullYieldsNull ? s_On : s_Off));
|
||||
}
|
||||
}
|
||||
|
||||
public string SetNumericAbortString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetNumericAbort, (this.settings.ArithAbort ? s_On : s_Off));
|
||||
}
|
||||
}
|
||||
|
||||
public string SetXactAbortString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetXACTAbort, (this.settings.XactAbortOn ? s_On : s_Off));
|
||||
}
|
||||
}
|
||||
|
||||
public string SetArithAbortString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetArithAbort, (this.settings.ArithAbort ? s_On : s_Off));
|
||||
}
|
||||
}
|
||||
|
||||
public string SetRowCountString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetRowCount, this.settings.RowCount);
|
||||
}
|
||||
}
|
||||
|
||||
public string SetLockTimeoutString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetLockTimeout, this.settings.LockTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
public string SetTextSizeString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetTextSize, this.settings.TextSize);
|
||||
}
|
||||
}
|
||||
|
||||
public string SetQueryGovernorCostString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetQueryGovernorCost, this.settings.QueryGovernorCostLimit);
|
||||
}
|
||||
}
|
||||
|
||||
public string SetDeadlockPriorityString
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
bool isDeadlockPriorityLow = string.Compare(this.settings.DeadlockPriority, "low", StringComparison.OrdinalIgnoreCase) == 0;
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetDeadlockPriority, (isDeadlockPriorityLow ? s_Low : s_Normal));
|
||||
}
|
||||
}
|
||||
|
||||
public string SetTransactionIsolationLevelString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetTranIsolationLevel, this.settings.TransactionIsolationLevel);
|
||||
}
|
||||
}
|
||||
|
||||
public string SetAnsiNullsString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetAnsiNulls, (this.settings.AnsiNulls ? s_On : s_Off));
|
||||
}
|
||||
}
|
||||
|
||||
public string SetAnsiNullDefaultString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetAnsiNullDefault, (this.settings.AnsiNullDefaultOn ? s_On : s_Off));
|
||||
}
|
||||
}
|
||||
|
||||
public string SetAnsiPaddingString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetAnsiPadding, (this.settings.AnsiPadding ? s_On : s_Off));
|
||||
}
|
||||
}
|
||||
|
||||
public string SetAnsiWarningsString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetAnsiWarnings, (this.settings.AnsiWarnings ? s_On : s_Off));
|
||||
}
|
||||
}
|
||||
|
||||
public string SetCursorCloseOnCommitString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetCursorCloseOnCommit, (this.settings.CursorCloseOnCommit ? s_On : s_Off));
|
||||
}
|
||||
}
|
||||
|
||||
public string SetImplicitTransactionString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetImplicitTransaction, (this.settings.ImplicitTransactions ? s_On : s_Off));
|
||||
}
|
||||
}
|
||||
|
||||
public string SetQuotedIdentifierString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetQuotedIdentifier, (this.settings.QuotedIdentifier ? s_On : s_Off));
|
||||
}
|
||||
}
|
||||
|
||||
public string SetNoExecString
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetNoExec, (this.settings.NoExec ? s_On : s_Off));
|
||||
}
|
||||
}
|
||||
|
||||
public string GetSetStatisticsTimeString(bool? on)
|
||||
{
|
||||
on = on ?? this.settings.StatisticsTime;
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetStatisticsTime, (on.Value ? s_On : s_Off));
|
||||
}
|
||||
|
||||
public string GetSetStatisticsIOString(bool? on)
|
||||
{
|
||||
on = on ?? this.settings.StatisticsIO;
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetStatisticsIO, (on.Value ? s_On : s_Off));
|
||||
}
|
||||
|
||||
public string GetSetParseOnlyString(bool? on)
|
||||
{
|
||||
on = on ?? this.settings.ParseOnly;
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, s_SetParseOnly, (on.Value ? s_On : s_Off));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user