/* * 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; } }
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(); } }
public new MySqlDataReader ExecuteReader(CommandBehavior behavior) { // interceptors didn't handle this so we fall through 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)); } 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; 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); 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(); } } } } }