Skip to content

Commit a82738f

Browse files
author
Didier Fracassi
committed
Implement COM_STMT_SEND_LONG_DATA
1 parent 76f8c51 commit a82738f

File tree

3 files changed

+45
-8
lines changed

3 files changed

+45
-8
lines changed

src/MySqlConnector/MySqlCommand.cs

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
using System.Buffers;
12
using System.Diagnostics.CodeAnalysis;
23
using Microsoft.Extensions.Logging;
34
using MySqlConnector.Core;
5+
using MySqlConnector.Protocol;
46
using MySqlConnector.Protocol.Serialization;
57
using MySqlConnector.Utilities;
68

@@ -357,15 +359,52 @@ internal async ValueTask<MySqlDataReader> ExecuteReaderAsync(CommandBehavior beh
357359
return await ExecuteReaderNoResetTimeoutAsync(behavior, ioBehavior, cancellationToken).ConfigureAwait(false);
358360
}
359361

360-
internal ValueTask<MySqlDataReader> ExecuteReaderNoResetTimeoutAsync(CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken)
362+
internal async ValueTask<MySqlDataReader> ExecuteReaderNoResetTimeoutAsync(CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken)
361363
{
362364
if (!IsValid(out var exception))
363-
return ValueTaskExtensions.FromException<MySqlDataReader>(exception);
365+
return await ValueTaskExtensions.FromException<MySqlDataReader>(exception).ConfigureAwait(false);
366+
367+
if (((IMySqlCommand) this).TryGetPreparedStatements() is { Statements.Count: 1 } statements)
368+
{
369+
for (var i = 0; i < Parameters.Count; i++)
370+
{
371+
if (Parameters[i].Value is Stream stream)
372+
{
373+
var writer = new ByteBufferWriter();
374+
writer.Write((byte) CommandKind.StatementSendLongData);
375+
writer.Write(statements.Statements[0].StatementId);
376+
writer.Write((ushort) i);
377+
378+
var buffer = ArrayPool<byte>.Shared.Rent(ProtocolUtility.MaxPacketSize);
379+
var dataLength = ProtocolUtility.MaxPacketSize - 7;
380+
381+
var bytesRead = stream.Read(buffer, 0, dataLength);
382+
writer.Write(buffer.AsSpan(0, bytesRead));
383+
384+
await Connection!.Session.SendAsync(writer.ToPayloadData(), ioBehavior, cancellationToken).ConfigureAwait(false);
385+
386+
if (bytesRead == dataLength)
387+
{
388+
dataLength = ProtocolUtility.MaxPacketSize;
389+
390+
do
391+
{
392+
bytesRead = stream.Read(buffer, 0, dataLength);
393+
394+
writer = new ByteBufferWriter();
395+
writer.Write(buffer.AsSpan(0, bytesRead));
396+
await Connection!.Session.SendReplyAsync(writer.ToPayloadData(), ioBehavior, cancellationToken).ConfigureAwait(false);
397+
}
398+
while (bytesRead == dataLength);
399+
}
400+
}
401+
}
402+
}
364403

365404
var activity = NoActivity ? null : Connection!.Session.StartActivity(ActivitySourceHelper.ExecuteActivityName,
366405
ActivitySourceHelper.DatabaseStatementTagName, CommandText);
367406
m_commandBehavior = behavior;
368-
return CommandExecutor.ExecuteReaderAsync(new(this), SingleCommandPayloadCreator.Instance, behavior, activity, ioBehavior, cancellationToken);
407+
return await CommandExecutor.ExecuteReaderAsync(new(this), SingleCommandPayloadCreator.Instance, behavior, activity, ioBehavior, cancellationToken).ConfigureAwait(false);
369408
}
370409

371410
public MySqlCommand Clone() => new(this);

src/MySqlConnector/MySqlParameter.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -714,12 +714,9 @@ private void AppendBinary(ByteBufferWriter writer, object value, StatementPrepar
714714
writer.WriteLengthEncodedInteger(unchecked((ulong) geometry.ValueSpan.Length));
715715
writer.Write(geometry.ValueSpan);
716716
}
717-
else if (value is MemoryStream memoryStream)
717+
else if (value is Stream)
718718
{
719-
if (!memoryStream.TryGetBuffer(out var streamBuffer))
720-
streamBuffer = new ArraySegment<byte>(memoryStream.ToArray());
721-
writer.WriteLengthEncodedInteger(unchecked((ulong) streamBuffer.Count));
722-
writer.Write(streamBuffer);
719+
// do nothing; this will be sent via CommandKind.StatementSendLongData
723720
}
724721
else if (value is float floatValue)
725722
{

src/MySqlConnector/Protocol/CommandKind.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ internal enum CommandKind
99
ChangeUser = 17,
1010
StatementPrepare = 22,
1111
StatementExecute = 23,
12+
StatementSendLongData = 24,
1213
ResetConnection = 31,
1314
}

0 commit comments

Comments
 (0)