コード例 #1
0
        /// <summary>
        /// Executes the script (on a separated thread)
        /// </summary>
        private void DoExecute(bool isBatchParser)
        {
            //we should not be in the middle of execution here
            if (executionState == ExecutionState.Executing || executionState == ExecutionState.ExecutingBatch)
            {
                throw new InvalidOperationException(SR.EE_ExecutionNotYetCompleteError);
            }

            executionState                = ExecutionState.Initial;
            result                        = ScriptExecutionResult.Failure;
            currentBatchIndex             = 0;
            currentBatch.ExecutionTimeout = executionTimeout;
            expectedShowPlan              = ShowPlanType.None;

            if (!isLocalParse)
            {
                errorAction = conditions.IsHaltOnError ?
                              OnErrorAction.Exit :
                              OnErrorAction.Ignore;

                CreatePrePostConditionBatches();
            }

            ConfigureBatchEventHandlers(currentBatch, batchEventHandlers, true);

            // do we have a cancel request already?
            lock (stateSyncLock)
            {
                if (executionState == ExecutionState.Cancelling)
                {
                    RaiseScriptExecutionFinished(ScriptExecutionResult.Cancel);
                    return;
                }
                Debug.Assert(executionState == ExecutionState.Initial);
                executionState = ExecutionState.Executing;
            }

            if ((result = ExecutePrePostConditionBatches(preConditionBatches)) == ScriptExecutionResult.Success)
            {
                DoScriptExecution(isBatchParser);
            }

            if (!CheckForDiscardedConnection())
            {
                if (!isLocalParse)
                {
                    if (conditions.IsTransactionWrapped && !conditions.IsParseOnly)
                    {
                        if (result == ScriptExecutionResult.Success)
                        {
                            postConditionBatches.Add(new Batch(ExecutionEngineConditions.CommitTransactionStatement, false, executionTimeout));
                        }
                        else
                        {
                            postConditionBatches.Add(new Batch(ExecutionEngineConditions.RollbackTransactionStatement, false, executionTimeout));
                        }
                    }

                    // no need to update the result value as it has been updated by the DoScriptExecution()
                    ExecutePrePostConditionBatches(postConditionBatches);
                }

                //fire an event that we're done with execution of all batches
                if (result == ScriptExecutionResult.Halted) //remap into failure
                {
                    result = ScriptExecutionResult.Failure;
                }

                RaiseScriptExecutionFinished(result);
            }
        }
コード例 #2
0
        private ScriptExecutionResult DoBatchExecution(Batch batch)
        {
            Validate.IsNotNull(nameof(batch), batch);

            ScriptExecutionResult result = ScriptExecutionResult.Success;

            // TODO, fawinter: Do I need to keep this batch?
            if (batch.HasValidText)
            {
                try
                {
                    // Parsing mode we execute only once
                    if (conditions.IsParseOnly)
                    {
                        numBatchExecutionTimes = 1;
                    }

                    int timesLoop = numBatchExecutionTimes;
                    if (numBatchExecutionTimes > 1)
                    {
                        RaiseBatchMessage(String.Format(CultureInfo.CurrentCulture, SR.EE_ExecutionInfo_InitilizingLoop, numBatchExecutionTimes));
                    }

                    while (timesLoop > 0 && result != ScriptExecutionResult.Cancel && result != ScriptExecutionResult.Halted)
                    {
                        result = batch.Execute(connection, expectedShowPlan);

                        Debug.Assert(connection != null);
                        if (connection == null || connection.State != ConnectionState.Open)
                        {
                            result = ScriptExecutionResult.Halted;
                        }

                        if (result == ScriptExecutionResult.Failure)
                        {
                            if (errorAction == OnErrorAction.Ignore)
                            {
                                if (numBatchExecutionTimes > 1)
                                {
                                    RaiseBatchMessage(SR.EE_BatchExecutionError_Ignoring);
                                }
                            }
                            else
                            {
                                RaiseBatchMessage(SR.EE_BatchExecutionError_Halting);
                                result = ScriptExecutionResult.Halted;
                            }
                        }

                        timesLoop--;
                    }


                    if (result == ScriptExecutionResult.Cancel)
                    {
                        RaiseBatchMessage(String.Format(CultureInfo.CurrentCulture, SR.EE_ExecutionInfo_QueryCancelledbyUser));
                    }
                    else
                    {
                        if (numBatchExecutionTimes > 1)
                        {
                            RaiseBatchMessage(String.Format(CultureInfo.CurrentCulture, SR.EE_ExecutionInfo_FinalizingLoop, numBatchExecutionTimes));
                        }
                    }
                }
                catch (OutOfMemoryException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    // if anything goes wrong it will shutdown VS
                    Logger.Write(LogLevel.Error, "Exception Caught in ExecutionEngine.DoBatchExecution(Batch) :" + ex.ToString());
                    result = ScriptExecutionResult.Failure;
                }
            }
            else
            {
                // TODO, fawinter: Success will be returned on an Empty text batch
            }

            return(result);
        }
コード例 #3
0
        /// <summary>
        /// Executes the batch text given the text span
        /// </summary>
        /// <param name="batchScript"></param>
        /// <param name="textSpan"></param>
        /// <param name="continueProcessing"></param>
        private void ExecuteBatchTextSpanInternal(string batchScript, TextSpan textSpan, out bool continueProcessing)
        {
            Debug.Assert(!String.IsNullOrEmpty(batchScript));
            continueProcessing = true;

            if (batchScript.Trim().Length <= 0)
            {
                result |= ScriptExecutionResult.Success;
                return;
            }

            Debug.Assert(currentBatch != null);

            if (executionState == ExecutionState.Cancelling)
            {
                result = ScriptExecutionResult.Cancel;
            }
            else
            {
                currentBatch.Reset();
                currentBatch.Text       = batchScript;
                currentBatch.TextSpan   = textSpan;
                currentBatch.BatchIndex = currentBatchIndex;

                currentBatchIndex++;

                if (conditions != null)
                {
                    currentBatch.IsSuppressProviderMessageHeaders = conditions.IsSuppressProviderMessageHeaders;

                    // TODO this is associated with Dacfx specific situations, so uncomment if need be
                    //currentBatch.IsScriptExecutionTracked = conditions.IsScriptExecutionTracked;
                    if (conditions.IsScriptExecutionTracked)
                    {
                        currentBatch.ScriptTrackingId = scriptTrackingId++;
                    }
                }

                //ExecutingBatch state means currentBatch is valid to use from another thread to Cancel
                executionState = ExecutionState.ExecutingBatch;
            }

            ScriptExecutionResult batchResult = ScriptExecutionResult.Failure;

            if (result != ScriptExecutionResult.Cancel)
            {
                bool isExecutionDiscarded = false;
                try
                {
                    RaiseBatchParserExecutionStarted(currentBatch, textSpan);

                    if (!isLocalParse)
                    {
                        batchResult = DoBatchExecution(currentBatch);
                    }
                    else
                    {
                        batchResult = ScriptExecutionResult.Success;
                    }
                }
                finally
                {
                    isExecutionDiscarded = (executionState == ExecutionState.Discarded);
                    if (executionState == ExecutionState.Cancelling || isExecutionDiscarded)
                    {
                        batchResult = ScriptExecutionResult.Cancel;
                    }
                    else
                    {
                        executionState = ExecutionState.Executing;
                    }
                }

                if (!isExecutionDiscarded)
                {
                    RaiseBatchParserExecutionFinished(currentBatch, batchResult);
                }
            }
            else
            {
                batchResult = ScriptExecutionResult.Cancel;
            }

            //if we're in Cancel or Halt state, do some special actions
            if (batchResult == ScriptExecutionResult.Cancel || batchResult == ScriptExecutionResult.Halted)
            {
                result             = batchResult;
                continueProcessing = false;
                return;
            }
            else
            {
                result |= batchResult;
            }
        }
コード例 #4
0
ファイル: Batch.cs プロジェクト: mattmasson/sqltoolsservice
        private ScriptExecutionResult CheckStateAndRead(IDataReader reader = null)
        {
            ScriptExecutionResult result = ScriptExecutionResult.Success;

            if (!isResultExpected)
            {
                lock (this)
                {
                    if (state == BatchState.Cancelling)
                    {
                        result = ScriptExecutionResult.Cancel;
                    }
                    else
                    {
                        result = ScriptExecutionResult.Success;
                        state  = BatchState.Executed;
                    }
                }
            }
            else
            {
                lock (this)
                {
                    if (state == BatchState.Cancelling)
                    {
                        result = ScriptExecutionResult.Cancel;
                    }
                    else
                    {
                        state = BatchState.ProcessingResults;
                    }
                }

                if (result != ScriptExecutionResult.Cancel)
                {
                    ScriptExecutionResult batchExecutionResult = ScriptExecutionResult.Success;

                    if (reader != null)
                    {
                        bool hasNextResult = false;
                        do
                        {
                            // if there were no results coming from the server, then the FieldCount is 0
                            if (reader.FieldCount <= 0)
                            {
                                hasNextResult = reader.NextResult();
                                continue;
                            }

                            batchExecutionResult = ProcessResultSet(reader);

                            if (batchExecutionResult != ScriptExecutionResult.Success)
                            {
                                result = batchExecutionResult;
                                break;
                            }

                            RaiseBatchResultSetFinished();

                            hasNextResult = reader.NextResult();
                        } while (hasNextResult);
                    }

                    if (hasErrors)
                    {
                        Debug.WriteLine("DoBatchExecution: successfull processed result set, but there were errors shown to the user");
                        result = ScriptExecutionResult.Failure;
                    }

                    if (result != ScriptExecutionResult.Cancel)
                    {
                        lock (this)
                        {
                            state = BatchState.Executed;
                        }
                    }
                }
            }

            if (reader != null)
            {
                try
                {
                    // reader.Close() doesn't actually close the reader
                    // so explicitly dispose the reader
                    reader.Dispose();
                    reader = null;
                }
                catch (OutOfMemoryException)
                {
                    throw;
                }
                catch (SqlException)
                {
                    // nothing
                }
            }

            return(result);
        }
コード例 #5
0
ファイル: Batch.cs プロジェクト: mattmasson/sqltoolsservice
        private ScriptExecutionResult DoBatchExecutionImpl(IDbConnection connection, string script)
        {
            Validate.IsNotNull(nameof(connection), connection);

            lock (this)
            {
                if (state == BatchState.Cancelling)
                {
                    state = BatchState.Initial;
                    return(ScriptExecutionResult.Cancel);
                }
            }

            ScriptExecutionResult result = ScriptExecutionResult.Success;

            // SqlClient event handlers setup
            SqlInfoMessageEventHandler     messageHandler            = new SqlInfoMessageEventHandler(OnSqlInfoMessageCallback);
            StatementCompletedEventHandler statementCompletedHandler = null;

            DbConnectionWrapper connectionWrapper = new DbConnectionWrapper(connection);

            connectionWrapper.InfoMessage += messageHandler;

            IDbCommand command = connection.CreateCommand();

            command.CommandText    = script;
            command.CommandTimeout = execTimeout;

            DbCommandWrapper commandWrapper = null;

            if (isScriptExecutionTracked && DbCommandWrapper.IsSupportedCommand(command))
            {
                statementCompletedHandler          = new StatementCompletedEventHandler(OnStatementExecutionFinished);
                commandWrapper                     = new DbCommandWrapper(command);
                commandWrapper.StatementCompleted += statementCompletedHandler;
            }

            lock (this)
            {
                state        = BatchState.Executing;
                this.command = command;
                command      = null;
            }

            try
            {
                result = this.ExecuteCommand();
            }
            catch (OutOfMemoryException)
            {
                throw;
            }
            catch (SqlException sqlEx)
            {
                result = HandleSqlException(sqlEx);
            }
            catch (Exception ex)
            {
                result = ScriptExecutionResult.Failure;
                HandleExceptionMessage(ex);
            }
            finally
            {
                if (messageHandler == null)
                {
                    Logger.Write(LogLevel.Error, "Expected handler to be declared");
                }

                if (null != connectionWrapper)
                {
                    connectionWrapper.InfoMessage -= messageHandler;
                }

                if (commandWrapper != null)
                {
                    if (statementCompletedHandler == null)
                    {
                        Logger.Write(LogLevel.Error, "Expect handler to be declared if we have a command wrapper");
                    }
                    commandWrapper.StatementCompleted -= statementCompletedHandler;
                }

                lock (this)
                {
                    state = BatchState.Initial;
                    if (command != null)
                    {
                        command.Dispose();
                        command = null;
                    }
                }
            }

            return(result);
        }
コード例 #6
0
 /// <summary>
 /// Called when parser is about to halt the execution
 /// </summary>
 private void OnHaltParser()
 {
     result = ScriptExecutionResult.Halted;
 }
コード例 #7
0
 // Capture the event once batch finish execution.
 private void OnBatchParserExecutionFinished(object sender, BatchParserExecutionFinishedEventArgs e)
 {
     executionResult = e.ExecutionResult;
 }