/// <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));
            }
        }
Exemple #2
0
        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");
            }
        }
Exemple #3
0
 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;
 }
Exemple #6
0
        /// <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);
        }
Exemple #7
0
 public void SetResult(object result)
 {
     _result = new ResultMetadata(result);
 }
Exemple #8
0
        /// <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;
 }