/// <summary> /// Handles the response of a (re)prepare request and retries to execute on the same connection /// </summary> private Action <IRequestError, Response, Host> NewReprepareResponseHandler( PreparedQueryNotFoundException originalError) { void ResponseHandler(IRequestError error, Response response, Host host) { try { if (error?.Exception != null) { HandleRequestError(error, host); return; } RequestExecution.ValidateResult(response); var output = ((ResultResponse)response).Output; if (!(output is OutputPrepared outputPrepared)) { _parent.SetCompleted(new DriverInternalError("Expected prepared response, obtained " + output.GetType().FullName)); return; } if (!outputPrepared.QueryId.SequenceEqual(originalError.UnknownId)) { _parent.SetCompleted(new PreparedStatementIdMismatchException( originalError.UnknownId, outputPrepared.QueryId)); return; } if (_parent.Statement is BoundStatement boundStatement) { // Use the latest result metadata id boundStatement.PreparedStatement.UpdateResultMetadata( new ResultMetadata(outputPrepared.ResultMetadataId, outputPrepared.ResultRowsMetadata)); } Send(_request, host, HandleResponse); } catch (Exception exception) { //There was an issue while sending _parent.SetCompleted(exception); } } return(ResponseHandler); }
/// <summary> /// Sends a prepare request before retrying the statement /// </summary> private void PrepareAndRetry(PreparedQueryNotFoundException ex, Host host) { BoundStatement boundStatement = null; if (_parent.Statement is BoundStatement statement1) { boundStatement = statement1; } else if (_parent.Statement is BatchStatement batch) { bool SearchBoundStatement(Statement s) => s is BoundStatement statement && statement.PreparedStatement.Id.SequenceEqual(ex.UnknownId); boundStatement = (BoundStatement)batch.Queries.FirstOrDefault(SearchBoundStatement); } if (boundStatement == null) { throw new DriverInternalError("Expected Bound or batch statement"); } var preparedKeyspace = boundStatement.PreparedStatement.Keyspace; var request = new InternalPrepareRequest(boundStatement.PreparedStatement.Cql, preparedKeyspace); if (!_parent.Serializer.ProtocolVersion.SupportsKeyspaceInRequest() && preparedKeyspace != null && _session.Keyspace != preparedKeyspace) { Logger.Warning(string.Format("The statement was prepared using another keyspace, changing the keyspace temporarily to" + " {0} and back to {1}. Use keyspace and table identifiers in your queries and avoid switching keyspaces.", preparedKeyspace, _session.Keyspace)); _connection .SetKeyspace(preparedKeyspace) .ContinueSync(_ => { Send(request, host, NewReprepareResponseHandler(ex)); return(true); }); return; } Send(request, host, NewReprepareResponseHandler(ex)); }