コード例 #1
0
ファイル: command.cs プロジェクト: the-alex-mark/proglib-cs
        /// <include file='docs/mysqlcommand.xml' path='docs/ExecuteReader1/*'/>
        public new MySqlDataReader ExecuteReader(CommandBehavior behavior)
        {
#if !RT
            // give our interceptors a shot at it first
            MySqlDataReader interceptedReader = null;
            if (connection != null &&
                connection.commandInterceptor != null &&
                connection.commandInterceptor.ExecuteReader(CommandText, behavior, ref interceptedReader))
            {
                return(interceptedReader);
            }
#endif

            // interceptors didn't handle this so we fall through
            bool success = false;
            CheckState();
            Driver driver = connection.driver;

            cmdText = cmdText.Trim();
            if (String.IsNullOrEmpty(cmdText))
            {
                Throw(new InvalidOperationException(MySqlResources.CommandTextNotInitialized));
            }

            string sql = cmdText.Trim(';');

            // Load balancing getting a new connection
            if (connection.hasBeenOpen && !driver.HasStatus(ServerStatusFlags.InTransaction))
            {
                ReplicationManager.GetNewConnection(connection.Settings.Server, !IsReadOnlyCommand(sql), connection);
            }

            lock (driver)
            {
                // We have to recheck that there is no reader, after we got the lock
                if (connection.Reader != null)
                {
                    Throw(new MySqlException(MySqlResources.DataReaderOpen));
                }

#if !RT
                System.Transactions.Transaction curTrans = System.Transactions.Transaction.Current;

                if (curTrans != null)
                {
                    bool inRollback = false;
                    if (driver.CurrentTransaction != null)
                    {
                        inRollback = driver.CurrentTransaction.InRollback;
                    }
                    if (!inRollback)
                    {
                        System.Transactions.TransactionStatus status = System.Transactions.TransactionStatus.InDoubt;
                        try
                        {
                            // in some cases (during state transitions) this throws
                            // an exception. Ignore exceptions, we're only interested
                            // whether transaction was aborted or not.
                            status = curTrans.TransactionInformation.Status;
                        }
                        catch (System.Transactions.TransactionException)
                        {
                        }
                        if (status == System.Transactions.TransactionStatus.Aborted)
                        {
                            Throw(new System.Transactions.TransactionAbortedException());
                        }
                    }
                }
#endif
                commandTimer = new CommandTimer(connection, CommandTimeout);

                lastInsertedId = -1;

                if (CommandType == CommandType.TableDirect)
                {
                    sql = "SELECT * FROM " + sql;
                }
                else if (CommandType == CommandType.Text)
                {
                    // validates single word statetment (maybe is a stored procedure call)
                    if (sql.IndexOf(" ") == -1)
                    {
                        if (AddCallStatement(sql))
                        {
                            sql = "call " + sql;
                        }
                    }
                }

                // if we are on a replicated connection, we are only allow readonly statements
                if (connection.Settings.Replication && !InternallyCreated)
                {
                    EnsureCommandIsReadOnly(sql);
                }

                if (statement == null || !statement.IsPrepared)
                {
                    if (CommandType == CommandType.StoredProcedure)
                    {
                        statement = new StoredProcedure(this, sql);
                    }
                    else
                    {
                        statement = new PreparableStatement(this, sql);
                    }
                }

                // stored procs are the only statement type that need do anything during resolve
                statement.Resolve(false);

                // Now that we have completed our resolve step, we can handle our
                // command behaviors
                HandleCommandBehaviors(behavior);

                updatedRowCount = -1;
                try
                {
                    MySqlDataReader reader = new MySqlDataReader(this, statement, behavior);
                    connection.Reader = reader;
                    canceled          = false;
                    // execute the statement
                    statement.Execute();
                    // wait for data to return
                    reader.NextResult();
                    success = true;
                    return(reader);
                }
                catch (TimeoutException tex)
                {
                    connection.HandleTimeoutOrThreadAbort(tex);
                    throw; //unreached
                }
                catch (ThreadAbortException taex)
                {
                    connection.HandleTimeoutOrThreadAbort(taex);
                    throw;
                }
                catch (IOException ioex)
                {
                    connection.Abort(); // Closes connection without returning it to the pool
                    throw new MySqlException(MySqlResources.FatalErrorDuringExecute, ioex);
                }
                catch (MySqlException ex)
                {
                    if (ex.InnerException is TimeoutException)
                    {
                        throw; // already handled
                    }
                    try
                    {
                        ResetReader();
                        ResetSqlSelectLimit();
                    }
                    catch (Exception)
                    {
                        // Reset SqlLimit did not work, connection is hosed.
                        Connection.Abort();
                        throw new MySqlException(ex.Message, true, ex);
                    }

                    // if we caught an exception because of a cancel, then just return null
                    if (ex.IsQueryAborted)
                    {
                        return(null);
                    }
                    if (ex.IsFatal)
                    {
                        Connection.Close();
                    }
                    if (ex.Number == 0)
                    {
                        throw new MySqlException(MySqlResources.FatalErrorDuringExecute, ex);
                    }
                    throw;
                }
                finally
                {
                    if (connection != null)
                    {
                        if (connection.Reader == null)
                        {
                            // Something went seriously wrong,  and reader would not
                            // be able to clear timeout on closing.
                            // So we clear timeout here.
                            ClearCommandTimer();
                        }
                        if (!success)
                        {
                            // ExecuteReader failed.Close Reader and set to null to
                            // prevent subsequent errors with DataReaderOpen
                            ResetReader();
                        }
                    }
                }
            }
        }
コード例 #2
0
ファイル: command.cs プロジェクト: tvrjcf/Demo
        /// <include file='docs/mysqlcommand.xml' path='docs/ExecuteReader1/*'/>
        public new MySqlDataReader ExecuteReader(CommandBehavior behavior)
        {
            lastInsertedId = -1;
            CheckState();

            if (cmdText == null ||
                cmdText.Trim().Length == 0)
            {
                throw new InvalidOperationException(System.Data.MySqlClient.Properties.Resources.CommandTextNotInitialized);
            }

            string sql = TrimSemicolons(cmdText);

            // now we check to see if we are executing a query that is buggy
            // in 4.1
            connection.IsExecutingBuggyQuery = false;
            if (!connection.driver.Version.isAtLeast(5, 0, 0) &&
                connection.driver.Version.isAtLeast(4, 1, 0))
            {
                string snippet = sql;
                if (snippet.Length > 17)
                {
                    snippet = sql.Substring(0, 17);
                }
                snippet = snippet.ToLower(CultureInfo.InvariantCulture);
                connection.IsExecutingBuggyQuery =
                    snippet.StartsWith("describe") ||
                    snippet.StartsWith("show table status");
            }

            if (statement == null || !statement.IsPrepared)
            {
                if (CommandType == CommandType.StoredProcedure)
                {
                    statement = new StoredProcedure(this, sql);
                }
                else
                {
                    statement = new PreparableStatement(this, sql);
                }
            }

            // stored procs are the only statement type that need do anything during resolve
            statement.Resolve();

            // Now that we have completed our resolve step, we can handle our
            // command behaviors
            HandleCommandBehaviors(behavior);

            updatedRowCount = -1;

            Timer timer = null;

            try
            {
                MySqlDataReader reader = new MySqlDataReader(this, statement, behavior);

                // start a threading timer on our command timeout
                timedOut = false;
                canceled = false;

                // execute the statement
                statement.Execute();

                // start a timeout timer
                if (connection.driver.Version.isAtLeast(5, 0, 0) &&
                    commandTimeout > 0)
                {
                    TimerCallback timerDelegate =
                        new TimerCallback(TimeoutExpired);
                    timer = new Timer(timerDelegate, this, this.CommandTimeout * 1000, Timeout.Infinite);
                }

                // wait for data to return
                reader.NextResult();

                connection.Reader = reader;
                return(reader);
            }
            catch (MySqlException ex)
            {
                // if we caught an exception because of a cancel, then just return null
                if (ex.Number == 1317)
                {
                    if (TimedOut)
                    {
                        throw new MySqlException(System.Data.MySqlClient.Properties.Resources.Timeout);
                    }
                    return(null);
                }
                if (ex.IsFatal)
                {
                    Connection.Close();
                }
                throw;
            }
            finally
            {
                if (timer != null)
                {
                    timer.Dispose();
                }
            }
        }