private Func <CancellationToken, Task <string> > GetJsonData(PostgresqlStreamId streamId, int version) => async cancellationToken => { using (var connection = await OpenConnection(cancellationToken)) using (var transaction = connection.BeginTransaction()) using (var command = BuildFunctionCommand( _schema.ReadJsonData, transaction, Parameters.StreamId(streamId), Parameters.Version(version))) using (var reader = await command .ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken) .NotOnCapturedContext()) { if (!await reader.ReadAsync(cancellationToken).NotOnCapturedContext() || reader.IsDBNull(0)) { return(null); } using (var textReader = reader.GetTextReader(0)) { return(await textReader.ReadToEndAsync().NotOnCapturedContext()); } } };
private async Task DeleteStreamInternal( PostgresqlStreamId streamId, int expectedVersion, IDbTransaction transaction, CancellationToken cancellationToken) { using (var command = BuildFunctionCommand( _schema.DeleteStream, transaction, Parameters.StreamId(streamId), Parameters.ExpectedVersion(expectedVersion), Parameters.CreatedUtc(_settings.GetUtcNow?.Invoke()), Parameters.DeletionTrackingDisabled(_settings.DisableDeletionTracking), _settings.DisableDeletionTracking ? Parameters.Empty() : Parameters.DeletedStreamId, _settings.DisableDeletionTracking ? Parameters.Empty() : Parameters.DeletedStreamIdOriginal, _settings.DisableDeletionTracking ? Parameters.Empty() : Parameters.DeletedStreamMessage(streamId))) { try { await command.ExecuteNonQueryAsync(cancellationToken).NotOnCapturedContext(); } catch (PostgresException ex) when(ex.IsWrongExpectedVersion()) { await transaction.RollbackAsync(cancellationToken).NotOnCapturedContext(); throw new WrongExpectedVersionException( ErrorMessages.DeleteStreamFailedWrongExpectedVersion(streamId.IdOriginal, expectedVersion), streamId.IdOriginal, expectedVersion, ex); } } }
public StreamIdInfo(string idOriginal) { Ensure.That(idOriginal, nameof(idOriginal)).IsNotNullOrWhiteSpace(); PostgresqlStreamId = new PostgresqlStreamId(idOriginal); MetadataPosgresqlStreamId = new PostgresqlStreamId("$$" + idOriginal); }
private Func <CancellationToken, Task <string> > GetJsonData(PostgresqlStreamId streamId, int version) => async cancellationToken => { using (var connection = await OpenConnection(cancellationToken)) using (var transaction = connection.BeginTransaction()) using (var command = BuildFunctionCommand( _schema.ReadJsonData, transaction, Parameters.StreamId(streamId), Parameters.Version(version))) { var jsonData = await command.ExecuteScalarAsync(cancellationToken).NotOnCapturedContext(); return(jsonData == DBNull.Value ? null : (string)jsonData); } };
private async Task <ReadStreamPage> ReadStreamInternal( PostgresqlStreamId streamId, int start, int count, ReadDirection direction, bool prefetch, ReadNextStreamPage readNext, NpgsqlTransaction transaction, CancellationToken cancellationToken) { // If the count is int.MaxValue, TSql will see it as a negative number. // Users shouldn't be using int.MaxValue in the first place anyway. count = count == int.MaxValue ? count - 1 : count; // To read backwards from end, need to use int MaxValue var streamVersion = start == StreamVersion.End ? int.MaxValue : start; var messages = new List <(StreamMessage message, int?maxAge)>(); Func <List <StreamMessage>, int, int> getNextVersion; if (direction == ReadDirection.Forward) { getNextVersion = (events, lastVersion) => { if (events.Any()) { return(events.Last().StreamVersion + 1); } return(lastVersion + 1); }; } else { getNextVersion = (events, lastVersion) => { if (events.Any()) { return(events.Last().StreamVersion - 1); } return(-1); }; } var refcursorSql = new StringBuilder(); using (var command = BuildFunctionCommand( _schema.Read, transaction, Parameters.StreamId(streamId), Parameters.Count(count + 1), Parameters.Version(streamVersion), Parameters.ReadDirection(direction), Parameters.Prefetch(prefetch))) using (var reader = await command .ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken) .ConfigureAwait(false)) { while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false)) { refcursorSql.AppendLine(Schema.FetchAll(reader.GetString(0))); } } using (var command = new NpgsqlCommand(refcursorSql.ToString(), transaction.Connection, transaction)) using (var reader = await command .ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken) .ConfigureAwait(false)) { if (!reader.HasRows) { return(new ReadStreamPage( streamId.IdOriginal, PageReadStatus.StreamNotFound, start, -1, -1, -1, direction, true, readNext)); } if (messages.Count == count) { messages.Add(default);