/// <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(); }
/// <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(); } }
/* * 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; }
/* * 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; }
/* * 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); }
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; } }
/* * 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; } }
/* * 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 }
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(); } } }
/// <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(); } }
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); }
/// <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(); } }
/// <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(); } } } }
/// <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(); } } } } }
/// <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(); } } } } }
/// <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(); } } } } }
/// <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(); } } } } }
/// <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(); } } } } }
/// <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(); } } }
/// <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(); } } } } }
/// <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; } }
/// <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(); } }
/// <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; } }