in MySQL.Data/src/PreparableStatement.cs [67:156]
public async Task PrepareAsync(bool execAsync)
{
// strip out names from parameter markers
string text;
List<string> parameterNames = PrepareCommandText(out text);
// ask our connection to send the prepare command
var result = await Driver.PrepareStatementAsync(text, execAsync).ConfigureAwait(false);
StatementId = result.Item1;
MySqlField[] paramList = result.Item2;
// now we need to assign our field names since we stripped them out
// for the prepare
for (int i = 0; i < parameterNames.Count; i++)
{
string parameterName = (string)parameterNames[i];
MySqlParameter p = Parameters.GetParameterFlexible(parameterName, false);
if (p == null)
throw new InvalidOperationException(
String.Format(Resources.ParameterNotFoundDuringPrepare, parameterName));
p.Encoding = paramList[i].Encoding;
_parametersToSend.Add(p);
}
if (Attributes.Count > 0 && !Driver.SupportsQueryAttributes)
MySqlTrace.LogWarning(Connection.ServerThread, string.Format(Resources.QueryAttributesNotSupported, Driver.Version));
_packet = new MySqlPacket(Driver.Encoding);
// write out some values that do not change run to run
_packet.WriteByte(0);
await _packet.WriteIntegerAsync(StatementId, 4, execAsync).ConfigureAwait(false);
// flags; if server supports query attributes, then set PARAMETER_COUNT_AVAILABLE (0x08) in the flags block
int flags = Driver.SupportsQueryAttributes && Driver.Version.isAtLeast(8, 0, 26) ? PARAMETER_COUNT_AVAILABLE : 0;
await _packet.WriteIntegerAsync(flags, 1, execAsync).ConfigureAwait(false);
await _packet.WriteIntegerAsync(1, 4, execAsync).ConfigureAwait(false); // iteration count; 1 for 4.1
int num_params = paramList != null ? paramList.Length : 0;
// we don't send QA with PS when MySQL Server is not at least 8.0.26
if (!Driver.Version.isAtLeast(8, 0, 26) && Attributes.Count > 0)
{
MySqlTrace.LogWarning(Connection.ServerThread, Resources.QueryAttributesNotSupportedByCnet);
Attributes.Clear();
}
if (num_params > 0 ||
(Driver.SupportsQueryAttributes && flags == PARAMETER_COUNT_AVAILABLE)) // if num_params > 0
{
int paramCount = num_params;
if (Driver.SupportsQueryAttributes) // if CLIENT_QUERY_ATTRIBUTES is on
{
paramCount += Attributes.Count;
await _packet.WriteLengthAsync(paramCount, execAsync).ConfigureAwait(false);
}
if (paramCount > 0)
{
// now prepare our null map
_nullMap = new BitArray(paramCount);
int numNullBytes = (_nullMap.Length + 7) / 8;
_nullMapPosition = _packet.Position;
_packet.Position += numNullBytes; // leave room for our null map
_packet.WriteByte(1); // new_params_bind_flag
// write out the parameter types and names
foreach (MySqlParameter p in _parametersToSend)
{
// parameter type
await _packet.WriteIntegerAsync(p.GetPSType(), 2, execAsync).ConfigureAwait(false);
// parameter name
if (Driver.SupportsQueryAttributes) // if CLIENT_QUERY_ATTRIBUTES is on
await _packet.WriteLenStringAsync(String.Empty, execAsync).ConfigureAwait(false);
}
// write out the attributes types and names
foreach (MySqlAttribute a in Attributes)
{
// attribute type
await _packet.WriteIntegerAsync(a.GetPSType(), 2, execAsync).ConfigureAwait(false);
// attribute name
if (Driver.SupportsQueryAttributes) // if CLIENT_QUERY_ATTRIBUTES is on
await _packet.WriteLenStringAsync(a.AttributeName, execAsync).ConfigureAwait(false);
}
}
}
_dataPosition = _packet.Position;
}