public async Task PrepareAsync()

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;
    }