private Row ScanRowAsyncRemainder(Row row, PayloadData payload) { if (EofPayload.IsEof(payload)) { var eof = EofPayload.Create(payload); BufferState = (eof.ServerStatus & ServerStatus.MoreResultsExist) == 0 ? ResultSetState.NoMoreData : ResultSetState.HasMoreData; m_rowBuffered = null; return(null); } var reader = new ByteArrayReader(payload.ArraySegment); for (var column = 0; column < m_dataOffsets.Length; column++) { var length = checked ((int)ReadFieldLength(reader)); m_dataLengths[column] = length == -1 ? 0 : length; m_dataOffsets[column] = length == -1 ? -1 : reader.Offset; reader.Offset += m_dataLengths[column]; } if (row == null) { row = new Row(this); } row.SetData(m_dataLengths, m_dataOffsets, payload.ArraySegment.Array); m_rowBuffered = row; return(row); }
private ValueTask <Row> ScanRowAsync(IOBehavior ioBehavior, Row row, CancellationToken cancellationToken) { // if we've already read past the end of this resultset, Read returns false if (BufferState == ResultSetState.HasMoreData || BufferState == ResultSetState.NoMoreData || BufferState == ResultSetState.None) { return(new ValueTask <Row>((Row)null)); } using (Command.RegisterCancel(cancellationToken)) { var payloadValueTask = Session.ReceiveReplyAsync(ioBehavior, CancellationToken.None); return(payloadValueTask.IsCompletedSuccessfully ? new ValueTask <Row>(ScanRowAsyncRemainder(payloadValueTask.Result)) : new ValueTask <Row>(ScanRowAsyncAwaited(payloadValueTask.AsTask(), cancellationToken))); } async Task <Row> ScanRowAsyncAwaited(Task <PayloadData> payloadTask, CancellationToken token) { try { return(ScanRowAsyncRemainder(await payloadTask.ConfigureAwait(false))); } catch (MySqlException ex) when(ex.Number == (int)MySqlErrorCode.QueryInterrupted) { BufferState = State = ResultSetState.NoMoreData; token.ThrowIfCancellationRequested(); throw; } } Row ScanRowAsyncRemainder(PayloadData payload) { if (EofPayload.IsEof(payload)) { var eof = EofPayload.Create(payload); BufferState = (eof.ServerStatus & ServerStatus.MoreResultsExist) == 0 ? ResultSetState.NoMoreData : ResultSetState.HasMoreData; m_rowBuffered = null; return(null); } var reader = new ByteArrayReader(payload.ArraySegment); for (var column = 0; column < m_dataOffsets.Length; column++) { var length = reader.ReadLengthEncodedIntegerOrNull(); m_dataLengths[column] = length == -1 ? 0 : length; m_dataOffsets[column] = length == -1 ? -1 : reader.Offset; reader.Offset += m_dataLengths[column]; } if (row == null) { row = new Row(this); } row.SetData(m_dataLengths, m_dataOffsets, payload.ArraySegment); m_rowBuffered = row; return(row); } }
private bool ReadAsyncRemainder(PayloadData payload) { if (EofPayload.IsEof(payload)) { var eof = EofPayload.Create(payload); m_state = eof.ServerStatus.HasFlag(ServerStatus.MoreResultsExist) ? State.HasMoreData : State.NoMoreData; return(false); } var reader = new ByteArrayReader(payload.ArraySegment); for (var column = 0; column < m_dataOffsets.Length; column++) { var length = checked ((int)ReadFieldLength(reader)); m_dataLengths[column] = length == -1 ? 0 : length; m_dataOffsets[column] = length == -1 ? -1 : reader.Offset; reader.Offset += m_dataLengths[column]; } m_currentRow = payload.ArraySegment.Array; m_state = State.ReadingRows; return(true); }
static Row?ScanRowAsyncRemainder(ResultSet this_, PayloadData payload, Row?row_) { if (payload.HeaderByte == EofPayload.Signature) { var span = payload.Span; if (this_.Session.SupportsDeprecateEof && OkPayload.IsOk(span, this_.Session.SupportsDeprecateEof)) { var ok = OkPayload.Create(span, this_.Session.SupportsDeprecateEof, this_.Session.SupportsSessionTrack); this_.BufferState = (ok.ServerStatus & ServerStatus.MoreResultsExist) == 0 ? ResultSetState.NoMoreData : ResultSetState.HasMoreData; return(null); } if (!this_.Session.SupportsDeprecateEof && EofPayload.IsEof(payload)) { var eof = EofPayload.Create(span); this_.BufferState = (eof.ServerStatus & ServerStatus.MoreResultsExist) == 0 ? ResultSetState.NoMoreData : ResultSetState.HasMoreData; return(null); } } if (row_ is null) { bool isBinaryRow = false; if (payload.HeaderByte == 0 && !this_.Connection.IgnorePrepare) { // this might be a binary row, but it might also be a text row whose first column is zero bytes long; try reading // the row as a series of length-encoded values (the text format) to see if this might plausibly be a text row var isTextRow = false; var reader = new ByteArrayReader(payload.Span); var columnCount = 0; while (reader.BytesRemaining > 0) { int length; var firstByte = reader.ReadByte(); if (firstByte == 0xFB) { // NULL length = 0; } else if (firstByte == 0xFC) { // two-byte length-encoded integer if (reader.BytesRemaining < 2) { break; } length = unchecked ((int)reader.ReadFixedLengthUInt32(2)); } else if (firstByte == 0xFD) { // three-byte length-encoded integer if (reader.BytesRemaining < 3) { break; } length = unchecked ((int)reader.ReadFixedLengthUInt32(3)); } else if (firstByte == 0xFE) { // eight-byte length-encoded integer if (reader.BytesRemaining < 8) { break; } length = checked ((int)reader.ReadFixedLengthUInt64(8)); } else if (firstByte == 0xFF) { // invalid length prefix break; } else { // single-byte length length = firstByte; } if (reader.BytesRemaining < length) { break; } reader.Offset += length; columnCount++; if (columnCount == this_.ColumnDefinitions !.Length) { // if we used up all the bytes reading exactly 'ColumnDefinitions' length-encoded columns, then assume this is a text row if (reader.BytesRemaining == 0) { isTextRow = true; } break; } } isBinaryRow = !isTextRow; } row_ = isBinaryRow ? (Row) new BinaryRow(this_) : new TextRow(this_); } row_.SetData(payload.Memory); this_.m_hasRows = true; this_.BufferState = ResultSetState.ReadingRows; return(row_); }
private ValueTask <Row> ScanRowAsync(IOBehavior ioBehavior, Row row, CancellationToken cancellationToken) { // if we've already read past the end of this resultset, Read returns false if (BufferState == ResultSetState.HasMoreData || BufferState == ResultSetState.NoMoreData || BufferState == ResultSetState.None) { return(new ValueTask <Row>((Row)null)); } using (Command.RegisterCancel(cancellationToken)) { var payloadValueTask = Session.ReceiveReplyAsync(ioBehavior, CancellationToken.None); return(payloadValueTask.IsCompletedSuccessfully ? new ValueTask <Row>(ScanRowAsyncRemainder(payloadValueTask.Result, row)) : new ValueTask <Row>(ScanRowAsyncAwaited(payloadValueTask.AsTask(), row, cancellationToken))); } async Task <Row> ScanRowAsyncAwaited(Task <PayloadData> payloadTask, Row row_, CancellationToken token) { PayloadData payloadData; try { payloadData = await payloadTask.ConfigureAwait(false); } catch (MySqlException ex) { BufferState = State = ResultSetState.NoMoreData; if (ex.Number == (int)MySqlErrorCode.QueryInterrupted) { token.ThrowIfCancellationRequested(); } throw; } return(ScanRowAsyncRemainder(payloadData, row_)); } Row ScanRowAsyncRemainder(PayloadData payload, Row row_) { if (payload.HeaderByte == EofPayload.Signature) { var span = payload.AsSpan(); if (Session.SupportsDeprecateEof && OkPayload.IsOk(span, Session.SupportsDeprecateEof)) { var ok = OkPayload.Create(span, Session.SupportsDeprecateEof, Session.SupportsSessionTrack); BufferState = (ok.ServerStatus & ServerStatus.MoreResultsExist) == 0 ? ResultSetState.NoMoreData : ResultSetState.HasMoreData; m_rowBuffered = null; return(null); } if (!Session.SupportsDeprecateEof && EofPayload.IsEof(payload)) { var eof = EofPayload.Create(span); BufferState = (eof.ServerStatus & ServerStatus.MoreResultsExist) == 0 ? ResultSetState.NoMoreData : ResultSetState.HasMoreData; m_rowBuffered = null; return(null); } } if (row_ == null) { row_ = DataReader.ResultSetProtocol == ResultSetProtocol.Binary ? (Row) new BinaryRow(this) : new TextRow(this); } row_.SetData(payload.ArraySegment); m_rowBuffered = row_; m_hasRows = true; BufferState = ResultSetState.ReadingRows; return(row_); } }
private ValueTask <Row> ScanRowAsync(IOBehavior ioBehavior, Row row, CancellationToken cancellationToken) { // if we've already read past the end of this resultset, Read returns false if (BufferState == ResultSetState.HasMoreData || BufferState == ResultSetState.NoMoreData || BufferState == ResultSetState.None) { return(new ValueTask <Row>((Row)null)); } using (Command.CancellableCommand.RegisterCancel(cancellationToken)) { var payloadValueTask = Session.ReceiveReplyAsync(ioBehavior, CancellationToken.None); return(payloadValueTask.IsCompletedSuccessfully ? new ValueTask <Row>(ScanRowAsyncRemainder(payloadValueTask.Result, row)) : new ValueTask <Row>(ScanRowAsyncAwaited(payloadValueTask.AsTask(), row, cancellationToken))); } async Task <Row> ScanRowAsyncAwaited(Task <PayloadData> payloadTask, Row row_, CancellationToken token) { PayloadData payloadData; try { payloadData = await payloadTask.ConfigureAwait(false); } catch (MySqlException ex) { BufferState = State = ResultSetState.NoMoreData; if (ex.Number == (int)MySqlErrorCode.QueryInterrupted) { token.ThrowIfCancellationRequested(); } throw; } return(ScanRowAsyncRemainder(payloadData, row_)); } Row ScanRowAsyncRemainder(PayloadData payload, Row row_) { if (payload.HeaderByte == EofPayload.Signature) { var span = payload.AsSpan(); if (Session.SupportsDeprecateEof && OkPayload.IsOk(span, Session.SupportsDeprecateEof)) { var ok = OkPayload.Create(span, Session.SupportsDeprecateEof, Session.SupportsSessionTrack); BufferState = (ok.ServerStatus & ServerStatus.MoreResultsExist) == 0 ? ResultSetState.NoMoreData : ResultSetState.HasMoreData; m_rowBuffered = null; return(null); } if (!Session.SupportsDeprecateEof && EofPayload.IsEof(payload)) { var eof = EofPayload.Create(span); BufferState = (eof.ServerStatus & ServerStatus.MoreResultsExist) == 0 ? ResultSetState.NoMoreData : ResultSetState.HasMoreData; m_rowBuffered = null; return(null); } } if (row_ is null) { bool isBinaryRow = false; if (payload.HeaderByte == 0 && !Connection.IgnorePrepare) { // this might be a binary row, but it might also be a text row whose first column is zero bytes long; try reading // the row as a series of length-encoded values (the text format) to see if this might plausibly be a text row var isTextRow = false; var reader = new ByteArrayReader(payload.AsSpan()); var columnCount = 0; while (reader.BytesRemaining > 0) { int length; var firstByte = reader.ReadByte(); if (firstByte == 0xFB) { // NULL length = 0; } else if (firstByte == 0xFC) { // two-byte length-encoded integer if (reader.BytesRemaining < 2) { break; } length = unchecked ((int)reader.ReadFixedLengthUInt32(2)); } else if (firstByte == 0xFD) { // three-byte length-encoded integer if (reader.BytesRemaining < 3) { break; } length = unchecked ((int)reader.ReadFixedLengthUInt32(3)); } else if (firstByte == 0xFE) { // eight-byte length-encoded integer if (reader.BytesRemaining < 8) { break; } length = checked ((int)reader.ReadFixedLengthUInt64(8)); } else if (firstByte == 0xFF) { // invalid length prefix break; } else { // single-byte length length = firstByte; } if (reader.BytesRemaining < length) { break; } reader.Offset += length; columnCount++; if (columnCount == ColumnDefinitions.Length) { // if we used up all the bytes reading exactly 'ColumnDefinitions' length-encoded columns, then assume this is a text row if (reader.BytesRemaining == 0) { isTextRow = true; } break; } } isBinaryRow = !isTextRow; } row_ = isBinaryRow ? (Row) new BinaryRow(this) : new TextRow(this); } row_.SetData(payload.ArraySegment); m_rowBuffered = row_; m_hasRows = true; BufferState = ResultSetState.ReadingRows; return(row_); } }