prepare method
Prepares given query
Returns PreparedStmt which can be used to execute prepared statement multiple times with different parameters See PreparedStmt.execute You shoud call PreparedStmt.deallocate when you don't need prepared statement anymore to prevent memory leaks
Pass iterable
true if you want to iterable result set. See execute for details
Implementation
Future<PreparedStmt> prepare(String query, [bool iterable = false]) async {
if (!_connected) {
throw MySQLClientException("Can not prepare stmt: connection closed");
}
// wait for ready state
if (_state != _MySQLConnectionState.connectionEstablished) {
await _waitForState(_MySQLConnectionState.connectionEstablished)
.timeout(Duration(milliseconds: _timeoutMs));
}
_state = _MySQLConnectionState.waitingCommandResponse;
final payload = MySQLPacketCommStmtPrepare(query: query);
final packet = MySQLPacket(
sequenceID: 0,
payload: payload,
payloadLength: 0,
);
final completer = Completer<PreparedStmt>();
/**
* 0 - initial
* 1 - first packet decoded
* 2 - eof decoded
*/
int state = 0;
int numOfEofPacketsParsed = 0;
MySQLPacketStmtPrepareOK? preparedPacket;
_responseCallback = (data) async {
try {
MySQLPacket? packet;
switch (state) {
case 0:
packet = MySQLPacket.decodeCommPrepareStmtResponsePacket(data);
state = 1;
break;
default:
packet = null;
if (MySQLPacket.detectPacketType(data) ==
MySQLGenericPacketType.eof) {
numOfEofPacketsParsed++;
var done = false;
assert(preparedPacket != null);
if (preparedPacket!.numOfCols > 0 &&
preparedPacket!.numOfParams > 0) {
// there should be two EOF packets in this case
if (numOfEofPacketsParsed == 2) {
done = true;
}
} else {
// there should be only one EOF packet otherwise
done = true;
}
if (done) {
state = 2;
completer.complete(PreparedStmt._(
preparedPacket: preparedPacket!,
connection: this,
iterable: iterable,
));
_state = _MySQLConnectionState.connectionEstablished;
return;
}
}
break;
}
if (packet != null) {
final payload = packet.payload;
if (payload is MySQLPacketStmtPrepareOK) {
preparedPacket = payload;
} else if (payload is MySQLPacketError) {
completer.completeError(
MySQLServerException(payload.errorMessage, payload.errorCode),
);
_state = _MySQLConnectionState.connectionEstablished;
return;
} else {
completer.completeError(
MySQLClientException(
"Unexpected payload received in response to COMM_STMT_PREPARE request",
),
StackTrace.current,
);
_forceClose();
return;
}
}
} catch (e) {
completer.completeError(e, StackTrace.current);
_forceClose();
}
};
_socket.add(packet.encode());
return completer.future;
}