public Task CommitAsync(CancellationToken cancellationToken = default) #endif { if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled(cancellationToken)); } using (NoSynchronizationContextScope.Enter()) return(Commit(true)); }
public override ValueTask <int> ReadAsync(Memory <byte> buffer, CancellationToken cancellationToken = default) #endif { CheckDisposed(); var count = Math.Min(buffer.Length, _len - _read); if (count == 0) { return(new ValueTask <int>(0)); } using (NoSynchronizationContextScope.Enter()) return(ReadLong(this, buffer.Slice(0, count), cancellationToken));
public ValueTask WriteAsync(ReadOnlyMemory <byte> buffer, CancellationToken cancellationToken = default) #endif { CheckDisposed(); if (!CanWrite) { throw new InvalidOperationException("Stream not open for writing"); } cancellationToken.ThrowIfCancellationRequested(); using (NoSynchronizationContextScope.Enter()) return(WriteAsyncInternal()); async ValueTask WriteAsyncInternal() { if (buffer.Length == 0) { return; } if (buffer.Length <= _writeBuf.WriteSpaceLeft) { _writeBuf.WriteBytes(buffer.Span); return; } try { // Value is too big, flush. await FlushAsync(true, cancellationToken); if (buffer.Length <= _writeBuf.WriteSpaceLeft) { _writeBuf.WriteBytes(buffer.Span); return; } // Value is too big even after a flush - bypass the buffer and write directly. await _writeBuf.DirectWrite(buffer, true, cancellationToken); } catch (Exception e) { _connector.Break(e); Cleanup(); throw; } } }
/// <summary> /// Disposes the transaction, rolling it back if it is still pending. /// </summary> public override async ValueTask DisposeAsync() { if (_isDisposed) { return; } if (!IsCompleted) { using (NoSynchronizationContextScope.Enter()) { await _connector.CloseOngoingOperations(async : true); await Rollback(async : true); } } _isDisposed = true; }
public ValueTask <int> ReadAsync(Memory <byte> buffer, CancellationToken cancellationToken = default) #endif { CheckDisposed(); if (cancellationToken.IsCancellationRequested) { return(new ValueTask <int>(Task.FromCanceled <int>(cancellationToken))); } var count = Math.Min(buffer.Length, _len - _read); if (count == 0) { return(new ValueTask <int>(0)); } using (NoSynchronizationContextScope.Enter()) return(ReadLong(buffer.Slice(0, count), cancellationToken)); async ValueTask <int> ReadLong(Memory <byte> buffer, CancellationToken cancellationToken = default)
public ValueTask <int> ReadAsync(Memory <byte> buffer, CancellationToken cancellationToken) #endif { CheckDisposed(); if (!CanRead) { throw new InvalidOperationException("Stream not open for reading"); } cancellationToken.ThrowIfCancellationRequested(); using (NoSynchronizationContextScope.Enter()) return(ReadAsyncInternal()); async ValueTask <int> ReadAsyncInternal() { var count = await ReadCore(buffer.Length, true, cancellationToken); if (count > 0) { _readBuf.ReadBytes(buffer.Slice(0, count).Span); } return(count); } }
/// <summary> /// Deletes a large object on the backend. /// </summary> /// <param name="oid">Oid of the object to delete</param> /// <param name="cancellationToken">Cancellation token.</param> public Task UnlinkAsync(uint oid, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using (NoSynchronizationContextScope.Enter()) return(ExecuteFunction <object>("lo_unlink", true, (int)oid)); }
/// <summary> /// Opens a large object on the backend, returning a stream controlling this remote object. /// Note that this method, as well as operations on the stream must be wrapped inside a transaction. /// </summary> /// <param name="oid">Oid of the object</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns>An NpgsqlLargeObjectStream</returns> public Task <NpgsqlLargeObjectStream> OpenReadWriteAsync(uint oid, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using (NoSynchronizationContextScope.Enter()) return(OpenReadWrite(oid, true)); }
public Task RollbackAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using (NoSynchronizationContextScope.Enter()) return(Rollback(true)); }
/// <summary> /// Reads <i>count</i> bytes from the large object. The only case when fewer bytes are read is when end of stream is reached. /// </summary> /// <param name="buffer">The buffer where read data should be stored.</param> /// <param name="offset">The offset in the buffer where the first byte should be read.</param> /// <param name="count">The maximum number of bytes that should be read.</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns>How many bytes actually read, or 0 if end of file was already reached.</returns> public override async Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using (NoSynchronizationContextScope.Enter()) return(await Read(buffer, offset, count, true)); }
/// <summary> /// Writes <i>count</i> bytes to the large object. /// </summary> /// <param name="buffer">The buffer to write data from.</param> /// <param name="offset">The offset in the buffer at which to begin copying bytes.</param> /// <param name="count">The number of bytes to write.</param> /// <param name="cancellationToken">Cancellation token.</param> public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using (NoSynchronizationContextScope.Enter()) await Write(buffer, offset, count, true); }
/// <summary> /// Exports a large object stored in the database to a file on the backend. This requires superuser permissions. /// </summary> /// <param name="oid">Oid of the object to export</param> /// <param name="path">Path to write the file on the backend</param> /// <param name="cancellationToken">Cancellation token.</param> public async Task ExportRemoteAsync(uint oid, string path, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using (NoSynchronizationContextScope.Enter()) await ExecuteFunction <object>("lo_export", true, (int)oid, path); }
public override Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { using (NoSynchronizationContextScope.Enter()) return(Read(buffer, offset, count, cancellationToken, true).AsTask()); }
/// <summary> /// Async cancels that binary import and sets the connection back to idle state /// </summary> /// <returns></returns> public ValueTask DisposeAsync() { using (NoSynchronizationContextScope.Enter()) return(CloseAsync(true)); }
/// <summary> /// Imports a large object to be stored as a large object in the database from a file stored on the backend. This requires superuser permissions. /// </summary> /// <param name="path">Path to read the file on the backend</param> /// <param name="oid">A preferred oid, or specify 0 if one should be automatically assigned</param> /// <param name="cancellationToken"> /// An optional token to cancel the asynchronous operation. The default value is <see cref="CancellationToken.None"/>. /// </param> public Task ImportRemoteAsync(string path, uint oid, CancellationToken cancellationToken = default) { using (NoSynchronizationContextScope.Enter()) return(ExecuteFunction <object>("lo_import", true, cancellationToken, path, (int)oid)); }
/// <summary> /// Deletes a large object on the backend. /// </summary> /// <param name="oid">Oid of the object to delete</param> /// <param name="cancellationToken"> /// An optional token to cancel the asynchronous operation. The default value is <see cref="CancellationToken.None"/>. /// </param> public Task UnlinkAsync(uint oid, CancellationToken cancellationToken = default) { using (NoSynchronizationContextScope.Enter()) return(ExecuteFunction <object>("lo_unlink", true, cancellationToken, (int)oid)); }
/// <summary> /// Opens a large object on the backend, returning a stream controlling this remote object. /// Note that this method, as well as operations on the stream must be wrapped inside a transaction. /// </summary> /// <param name="oid">Oid of the object</param> /// <param name="cancellationToken"> /// An optional token to cancel the asynchronous operation. The default value is <see cref="CancellationToken.None"/>. /// </param> /// <returns>An NpgsqlLargeObjectStream</returns> public Task <NpgsqlLargeObjectStream> OpenReadWriteAsync(uint oid, CancellationToken cancellationToken = default) { using (NoSynchronizationContextScope.Enter()) return(OpenReadWrite(oid, true, cancellationToken)); }
/// <summary> /// Writes <i>count</i> bytes to the large object. /// </summary> /// <param name="buffer">The buffer to write data from.</param> /// <param name="offset">The offset in the buffer at which to begin copying bytes.</param> /// <param name="count">The number of bytes to write.</param> /// <param name="cancellationToken"> /// An optional token to cancel the asynchronous operation. The default value is <see cref="CancellationToken.None"/>. /// </param> public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { using (NoSynchronizationContextScope.Enter()) return(Write(buffer, offset, count, true, cancellationToken)); }
/// <summary> /// Imports a large object to be stored as a large object in the database from a file stored on the backend. This requires superuser permissions. /// </summary> /// <param name="path">Path to read the file on the backend</param> /// <param name="oid">A preferred oid, or specify 0 if one should be automatically assigned</param> /// <param name="cancellationToken">Cancellation token.</param> public Task ImportRemoteAsync(string path, uint oid, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using (NoSynchronizationContextScope.Enter()) return(ExecuteFunction <object>("lo_import", true, path, (int)oid)); }
/// <summary> /// Reads the current column, returns its value according to <paramref name="type"/> and /// moves ahead to the next column. /// If the column is null an exception is thrown. /// </summary> /// <param name="type"> /// In some cases <typeparamref name="T"/> isn't enough to infer the data type coming in from the /// database. This parameter can be used to unambiguously specify the type. An example is the JSONB /// type, for which <typeparamref name="T"/> will be a simple string but for which /// <paramref name="type"/> must be specified as <see cref="NpgsqlDbType.Jsonb"/>. /// </param> /// <param name="cancellationToken"> /// An optional token to cancel the asynchronous operation. The default value is <see cref="CancellationToken.None"/>. /// </param> /// <typeparam name="T">The .NET type of the column to be read.</typeparam> /// <returns>The value of the column</returns> public ValueTask <T> ReadAsync <T>(NpgsqlDbType type, CancellationToken cancellationToken = default) { using (NoSynchronizationContextScope.Enter()) return(Read <T>(type, true, cancellationToken)); }
public async Task RollbackAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using (NoSynchronizationContextScope.Enter()) await Rollback(true, cancellationToken); }
/// <summary> /// Cancels and terminates an ongoing operation. Any data already written will be discarded. /// </summary> public Task CancelAsync() { using (NoSynchronizationContextScope.Enter()) return(Cancel(true)); }
#pragma warning restore CA1721 /// <summary> /// Gets the length of the large object. This internally seeks to the end of the stream to retrieve the length, and then back again. /// </summary> public async Task <long> GetLengthAsync() { using (NoSynchronizationContextScope.Enter()) return(await GetLength(true)); }
/// <summary> /// Starts reading a single row, must be invoked before reading any columns. /// </summary> /// <returns> /// The number of columns in the row. -1 if there are no further rows. /// Note: This will currently be the same value for all rows, but this may change in the future. /// </returns> public ValueTask <int> StartRowAsync(CancellationToken cancellationToken = default) { using (NoSynchronizationContextScope.Enter()) return(StartRow(true, cancellationToken)); }
/// <summary> /// Seeks in the stream to the specified position. This requires a round-trip to the backend. /// </summary> /// <param name="offset">A byte offset relative to the <i>origin</i> parameter.</param> /// <param name="origin">A value of type SeekOrigin indicating the reference point used to obtain the new position.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns></returns> public async Task <long> SeekAsync(long offset, SeekOrigin origin, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using (NoSynchronizationContextScope.Enter()) return(await Seek(offset, origin, true)); }
public override Task <T> GetFieldValueAsync <T>(int ordinal, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using (NoSynchronizationContextScope.Enter()) return(GetFieldValue <T>(ordinal, true).AsTask()); }
/// <summary> /// Truncates or enlarges the large object to the given size. If enlarging, the large object is extended with null bytes. /// For PostgreSQL versions earlier than 9.3, the value must fit in an Int32. /// </summary> /// <param name="value">Number of bytes to either truncate or enlarge the large object.</param> /// <param name="cancellationToken">Cancellation token.</param> public async Task SetLength(long value, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using (NoSynchronizationContextScope.Enter()) await SetLength(value, true); }