コード例 #1
0
        /// <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);
        }
コード例 #2
0
        /// <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));
        }