in MySQL.Data/src/MySqlDataReader.cs [1302:1409]
internal async Task<bool> NextResultAsync(bool execAsync, CancellationToken cancellationToken)
{
if (!_isOpen)
Throw(new MySqlException(Resources.NextResultIsClosed));
bool isCaching = Command.CommandType == CommandType.TableDirect && Command.EnableCaching &&
(CommandBehavior & CommandBehavior.SequentialAccess) == 0;
// this will clear out any unread data
if (ResultSet != null)
{
await ResultSet.CloseAsync(execAsync).ConfigureAwait(false);
if (isCaching)
TableCache.AddToCache(Command.CommandText, ResultSet);
}
// single result means we only return a single resultset. If we have already
// returned one, then we return false
// TableDirect is basically a select * from a single table so it will generate
// a single result also
if (ResultSet != null &&
((CommandBehavior & CommandBehavior.SingleResult) != 0 || isCaching))
return false;
// next load up the next resultset if any
try
{
do
{
ResultSet = null;
// if we are table caching, then try to retrieve the resultSet from the cache
if (isCaching)
ResultSet = TableCache.RetrieveFromCache(Command.CommandText, Command.CacheAge);
if (ResultSet == null)
{
ResultSet = await driver.NextResultAsync(Statement.StatementId, false, execAsync).ConfigureAwait(false);
if (ResultSet == null) return false;
if (ResultSet.IsOutputParameters && Command.CommandType == CommandType.StoredProcedure)
{
StoredProcedure sp = Statement as StoredProcedure;
sp.ProcessOutputParameters(this);
await ResultSet.CloseAsync(execAsync).ConfigureAwait(false);
for (int i = 0; i < ResultSet.Fields.Length; i++)
{
if (ResultSet.Fields[i].ColumnName.StartsWith("@" + StoredProcedure.ParameterPrefix, StringComparison.OrdinalIgnoreCase))
{
ResultSet = null;
break;
}
}
if (!sp.ServerProvidingOutputParameters) return false;
// if we are using server side output parameters then we will get our ok packet
// *after* the output parameters resultset
ResultSet = await driver.NextResultAsync(Statement.StatementId, true, execAsync).ConfigureAwait(false);
}
else if (ResultSet.IsOutputParameters && Command.CommandType == CommandType.Text && !Command.IsPrepared && !Command.InternallyCreated)
{
Command.ProcessOutputParameters(this);
await ResultSet.CloseAsync(execAsync).ConfigureAwait(false);
for (int i = 0; i < ResultSet.Fields.Length; i++)
{
if (ResultSet.Fields[i].ColumnName.StartsWith("@" + MySqlCommand.ParameterPrefix, StringComparison.OrdinalIgnoreCase))
{
ResultSet = null;
break;
}
}
if (!Statement.ServerProvidingOutputParameters) return false;
ResultSet = await driver.NextResultAsync(Statement.StatementId, true, execAsync).ConfigureAwait(false);
}
ResultSet.Cached = isCaching;
}
if (ResultSet.Size == 0)
{
if (Command.LastInsertedId == -1) Command.LastInsertedId = ResultSet.InsertedId;
else {
if (ResultSet.InsertedId > 0) Command.LastInsertedId = ResultSet.InsertedId;
}
if (affectedRows == -1)
affectedRows = ResultSet.AffectedRows;
else
affectedRows += ResultSet.AffectedRows;
}
} while (ResultSet.Size == 0);
return true;
}
catch (MySqlException ex)
{
if (ex.IsFatal)
await _connection.AbortAsync(execAsync, CancellationToken.None).ConfigureAwait(false);
if (ex.Number == 0)
throw new MySqlException(Resources.FatalErrorReadingResult, ex);
if ((CommandBehavior & CommandBehavior.CloseConnection) != 0)
await CloseAsync(execAsync).ConfigureAwait(false);
throw;
}
}