internal void GetParametersFromShowCreate(MyCatSchemaCollection parametersTable, string[] restrictions, MyCatSchemaCollection routines) { // this allows us to pass in a pre-populated routines table // and avoid the querying for them again. // we use this when calling a procedure or function if (routines == null) { routines = GetSchema("procedures", restrictions); } MyCatCommand cmd = connection.CreateCommand(); foreach (MyCatSchemaRow routine in routines.Rows) { string showCreateSql = String.Format("SHOW CREATE {0} `{1}`.`{2}`", routine["ROUTINE_TYPE"], routine["ROUTINE_SCHEMA"], routine["ROUTINE_NAME"]); cmd.CommandText = showCreateSql; try { string nameToRestrict = null; if (restrictions != null && restrictions.Length == 5 && restrictions[4] != null) { nameToRestrict = restrictions[4]; } using (MyCatDataReader reader = cmd.ExecuteReader()) { reader.Read(); string body = reader.GetString(2); #if NETSTANDARD1_3 reader.Dispose(); #else reader.Close(); #endif ParseProcedureBody(parametersTable, body, routine, nameToRestrict); } } #if NETSTANDARD1_3 catch (MyCatNullValueException snex) #else catch (System.Data.SqlTypes.SqlNullValueException snex) #endif { throw new InvalidOperationException( String.Format(Resources.UnableToRetrieveParameters, routine["ROUTINE_NAME"]), snex); } } }
/// <include file='docs/mysqlcommand.xml' path='docs/ExecuteNonQuery/*'/> public override int ExecuteNonQuery() { #if !NETSTANDARD1_3 int records = -1; // give our interceptors a shot at it first if (connection != null && connection.commandInterceptor != null && connection.commandInterceptor.ExecuteNonQuery(CommandText, ref records)) { return(records); } #endif // ok, none of our interceptors handled this so we default using (MyCatDataReader reader = ExecuteReader()) { #if !NETSTANDARD1_3 reader.Close(); #else reader.Dispose(); #endif return(reader.RecordsAffected); } }
/// <include file='docs/mysqlcommand.xml' path='docs/ExecuteReader1/*'/> public new MyCatDataReader ExecuteReader(CommandBehavior behavior) { #if !NETSTANDARD1_3 // give our interceptors a shot at it first MyCatDataReader 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(';'); var splited_sql = sql.Split(';'); var not_second_query = splited_sql.First().IndexOf("SELECT") >= 0 || splited_sql.Count() == 1; var second_query = splited_sql.Where(x => x.IndexOf("SELECT") >= 0).ToList(); if (!not_second_query) { sql = string.Join(";", splited_sql.Where(x => x.IndexOf("SELECT") < 0)); } lock (driver) { #if !NETSTANDARD1_3 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 { MyCatDataReader reader = new MyCatDataReader(this, statement, behavior); connection.Reader.Add(reader); canceled = false; // execute the statement statement.Execute(); // wait for data to return try { reader.NextResult(); } catch (MyCatException ex) { if (ex.Number != 1064) { throw; } } success = true; if (!not_second_query) { reader.Dispose(); connection.Reader.Remove(reader); if (second_query.Count > 0) { return(_ExecuteReader(behavior, second_query.First())); } } 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 MyCatException(Resources.FatalErrorDuringExecute, ioex); } catch (MyCatException 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 MyCatException(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 MyCatException(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(); } } } } }