private async Task WriteExecFinishAndProcess <TState, TResult>( TState initialState, Func <TState, TResult> resultFactory, Action <TResult, ReadBuffer, int, int> columnBinder) { await WriteExecFinish(); await _readBuffer.ReceiveAsync(); read: var message = _readBuffer.ReadMessage(); switch (message.Type) { case MessageType.BindComplete: goto read; case MessageType.DataRow: { var result = resultFactory != null ? resultFactory(initialState) : default; var columns = _readBuffer.ReadShort(); for (var i = 0; i < columns; i++) { var length = _readBuffer.ReadInt(); columnBinder(result, _readBuffer, i, length); } goto read; } case MessageType.CommandComplete: return; case MessageType.ErrorResponse: throw new InvalidOperationException(_readBuffer.ReadErrorMessage()); default: throw new NotImplementedException(message.Type.ToString()); } }
public async Task ExecuteAsync <TResult>( string statementName, Func <TResult> resultFactory, Action <TResult, ReadBuffer, int, int> columnBinder) { ThrowIfDisposed(); ThrowIfNotConnected(); await _writeBuffer .StartMessage('B') .WriteNull() .WriteString(statementName) .WriteShort(0) .WriteShort(0) .WriteShort(1) .WriteShort(1) .EndMessage() .StartMessage('E') .WriteNull() .WriteInt(0) .EndMessage() .StartMessage('S') .EndMessage() .FlushAsync(); await _readBuffer.ReceiveAsync(); read: var message = ReadMessage(); switch (message.Type) { case MessageType.BindComplete: goto read; case MessageType.DataRow: { var result = resultFactory != null ? resultFactory() : default; var columns = _readBuffer.ReadShort(); for (var i = 0; i < columns; i++) { var length = _readBuffer.ReadInt(); columnBinder(result, _readBuffer, i, length); } goto read; } case MessageType.CommandComplete: return; case MessageType.ErrorResponse: throw new InvalidOperationException(ReadErrorMessage()); default: throw new NotImplementedException(message.Type.ToString()); } }