Summary description for PreparedStatement.
Inheritance: Statement
Ejemplo n.º 1
0
        /// <include file='docs/mysqlcommand.xml' path='docs/Prepare2/*'/>
        private void Prepare(int cursorPageSize)
        {
            if (!connection.driver.Version.isAtLeast(5, 0, 0) && cursorPageSize > 0)
            {
                throw new InvalidOperationException("Nested commands are only supported on MySQL 5.0 and later");
            }

            // if the length of the command text is zero, then just return
            string psSQL = CommandText;

            if (psSQL == null ||
                psSQL.Trim().Length == 0)
            {
                return;
            }

            if (CommandType == CommandType.StoredProcedure)
            {
                statement = new StoredProcedure(this, CommandText);
            }
            else
            {
                statement = new PreparableStatement(this, CommandText);
            }

            statement.Prepare();
        }
Ejemplo n.º 2
0
        /// <include file='docs/mysqlcommand.xml' path='docs/Prepare2/*'/>
        private void Prepare(int cursorPageSize)
        {
            using (new CommandTimer(Connection, CommandTimeout))
            {
                // if the length of the command text is zero, then just return
                string psSQL = CommandText;
                if (psSQL == null ||
                    psSQL.Trim().Length == 0)
                {
                    return;
                }

                if (CommandType == CommandType.StoredProcedure)
                {
                    statement = new StoredProcedure(this, CommandText);
                }
                else
                {
                    statement = new PreparableStatement(this, CommandText);
                }

                statement.Resolve(true);
                statement.Prepare();
            }
        }
Ejemplo n.º 3
0
 /*
  * Because the user should not be able to directly create a
  * DataReader object, the constructors are
  * marked as internal.
  */
 internal MySqlDataReader(MySqlCommand cmd, PreparableStatement statement, CommandBehavior behavior)
 {
     this.command = cmd;
     connection = (MySqlConnection)command.Connection;
     commandBehavior = behavior;
     driver = connection.driver;
     affectedRows = -1;
     this.statement = statement;
 }
Ejemplo n.º 4
0
 /*
  * Because the user should not be able to directly create a
  * DataReader object, the constructors are
  * marked as internal.
  */
 internal MySqlDataReader(MySqlCommand cmd, PreparableStatement statement, CommandBehavior behavior)
 {
     command         = cmd;
     connection      = command.Connection;
     commandBehavior = behavior;
     driver          = connection.driver;
     affectedRows    = -1;
     this.statement  = statement;
     nextResultDone  = false;
 }
Ejemplo n.º 5
0
 /*
  * Because the user should not be able to directly create a
  * DataReader object, the constructors are
  * marked as internal.
  */
 internal MySqlDataReader(MySqlCommand cmd, PreparableStatement statement, CommandBehavior behavior)
 {
     this.command    = cmd;
     connection      = (MySqlConnection)command.Connection;
     commandBehavior = behavior;
     driver          = connection.driver;
     affectedRows    = -1;
     this.statement  = statement;
     nextResultDone  = false;
     fieldHashCS     = new Hashtable();
     fieldHashCI     = new Hashtable(StringComparer.InvariantCultureIgnoreCase);
 }
Ejemplo n.º 6
0
		/*
		 * Because the user should not be able to directly create a 
		 * DataReader object, the constructors are
		 * marked as internal.
		 */
		internal MySqlDataReader(MySqlCommand cmd, PreparableStatement statement, CommandBehavior behavior)
		{
			this.command = cmd;
			connection = (MySqlConnection)command.Connection;
			commandBehavior = behavior;
			driver = connection.driver;
			affectedRows = -1;
			this.statement = statement;
			nextResultDone = false;
			fieldHashCS = new Hashtable();
			fieldHashCI = new Hashtable(StringComparer.InvariantCultureIgnoreCase);
		}
Ejemplo n.º 7
0
 internal MySqlDataReader(MySqlCommand cmd, PreparableStatement statement, CommandBehavior behavior)
 {
     this.command         = cmd;
     this.connection      = this.command.Connection;
     this.commandBehavior = behavior;
     this.driver          = this.connection.driver;
     this.affectedRows    = -1L;
     this.statement       = statement;
     if (cmd.CommandType == CommandType.StoredProcedure && cmd.UpdatedRowSource == UpdateRowSource.FirstReturnedRecord)
     {
         this.disableZeroAffectedRows = true;
     }
 }
Ejemplo n.º 8
0
    /*
     * Because the user should not be able to directly create a 
     * DataReader object, the constructors are
     * marked as internal.
     */
    internal MySqlDataReader(MySqlCommand cmd, PreparableStatement statement, CommandBehavior behavior)
    {
      this.command = cmd;
      connection = (MySqlConnection)command.Connection;
      commandBehavior = behavior;
      driver = connection.driver;
      affectedRows = -1;
      this.statement = statement;

      if (cmd.CommandType == CommandType.StoredProcedure &&
      cmd.UpdatedRowSource == UpdateRowSource.FirstReturnedRecord)
      {
        disableZeroAffectedRows = true;
      }
    }
Ejemplo n.º 9
0
        /*
         * Because the user should not be able to directly create a
         * DataReader object, the constructors are
         * marked as internal.
         */
        internal MySqlDataReader(MySqlCommand cmd, PreparableStatement statement, CommandBehavior behavior)
        {
            this.command    = cmd;
            connection      = (MySqlConnection)command.Connection;
            commandBehavior = behavior;
            driver          = connection.driver;
            affectedRows    = -1;
            this.statement  = statement;

#if !RT && !NETSTANDARD1_3
            if (cmd.CommandType == CommandType.StoredProcedure &&
                cmd.UpdatedRowSource == UpdateRowSource.FirstReturnedRecord
                )
            {
                disableZeroAffectedRows = true;
            }
#endif
        }
Ejemplo n.º 10
0
 private void Prepare(int cursorPageSize)
 {
     using (new CommandTimer(this.Connection, this.CommandTimeout))
     {
         string commandText = this.CommandText;
         if (commandText != null && commandText.Trim().Length != 0)
         {
             if (this.CommandType == CommandType.StoredProcedure)
             {
                 this.statement = new StoredProcedure(this, this.CommandText);
             }
             else
             {
                 this.statement = new PreparableStatement(this, this.CommandText);
             }
             this.statement.Resolve(true);
             this.statement.Prepare();
         }
     }
 }
Ejemplo n.º 11
0
		/// <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(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(Resources.Timeout);
                    return null;
                }
                if (ex.IsFatal)
                    Connection.Close();
                if (ex.Number == 0)
                    throw new MySqlException(Resources.FatalErrorDuringExecute, ex);
                throw;
            }
            finally
            {
                if (timer != null)
                    timer.Dispose();
            }
		}
Ejemplo n.º 12
0
        public new MySqlDataReader ExecuteReader(CommandBehavior behavior)
        {
            MySqlDataReader result = null;

            if (this.connection != null && this.connection.commandInterceptor != null && this.connection.commandInterceptor.ExecuteReader(this.CommandText, behavior, ref result))
            {
                return(result);
            }
            bool flag = false;

            this.CheckState();
            Driver driver = this.connection.driver;

            this.cmdText = this.cmdText.Trim();
            if (string.IsNullOrEmpty(this.cmdText))
            {
                this.Throw(new InvalidOperationException(Resources.CommandTextNotInitialized));
            }
            string text = this.cmdText.Trim(new char[]
            {
                ';'
            });

            if (this.connection.hasBeenOpen && !driver.HasStatus(ServerStatusFlags.InTransaction))
            {
                ReplicationManager.GetNewConnection(this.connection.Settings.Server, !this.IsReadOnlyCommand(text), this.connection);
            }
            Driver          obj = driver;
            MySqlDataReader result2;

            lock (obj)
            {
                if (this.connection.Reader != null)
                {
                    this.Throw(new MySqlException(Resources.DataReaderOpen));
                }
                Transaction current = System.Transactions.Transaction.Current;
                if (current != null)
                {
                    bool flag3 = false;
                    if (driver.CurrentTransaction != null)
                    {
                        flag3 = driver.CurrentTransaction.InRollback;
                    }
                    if (!flag3)
                    {
                        TransactionStatus transactionStatus = TransactionStatus.InDoubt;
                        try
                        {
                            transactionStatus = current.TransactionInformation.Status;
                        }
                        catch (TransactionException)
                        {
                        }
                        if (transactionStatus == TransactionStatus.Aborted)
                        {
                            this.Throw(new TransactionAbortedException());
                        }
                    }
                }
                this.commandTimer   = new CommandTimer(this.connection, this.CommandTimeout);
                this.lastInsertedId = -1L;
                if (this.CommandType == CommandType.TableDirect)
                {
                    text = "SELECT * FROM " + text;
                }
                else if (this.CommandType == CommandType.Text && text.IndexOf(" ") == -1 && this.AddCallStatement(text))
                {
                    text = "call " + text;
                }
                if (this.connection.Settings.Replication && !this.InternallyCreated)
                {
                    this.EnsureCommandIsReadOnly(text);
                }
                if (this.statement == null || !this.statement.IsPrepared)
                {
                    if (this.CommandType == CommandType.StoredProcedure)
                    {
                        this.statement = new StoredProcedure(this, text);
                    }
                    else
                    {
                        this.statement = new PreparableStatement(this, text);
                    }
                }
                this.statement.Resolve(false);
                this.HandleCommandBehaviors(behavior);
                this.updatedRowCount = -1L;
                try
                {
                    MySqlDataReader mySqlDataReader = new MySqlDataReader(this, this.statement, behavior);
                    this.connection.Reader = mySqlDataReader;
                    this.canceled          = false;
                    this.statement.Execute();
                    mySqlDataReader.NextResult();
                    flag    = true;
                    result2 = mySqlDataReader;
                }
                catch (TimeoutException ex)
                {
                    this.connection.HandleTimeoutOrThreadAbort(ex);
                    throw;
                }
                catch (ThreadAbortException ex2)
                {
                    this.connection.HandleTimeoutOrThreadAbort(ex2);
                    throw;
                }
                catch (IOException ex3)
                {
                    this.connection.Abort();
                    throw new MySqlException(Resources.FatalErrorDuringExecute, ex3);
                }
                catch (MySqlException ex4)
                {
                    if (ex4.InnerException is TimeoutException)
                    {
                        throw;
                    }
                    try
                    {
                        this.ResetReader();
                        this.ResetSqlSelectLimit();
                    }
                    catch (Exception)
                    {
                        this.Connection.Abort();
                        throw new MySqlException(ex4.Message, true, ex4);
                    }
                    if (ex4.IsQueryAborted)
                    {
                        result2 = null;
                    }
                    else
                    {
                        if (ex4.IsFatal)
                        {
                            this.Connection.Close();
                        }
                        if (ex4.Number == 0)
                        {
                            throw new MySqlException(Resources.FatalErrorDuringExecute, ex4);
                        }
                        throw;
                    }
                }
                finally
                {
                    if (this.connection != null)
                    {
                        if (this.connection.Reader == null)
                        {
                            this.ClearCommandTimer();
                        }
                        if (!flag)
                        {
                            this.ResetReader();
                        }
                    }
                }
            }
            return(result2);
        }
Ejemplo n.º 13
0
        /// <include file='docs/mysqlcommand.xml' path='docs/Prepare2/*'/>
        private void Prepare(int cursorPageSize)
        {
            if (!connection.driver.Version.isAtLeast(5, 0, 0) && cursorPageSize > 0)
                throw new InvalidOperationException("Nested commands are only supported on MySQL 5.0 and later");

            using (new CommandTimer(Connection, CommandTimeout))
            {
                // if the length of the command text is zero, then just return
                string psSQL = CommandText;
                if (psSQL == null ||
                     psSQL.Trim().Length == 0)
                    return;

                if (CommandType == CommandType.StoredProcedure)
                    statement = new StoredProcedure(this, CommandText);
                else
                    statement = new PreparableStatement(this, CommandText);

                statement.Resolve(true);
                statement.Prepare();
            }
        }
Ejemplo n.º 14
0
        /// <include file='docs/mysqlcommand.xml' path='docs/ExecuteReader1/*'/>
        public new MySqlDataReader ExecuteReader (CommandBehavior behavior)
        {

            CheckState();
            Driver driver = connection.driver;
            lock (driver)
            {

            // We have to recheck that there is no reader, after we got the lock
            if (connection.Reader != null)
            {
               throw new  MySqlException(Resources.DataReaderOpen);
            }
#if !CF
            System.Transactions.Transaction curTrans = System.Transactions.Transaction.Current;

            if (curTrans != null)
            {
                TransactionStatus status = 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(TransactionException)
                {
                }
                if (status == TransactionStatus.Aborted)
                    throw new TransactionAbortedException();
            }
#endif
            commandTimer = new CommandTimer(connection, CommandTimeout);

            lastInsertedId = -1;
            if (cmdText == null ||
                 cmdText.Trim().Length == 0)
                throw new InvalidOperationException(Resources.CommandTextNotInitialized);

			string sql = TrimSemicolons(cmdText);

            if (CommandType == CommandType.TableDirect)
                sql = "SELECT * FROM " + sql;

            // now we check to see if we are executing a query that is buggy 
            // in 4.1 
            connection.driver.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.ToUpper(CultureInfo.InvariantCulture);
                connection.driver.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(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;
                // execute the statement
                statement.Execute();
                // wait for data to return
                reader.NextResult();
                return reader;
            }
            catch (TimeoutException tex)
            {
                connection.HandleTimeout(tex);
                return null;
            }
            catch (MySqlException ex)
            {
                connection.Reader = null;
                if (ex.InnerException is TimeoutException)
                    throw ex; // already handled

                try
                {
                    ResetSqlSelectLimit();
                }
                catch (Exception ex2)
                {
                    // 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.Number == 1317)
                    return null;

                if (ex.IsFatal)
                    Connection.Close();
                if (ex.Number == 0)
                    throw new MySqlException(Resources.FatalErrorDuringExecute, ex);
                throw;
            }
            finally
            {
                if (connection != null && connection.Reader == null)
                {
                    // Comething want seriously wrong,  and reader would not be 
                    // able to clear timeout on closing.
                    // So we clear timeout here.
                    ClearCommandTimer();
                }
            }
        }
        }
Ejemplo n.º 15
0
        /// <include file='docs/mysqlcommand.xml' path='docs/ExecuteReader1/*'/>
        public new MySqlDataReader ExecuteReader(CommandBehavior behavior)
        {
            bool success = false;

            CheckState();
            Driver driver = connection.driver;

            lock (driver)
            {
                // We have to recheck that there is no reader, after we got the lock
                if (connection.Reader != null)
                {
                    throw new  MySqlException(Resources.DataReaderOpen);
                }
#if !CF
                System.Transactions.Transaction curTrans = System.Transactions.Transaction.Current;

                if (curTrans != null)
                {
                    bool inRollback = false;
                    if (driver.CurrentTransaction != null)
                    {
                        inRollback = driver.CurrentTransaction.InRollback;
                    }
                    if (!inRollback)
                    {
                        TransactionStatus status = 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 (TransactionException)
                        {
                        }
                        if (status == TransactionStatus.Aborted)
                        {
                            throw new TransactionAbortedException();
                        }
                    }
                }
#endif
                commandTimer = new CommandTimer(connection, CommandTimeout);

                lastInsertedId = -1;
                if (cmdText == null ||
                    cmdText.Trim().Length == 0)
                {
                    throw new InvalidOperationException(Resources.CommandTextNotInitialized);
                }

                string sql = TrimSemicolons(cmdText);

                if (CommandType == CommandType.TableDirect)
                {
                    sql = "SELECT * FROM " + 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;
                    // 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(Resources.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 (ex.IsFatal)
                    {
                        Connection.Close();
                    }
                    if (ex.Number == 0)
                    {
                        throw new MySqlException(Resources.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();
                        }
                    }
                }
            }
        }
Ejemplo n.º 16
0
        /// <include file='docs/mysqlcommand.xml' path='docs/ExecuteReader1/*'/>
        public new MySqlDataReader ExecuteReader(CommandBehavior behavior)
        {
            // interceptors didn't handle this so we fall through
            bool success = false;

            CheckState();
            Driver driver = connection.driver;

            cmdText = cmdText.Trim();


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



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


                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("Resources.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("Resources.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();
                        }
                    }
                }
            }
        }
Ejemplo n.º 17
0
    /// <include file='docs/mysqlcommand.xml' path='docs/ExecuteReader1/*'/>
    public new MySqlDataReader ExecuteReader(CommandBehavior behavior)
    {
#if !CF && !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(Resources.CommandTextNotInitialized));

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

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

      lock (driver)
      {

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

#if !CF && !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 && !SingleWordKeywords.Contains(sql.ToUpper()))
          {
            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(Resources.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(Resources.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();
            }
          }
        }
      }
    }
Ejemplo n.º 18
0
        /// <include file='docs/mysqlcommand.xml' path='docs/ExecuteReader1/*'/>
        public new MySqlDataReader ExecuteReader(CommandBehavior behavior)
        {
            // interceptors didn't handle this so we fall through
            bool success = false;
            CheckState();
            Driver driver = connection.driver;

            cmdText = cmdText.Trim();

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

            lock (driver)
            {

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

                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("Resources.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("Resources.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();
                        }
                    }
                }
            }
        }
Ejemplo n.º 19
0
        /// <include file='docs/mysqlcommand.xml' path='docs/ExecuteReader1/*'/>
        private void InnerBeginExecuteReader(CommandBehavior behavior)
        {
            CheckState();
            Driver driver = connection.driver;
            lock (driver)
            {

                // We have to recheck that there is no reader, after we got the lock
                if (connection.Reader != null)
                {
                    throw new MySqlException(Resources.DataReaderOpen);
                }
#if !CF
                System.Transactions.Transaction curTrans = System.Transactions.Transaction.Current;

                if (curTrans != null)
                {
                    bool inRollback = false;
                    if (driver.CurrentTransaction != null)
                        inRollback = driver.CurrentTransaction.InRollback;
                    if (!inRollback)
                    {
                        TransactionStatus status = 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 (TransactionException)
                        {
                        }
                        if (status == TransactionStatus.Aborted)
                            throw new TransactionAbortedException();
                    }
                }
#endif
                commandTimer = new CommandTimer(connection, CommandTimeout);

                lastInsertedId = -1;
                cmdText = cmdText.Trim();
                if (String.IsNullOrEmpty(cmdText))
                    throw new InvalidOperationException(Resources.CommandTextNotInitialized);

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

                if (CommandType == CommandType.TableDirect)
                    sql = "SELECT * FROM " + 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.BeginNextResult();

                    MysqlAsyncResult result = _asyncResult as MysqlAsyncResult;
                    result.DataReader = 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(Resources.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
                    //只有主动调用Cancel时才会出现这个异常,注释让他throw吧
                    //if (ex.IsQueryAborted)
                    //    return null;
                    if (ex.IsFatal)
                        Connection.Close();
                    if (ex.Number == 0)
                        throw new MySqlException(Resources.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();
                        }
                    }
                }
            }
        }
Ejemplo n.º 20
0
        /// <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(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)
            {
                try
                {
                    ResetSqlSelectLimit();
                }
                catch (Exception) { }

                // if we caught an exception because of a cancel, then just return null
                if (ex.Number == 1317)
                {
                    if (TimedOut)
                    {
                        throw new MySqlException(Resources.Timeout);
                    }
                    return(null);
                }
                if (ex.IsFatal)
                {
                    Connection.Close();
                }
                if (ex.Number == 0)
                {
                    throw new MySqlException(Resources.FatalErrorDuringExecute, ex);
                }
                throw;
            }
            finally
            {
                if (timer != null)
                {
                    timer.Dispose();
                }
            }
        }
Ejemplo n.º 21
0
        /// <include file='docs/mysqlcommand.xml' path='docs/ExecuteReader1/*'/>
        public new MySqlDataReader ExecuteReader(CommandBehavior behavior)
        {
            // give our interceptors a shot at it first
            MySqlDataReader interceptedReader = null;

            if (connection?.commandInterceptor != null && connection.commandInterceptor.ExecuteReader(CommandText, behavior, ref interceptedReader))
            {
                return(interceptedReader);
            }

            // 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(Resources.CommandTextNotInitialized));
            }

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

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

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

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

                if (curTrans != null)
                {
                    bool inRollback = false;
                    //TODO: ADD support for 452 and 46X
                    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);

                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
                }
#if !NETSTANDARD1_3
                catch (ThreadAbortException taex)
                {
                    connection.HandleTimeoutOrThreadAbort(taex);
                    throw;
                }
#endif
                catch (IOException ioex)
                {
                    connection.Abort(); // Closes connection without returning it to the pool
                    throw new MySqlException(Resources.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(Resources.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();
                        }
                    }
                }
            }
        }
Ejemplo n.º 22
0
        /// <include file='docs/mysqlcommand.xml' path='docs/ExecuteReader1/*'/>
        private void InnerBeginExecuteReader(CommandBehavior behavior)
        {
            lastInsertedId = -1;
            CheckState();

            if (cmdText == null ||
                 cmdText.Trim().Length == 0)
                throw new InvalidOperationException(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;

            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)
                {
                    ExecuteQueryManager.Instace.Add(this);
                }

                reader.BeginNextResult();

                MysqlAsyncResult result = _asyncResult as MysqlAsyncResult;
                result.DataReader = reader;
            }
            catch (MySqlException ex)
            {
                if (ex.IsFatal)
                    Connection.Close();
                if (ex.Number == 0)
                    throw new MySqlException(Resources.FatalErrorDuringExecute, ex);
                throw;
            }
        }
Ejemplo n.º 23
0
    /// <include file='docs/mysqlcommand.xml' path='docs/Prepare2/*'/>
    private void Prepare(int cursorPageSize)
    {
      using (new CommandTimer(Connection, CommandTimeout))
      {
        // if the length of the command text is zero, then just return
        string psSQL = CommandText;
        if (psSQL == null ||
             psSQL.Trim().Length == 0)
          return;

        if (CommandType == CommandType.StoredProcedure)
          statement = new StoredProcedure(this, CommandText);
        else
          statement = new PreparableStatement(this, CommandText);

        statement.Resolve(true);
        statement.Prepare();
      }
    }
Ejemplo n.º 24
0
        /// <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(Resources.CommandTextNotInitialized);
            }

            string sql = TrimSemicolons(cmdText);

            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;

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

                // start a threading timer on our command timeout
                timedOut = false;
                Timer t = null;
                querySent.Reset();
                if (connection.driver.Version.isAtLeast(5, 0, 0) &&
                    commandTimeout > 0)
                {
                    TimerCallback timerDelegate =
                        new TimerCallback(TimeoutExpired);
                    t = new Timer(timerDelegate, this, this.CommandTimeout * 1000, Timeout.Infinite);
                }

                // execute the statement
                statement.Execute();
                querySent.Set();

                canCancel = true;
                reader.NextResult();
                if (t != null)
                {
                    t.Dispose();
                }
                canCancel         = false;
                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(Resources.Timeout);
                    }
                    return(null);
                }
                throw;
            }
            finally
            {
                querySent.Reset();
                canCancel = false;
            }
        }