/// <summary> /// Process rows and sets the paging event handler /// </summary> internal void ProcessRows(RowSet rs, FrameReader reader, ResultMetadata providedResultMetadata) { RowSetMetadata resultMetadata = null; // result metadata in the response takes precedence over the previously provided result metadata. if (ResultRowsMetadata != null) { resultMetadata = ResultRowsMetadata; rs.Columns = ResultRowsMetadata.Columns; rs.PagingState = ResultRowsMetadata.PagingState; } // if the response has no column definitions, then SKIP_METADATA was set by the driver // the driver only sets this flag for bound statements if (resultMetadata?.Columns == null) { resultMetadata = providedResultMetadata?.RowSetMetadata; rs.Columns = resultMetadata?.Columns; } for (var i = 0; i < _rowLength; i++) { rs.AddRow(ProcessRowItem(reader, resultMetadata)); } }
internal ResultResponse(Frame frame) : base(frame) { Kind = (ResultResponseKind)Reader.ReadInt32(); switch (Kind) { case ResultResponseKind.Void: Output = new OutputVoid(TraceId); break; case ResultResponseKind.Rows: var outputRows = new OutputRows(Reader, frame.ResultMetadata, TraceId); Output = outputRows; if (outputRows.ResultRowsMetadata.HasNewResultMetadataId()) { NewResultMetadata = new ResultMetadata( outputRows.ResultRowsMetadata.NewResultMetadataId, outputRows.ResultRowsMetadata); } break; case ResultResponseKind.SetKeyspace: Output = new OutputSetKeyspace(Reader.ReadString()); break; case ResultResponseKind.Prepared: Output = new OutputPrepared(frame.Header.Version, Reader); break; case ResultResponseKind.SchemaChange: Output = new OutputSchemaChange(frame.Header.Version, Reader, TraceId); break; default: throw new DriverInternalError("Unknown ResultResponseKind Type"); } }
public Frame(FrameHeader header, Stream body, ISerializer serializer, ResultMetadata resultMetadata) { Header = header ?? throw new ArgumentNullException(nameof(header)); Body = body ?? throw new ArgumentNullException(nameof(body)); Serializer = serializer ?? throw new ArgumentNullException(nameof(serializer)); ResultMetadata = resultMetadata; }
internal OutputRows(FrameReader reader, ResultMetadata resultMetadata, Guid?traceId) { ResultRowsMetadata = new RowSetMetadata(reader); _rowLength = reader.ReadInt32(); TraceId = traceId; RowSet = new RowSet(); ProcessRows(RowSet, reader, resultMetadata); }
internal PreparedStatement(RowSetMetadata variablesRowsMetadata, byte[] id, ResultMetadata resultMetadata, string cql, string keyspace, ISerializerManager serializer) { _variablesRowsMetadata = variablesRowsMetadata; _resultMetadata = resultMetadata; Id = id; Cql = cql; Keyspace = keyspace; _serializerManager = serializer; }
/// <summary> /// Returns an action that capture the parameters closure /// </summary> private Action <MemoryStream, long> CreateResponseAction( ResultMetadata resultMetadata, ISerializer serializer, FrameHeader header, Action <IRequestError, Response, long> callback) { var compressor = Compressor; void DeserializeResponseStream(MemoryStream stream, long timestamp) { Response response = null; IRequestError error = null; var nextPosition = stream.Position + header.BodyLength; try { Stream plainTextStream = stream; if (header.Flags.HasFlag(HeaderFlags.Compression)) { plainTextStream = compressor.Decompress(new WrappedStream(stream, header.BodyLength)); plainTextStream.Position = 0; } response = FrameParser.Parse(new Frame(header, plainTextStream, serializer, resultMetadata)); } catch (Exception caughtException) { error = RequestError.CreateClientError(caughtException, false); } if (response is ErrorResponse errorResponse) { error = RequestError.CreateServerError(errorResponse); response = null; } //We must advance the position of the stream manually in case it was not correctly parsed stream.Position = nextPosition; callback(error, response, timestamp); } return(DeserializeResponseStream); }
public void SetResult(object result) { _result = new ResultMetadata(result); }
/// <summary> /// Deserializes each frame header and copies the body bytes into a single buffer. /// </summary> /// <returns>True if a full operation (streamId) has been processed.</returns> internal bool ReadParse(byte[] buffer, int length) { if (length <= 0) { return(false); } // Check if protocol version has already been determined (first message) ProtocolVersion protocolVersion; var headerLength = Volatile.Read(ref _frameHeaderSize); var serializer = Volatile.Read(ref _serializer); if (headerLength == 0) { // The server replies the first message with the max protocol version supported protocolVersion = FrameHeader.GetProtocolVersion(buffer); serializer = serializer.CloneWithProtocolVersion(protocolVersion); headerLength = protocolVersion.GetHeaderSize(); Volatile.Write(ref _serializer, serializer); Volatile.Write(ref _frameHeaderSize, headerLength); _frameHeaderSize = headerLength; } else { protocolVersion = serializer.ProtocolVersion; } // Use _readStream to buffer between messages, when the body is not contained in a single read call var stream = Interlocked.Exchange(ref _readStream, null); var previousHeader = Interlocked.Exchange(ref _receivingHeader, null); if (previousHeader != null && stream == null) { // This connection has been disposed return(false); } var operationCallbacks = new LinkedList <Action <MemoryStream, long> >(); var offset = 0; while (offset < length) { FrameHeader header; int remainingBodyLength; // check if header has not been read yet if (previousHeader == null) { header = ReadHeader(buffer, ref offset, length, headerLength, protocolVersion); if (header == null) { // There aren't enough bytes to read the header break; } Connection.Logger.Verbose("Received #{0} from {1}", header.StreamId, EndPoint.EndpointFriendlyName); remainingBodyLength = header.BodyLength; } else { header = previousHeader; previousHeader = null; remainingBodyLength = header.BodyLength - (int)stream.Length; } if (remainingBodyLength > length - offset) { // The buffer does not contains the body for the current frame, store it for later StoreReadState(header, stream, buffer, offset, length, operationCallbacks.Count > 0); break; } // Get read stream stream = stream ?? Configuration.BufferPool.GetStream(Connection.StreamReadTag); // Get callback and operation state Action <IRequestError, Response, long> callback; ResultMetadata resultMetadata = null; if (header.Opcode == EventResponse.OpCode) { callback = EventHandler; } else { var state = RemoveFromPending(header.StreamId); // State can be null when the Connection is being closed concurrently // The original callback is being called with an error, use a Noop here if (state == null) { callback = OperationState.Noop; } else { callback = state.SetCompleted(); resultMetadata = state.ResultMetadata; } } // Write to read stream stream.Write(buffer, offset, remainingBodyLength); // Add callback with deserialize from stream operationCallbacks.AddLast(CreateResponseAction(resultMetadata, serializer, header, callback)); offset += remainingBodyLength; } // Invoke callbacks with read stream return(Connection.InvokeReadCallbacks(stream, operationCallbacks, GetTimestamp())); }
internal void UpdateResultMetadata(ResultMetadata resultMetadata) { _resultMetadata = resultMetadata; }