/// <summary> /// Commits the import operation. The writer is unusable after this operation. /// </summary> public void Commit() { CheckReady(); if (InMiddleOfRow) { Cancel(); throw new InvalidOperationException("Binary importer closed in the middle of a row, cancelling import."); } try { WriteTrailer(); _buf.Flush(); _buf.EndCopyMode(); _connector.SendMessage(CopyDoneMessage.Instance); _connector.ReadExpecting <CommandCompleteMessage>(); _connector.ReadExpecting <ReadyForQueryMessage>(); _state = ImporterState.Committed; } catch { // An exception here will have already broken the connection etc. Cleanup(); throw; } }
public override int Read(byte[] buffer, int offset, int count) { CheckDisposed(); if (!CanRead) { throw new InvalidOperationException("Stream not open for reading"); } if (_isConsumed) { return(0); } if (_leftToReadInDataMsg == 0) { // We've consumed the current DataMessage (or haven't yet received the first), // read the next message var msg = _connector.ReadMessage(); switch (msg.Code) { case BackendMessageCode.CopyData: _leftToReadInDataMsg = ((CopyDataMessage)msg).Length; break; case BackendMessageCode.CopyDone: _connector.ReadExpecting <CommandCompleteMessage>(); _connector.ReadExpecting <ReadyForQueryMessage>(); _isConsumed = true; return(0); default: throw _connector.UnexpectedMessageReceived(msg.Code); } } Debug.Assert(_leftToReadInDataMsg > 0); // If our buffer is empty, read in more. Otherwise return whatever is there, even if the // user asked for more (normal socket behavior) if (_readBuf.ReadBytesLeft == 0) { _readBuf.ReadMore(false).GetAwaiter().GetResult(); } Debug.Assert(_readBuf.ReadBytesLeft > 0); var maxCount = Math.Min(_readBuf.ReadBytesLeft, _leftToReadInDataMsg); if (count > maxCount) { count = maxCount; } _leftToReadInDataMsg -= count; _readBuf.ReadBytes(buffer, offset, count); return(count); }
async Task <int> Read(byte[] buffer, int offset, int count, bool async) { if (_leftToRead == 0) { var response = await _connector.ReadExpecting <AuthenticationRequestMessage>(async); if (response.AuthRequestType == AuthenticationRequestType.AuthenticationOk) { throw new AuthenticationCompleteException(); } var gssMsg = response as AuthenticationGSSContinueMessage; if (gssMsg == null) { throw new NpgsqlException($"Received unexpected authentication request message {response.AuthRequestType}"); } _readBuf = gssMsg.AuthenticationData; _leftToRead = gssMsg.AuthenticationData.Length; _readPos = 0; buffer[0] = 22; buffer[1] = 1; buffer[2] = 0; buffer[3] = (byte)((_leftToRead >> 8) & 0xFF); buffer[4] = (byte)(_leftToRead & 0xFF); return(5); } if (count > _leftToRead) { throw new NpgsqlException($"NegotiateStream trying to read {count} bytes but according to frame header we only have {_leftToRead} left!"); } count = Math.Min(count, _leftToRead); Array.Copy(_readBuf, _readPos, buffer, offset, count); _leftToRead -= count; return(count); }
void ReadHeader() { _leftToReadInDataMsg = _connector.ReadExpecting <CopyDataMessage>().Length; var headerLen = NpgsqlRawCopyStream.BinarySignature.Length + 4 + 4; _buf.Ensure(headerLen); if (NpgsqlRawCopyStream.BinarySignature.Any(t => _buf.ReadByte() != t)) { throw new NpgsqlException("Invalid COPY binary signature at beginning!"); } var flags = _buf.ReadInt32(); if (flags != 0) { throw new NotSupportedException("Unsupported flags in COPY operation (OID inclusion?)"); } _buf.ReadInt32(); // Header extensions, currently unused _leftToReadInDataMsg -= headerLen; }