/// <summary> /// Constructor method for ScriptExecutionArgs /// </summary> public ScriptExecutionArgs( string script, IDbConnection connection, int timeOut, ExecutionEngineConditions conditions, IBatchEventsHandler batchEventHandlers) : this(script, connection, timeOut, conditions, batchEventHandlers, 0, null) { // nothing }
/// <summary> /// Constructor method for ScriptExecutionArgs /// </summary> public ScriptExecutionArgs( string script, SqlConnection connection, int timeOut, ExecutionEngineConditions conditions, IBatchEventsHandler batchEventHandlers, int startingLine, IDictionary <string, string> variables) : this(script, (IDbConnection)connection, timeOut, conditions, batchEventHandlers, startingLine, variables) { // nothing }
/// <summary> /// Resets the script's related fields /// </summary> /// <remarks> /// Once the execution thread is nulled, all handles will be closed and GC will collect it /// </remarks> private void ResetScript() { lock (stateSyncLock) { executionState = ExecutionState.Initial; } ConfigurePrePostConditionBatches(preConditionBatches); ConfigurePrePostConditionBatches(postConditionBatches); currentBatchIndex = -1; conditions = null; batchEventHandlers = null; }
/// <summary> /// Parses the script locally /// </summary> /// <param name="script">script to parse</param> /// <param name="batchEventsHandler">batch handler</param> /// <param name="conditions">execution engine conditions if specified</param> /// <remarks> /// The batch parser functionality is used in this case /// </remarks> public void ParseScript(string script, IBatchEventsHandler batchEventsHandler, ExecutionEngineConditions conditions = null) { Validate.IsNotNull(nameof(script), script); Validate.IsNotNull(nameof(batchEventsHandler), batchEventsHandler); if (conditions != null) { this.conditions = conditions; } this.script = script; batchEventHandlers = batchEventsHandler; isLocalParse = true; DoExecute(/* isBatchParser */ true); }
/// <summary> /// Setups the script execution /// </summary> /// <param name="scriptExecutionArgs"></param> private void ExecuteInternal(ScriptExecutionArgs scriptExecutionArgs, bool isBatchParser) { Validate.IsNotNull(nameof(scriptExecutionArgs), scriptExecutionArgs); Validate.IsNotNullOrEmptyString(nameof(scriptExecutionArgs.Script), scriptExecutionArgs.Script); Validate.IsNotNull(nameof(scriptExecutionArgs.ReliableConnection), scriptExecutionArgs.ReliableConnection); Validate.IsNotNull(nameof(scriptExecutionArgs.Conditions), scriptExecutionArgs.Conditions); Validate.IsNotNull(nameof(scriptExecutionArgs.BatchEventHandlers), scriptExecutionArgs.BatchEventHandlers); Debug.Assert(scriptExecutionArgs.TimeOut >= 0); executionTimeout = scriptExecutionArgs.TimeOut < 0 ? 0 : scriptExecutionArgs.TimeOut; connection = scriptExecutionArgs.ReliableConnection; conditions = new ExecutionEngineConditions(scriptExecutionArgs.Conditions); script = scriptExecutionArgs.Script; isSqlCmdConnection = false; batchEventHandlers = scriptExecutionArgs.BatchEventHandlers; startingLine = scriptExecutionArgs.StartingLine; internalVariables = scriptExecutionArgs.Variables; DoExecute(isBatchParser); }
/// <summary> /// Constructor method for ScriptExecutionArgs /// </summary> public ScriptExecutionArgs( string script, IDbConnection connection, int timeOut, ExecutionEngineConditions conditions, IBatchEventsHandler batchEventHandlers, int startingLine, IDictionary <string, string> variables) { Script = script; this.connection = connection; TimeOut = timeOut; Conditions = conditions; this.batchEventHandlers = batchEventHandlers; this.startingLine = startingLine; if (variables != null) { foreach (var variable in variables) { Variables[variable.Key] = variable.Value; } } }
/// <summary> /// Overloaded constructor taking another ExecutionEngineCondition object as a reference /// </summary> public ExecutionEngineConditions(ExecutionEngineConditions condition) { state = condition.state; batchSeparator = condition.batchSeparator; }
/// <summary> /// Create a set of batches to be executed before and after the script is executed /// </summary> /// <remarks> /// This is the way some server side settings can be set. Additionally, it supports /// a way to wrap the script execution within a transaction block /// </remarks> private void CreatePrePostConditionBatches() { StringBuilder scriptPreBatches = new StringBuilder(); StringBuilder scriptPostBatches = new StringBuilder(); int serverVersion = 8; if (connection != null && connection.State == ConnectionState.Open) { serverVersion = new Version(ReliableConnectionHelper.ReadServerVersion(connection)).Major; } ConfigurePrePostConditionBatches(preConditionBatches); ConfigurePrePostConditionBatches(postConditionBatches); if (conditions.IsNoExec) { scriptPreBatches.AppendFormat(CultureInfo.InvariantCulture, "{0} ", ExecutionEngineConditions.NoExecStatement(false)); } if (conditions.IsStatisticsIO) { scriptPreBatches.AppendFormat(CultureInfo.InvariantCulture, "{0} ", ExecutionEngineConditions.StatisticsIOStatement(true)); scriptPostBatches.AppendFormat(CultureInfo.InvariantCulture, "{0} ", ExecutionEngineConditions.StatisticsIOStatement(false)); } if (conditions.IsStatisticsTime) { scriptPreBatches.AppendFormat(CultureInfo.InvariantCulture, "{0} ", ExecutionEngineConditions.StatisticsTimeStatement(true)); scriptPostBatches.AppendFormat(CultureInfo.InvariantCulture, "{0} ", ExecutionEngineConditions.StatisticsTimeStatement(false)); } if (conditions.IsEstimatedShowPlan) { if (serverVersion >= 9) { scriptPreBatches.AppendFormat(CultureInfo.InvariantCulture, "{0} ", ExecutionEngineConditions.ShowPlanXmlStatement(true)); scriptPostBatches.AppendFormat(CultureInfo.InvariantCulture, "{0} ", ExecutionEngineConditions.ShowPlanXmlStatement(false)); expectedShowPlan = ShowPlanType.EstimatedXmlShowPlan; } else { scriptPreBatches.AppendFormat(CultureInfo.InvariantCulture, "{0} ", ExecutionEngineConditions.ShowPlanAllStatement(true)); scriptPostBatches.AppendFormat(CultureInfo.InvariantCulture, "{0} ", ExecutionEngineConditions.ShowPlanAllStatement(false)); expectedShowPlan = ShowPlanType.EstimatedExecutionShowPlan; } } else if (conditions.IsActualShowPlan) { if (serverVersion >= 9) { scriptPreBatches.AppendFormat(CultureInfo.InvariantCulture, "{0} ", ExecutionEngineConditions.StatisticsXmlStatement(true)); scriptPostBatches.AppendFormat(CultureInfo.InvariantCulture, "{0} ", ExecutionEngineConditions.StatisticsXmlStatement(false)); expectedShowPlan = ShowPlanType.ActualXmlShowPlan; } else { scriptPreBatches.AppendFormat(CultureInfo.InvariantCulture, "{0} ", ExecutionEngineConditions.StatisticsProfileStatement(true)); scriptPostBatches.AppendFormat(CultureInfo.InvariantCulture, "{0} ", ExecutionEngineConditions.StatisticsProfileStatement(false)); expectedShowPlan = ShowPlanType.ActualExecutionShowPlan; } } if (conditions.IsTransactionWrapped) { scriptPreBatches.AppendFormat(CultureInfo.InvariantCulture, "{0} ", ExecutionEngineConditions.BeginTransactionStatement); // issuing a Rollback or a Commit will depend on the script execution result } if (conditions.IsParseOnly) { scriptPreBatches.AppendFormat(CultureInfo.InvariantCulture, "{0} ", ExecutionEngineConditions.ParseOnlyStatement(true)); scriptPostBatches.AppendFormat(CultureInfo.InvariantCulture, "{0} ", ExecutionEngineConditions.ParseOnlyStatement(false)); } if (conditions.IsNoExec) { scriptPreBatches.AppendFormat(CultureInfo.InvariantCulture, "{0} ", ExecutionEngineConditions.NoExecStatement(true)); } if (conditions.IsShowPlanText && !conditions.IsEstimatedShowPlan && !conditions.IsActualShowPlan) { // SET SHOWPLAN_TEXT cannot be used with other statements in the batch preConditionBatches.Insert(0, new Batch( string.Format(CultureInfo.CurrentCulture, "{0} ", ExecutionEngineConditions.ShowPlanTextStatement(true)), false, executionTimeout)); postConditionBatches.Insert(0, new Batch( string.Format(CultureInfo.CurrentCulture, "{0} ", ExecutionEngineConditions.ShowPlanTextStatement(false)), false, executionTimeout)); } string preBatches = scriptPreBatches.ToString().Trim(); string postBatches = scriptPostBatches.ToString().Trim(); if (scriptPreBatches.Length > 0) { preConditionBatches.Add(new Batch(preBatches, false, executionTimeout)); } if (scriptPostBatches.Length > 0) { postConditionBatches.Add(new Batch(postBatches, false, executionTimeout)); } }