Exemple #1
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;
			this.nextResultDone = false;
			this.fieldHashCS = new Hashtable();
			this.fieldHashCI = new Hashtable(StringComparer.InvariantCultureIgnoreCase);
		}
        /// <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)
        {
#if !NETSTANDARD1_6
      // 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 SUPPORT_REPLICATION
      // 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_6
                System.Transactions.Transaction curTrans = System.Transactions.Transaction.Current;

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

                lastInsertedId = -1;

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

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

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

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

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


                try
                {
                    MySqlDataReader reader = new MySqlDataReader(this, statement, behavior);
                    connection.Reader.Add(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();
                        }
                    }
                }
            }
        }
Exemple #4
0
		private void Prepare(int cursorPageSize) {
			if (!this.connection.driver.Version.isAtLeast(5, 0, 0) && (cursorPageSize > 0)) {
				throw new InvalidOperationException("Nested commands are only supported on MySQL 5.0 and later");
			}
			string commandText = this.CommandText;
			if ((commandText != null) && (commandText.Trim().Length != 0)) {
				if (this.CommandType == System.Data.CommandType.StoredProcedure) {
					this.statement = new StoredProcedure(this, this.CommandText);
				} else {
					this.statement = new PreparableStatement(this, this.CommandText);
				}
				this.statement.Prepare();
			}
		}
Exemple #5
0
		new public MySqlDataReader ExecuteReader(CommandBehavior behavior) {
			MySqlDataReader reader2;
			this.lastInsertedId = -1L;
			this.CheckState();
			if ((this.cmdText == null) || (this.cmdText.Trim().Length == 0)) {
				throw new InvalidOperationException(Resources.CommandTextNotInitialized);
			}
			string text = TrimSemicolons(this.cmdText);
			this.connection.IsExecutingBuggyQuery = false;
			if (!this.connection.driver.Version.isAtLeast(5, 0, 0) && this.connection.driver.Version.isAtLeast(4, 1, 0)) {
				string str2 = text;
				if (str2.Length > 0x11) {
					str2 = text.Substring(0, 0x11);
				}
				str2 = str2.ToLower(CultureInfo.InvariantCulture);
				this.connection.IsExecutingBuggyQuery = str2.StartsWith("describe") || str2.StartsWith("show table status");
			}
			if ((this.statement == null) || !this.statement.IsPrepared) {
				if (this.CommandType == System.Data.CommandType.StoredProcedure) {
					this.statement = new StoredProcedure(this, text);
				} else {
					this.statement = new PreparableStatement(this, text);
				}
			}
			this.statement.Resolve();
			this.HandleCommandBehaviors(behavior);
			this.updatedRowCount = -1L;
			Timer timer = null;
			try {
				MySqlDataReader reader = new MySqlDataReader(this, this.statement, behavior);
				this.timedOut = false;
				this.statement.Execute();
				if (this.connection.driver.Version.isAtLeast(5, 0, 0) && (this.commandTimeout > 0)) {
					TimerCallback callback = new TimerCallback(this.TimeoutExpired);
					timer = new Timer(callback, this, this.CommandTimeout * 0x3e8, -1);
				}
				reader.NextResult();
				this.connection.Reader = reader;
				reader2 = reader;
			} catch (MySqlException exception) {
				if (exception.Number == 0x525) {
					if (this.TimedOut) {
						throw new MySqlException(Resources.Timeout);
					}
					return null;
				}
				if (exception.IsFatal) {
					this.Connection.Close();
				}
				if (exception.Number == 0) {
					throw new MySqlException(Resources.FatalErrorDuringExecute, exception);
				}
				throw;
			} finally {
				if (timer != null) {
					timer.Dispose();
				}
			}
			return reader2;
		}