public void Handle(Envelope <ApprovalInitiated> @event) { _projector.ProjectAsync(@event); DispatchCommands(); _projector.ProjectAsync(new SetCheckpoint(@event.Headers[Constants.TenantIdKey], @event.Headers[Constants.StreamCheckpointTokenKey])); }
public async Task ShowWithCatchupSubscription() { //setup a projection schema (one of many ways) var projector = new AsyncSqlProjector( Resolve.WhenEqualToHandlerMessageType(new PortfolioProjection()), new TransactionalSqlCommandExecutor( new ConnectionStringSettings( "projac", @"Data Source=(localdb)\ProjectsV12;Initial Catalog=ProjacUsage;Integrated Security=SSPI;", "System.Data.SqlClient"), IsolationLevel.ReadCommitted)); await projector.ProjectAsync(new object[] { new DropSchema(), new CreateSchema() }); //setup a memory eventstore var store = new InMemoryStreamStore(); //setup a sample stream (using some sample events) var portfolioId = Guid.NewGuid(); var events = new object[] { new PortfolioAdded { Id = portfolioId, Name = "My Portfolio" }, new PortfolioRenamed { Id = portfolioId, Name = "Your Portfolio" }, new PortfolioRemoved { Id = portfolioId } }; var stream = string.Format("portfolio-{0}", portfolioId.ToString("N")); await store.AppendToStream( stream, ExpectedVersion.Any, events .Select(@event => new NewStreamMessage( Guid.NewGuid(), @event.GetType().FullName, JsonConvert.SerializeObject(@event))) .ToArray()); //project the sample stream (until end of stream) var subscription = store.SubscribeToStream(stream, null, async(_, rawMessage, ct) => { var @event = JsonConvert.DeserializeObject( await rawMessage.GetJsonData(), Type.GetType(rawMessage.Type, true)); await projector.ProjectAsync(@event, ct); }); //should complete within 5 seconds. await Task.Delay(TimeSpan.FromSeconds(5)); subscription.Dispose(); }
public Task Show() { var builder = new SQLiteConnectionStringBuilder { BinaryGUID = true, DataSource = _databasePath, DateTimeFormat = SQLiteDateFormats.ISO8601, FailIfMissing = true, DateTimeKind = DateTimeKind.Utc, JournalMode = SQLiteJournalModeEnum.Wal, SyncMode = SynchronizationModes.Full }; var projector = new AsyncSqlProjector( Resolve.WhenEqualToHandlerMessageType(new PortfolioProjection()), new SQLiteExecutor(() => new SQLiteConnection(builder.ToString())) ); var portfolioId = Guid.NewGuid(); return(projector.ProjectAsync(new object[] { new CreateSchema(), new PortfolioAdded { Id = portfolioId, Name = "My portfolio" }, new PortfolioRenamed { Id = portfolioId, Name = "Your portfolio" }, new PortfolioRemoved { Id = portfolioId } })); }
public Task ProjectAsync(StreamSubscription subscription, ResolvedEvent e, CancellationToken cancellationToken) { if (!_messageTypeMapper.TryMap(e.Event.EventType, out var type)) { return(Task.CompletedTask); } var message = JsonSerializer.Deserialize(e.Event.Data.Span, type, TransactoSerializerOptions.Events) !; return(Task.WhenAll(_projectors.Where(projection => projection.Checkpoint < e.OriginalPosition) .Select(async projector => { await using var connection = _connectionFactory(); await connection.OpenAsync(cancellationToken); await using var transaction = await connection.BeginTransactionAsync(cancellationToken); var(projection, _) = projector; var sqlProjector = new AsyncSqlProjector(projector.Resolver, new ConnectedTransactionalSqlCommandExecutor(transaction)); await sqlProjector.ProjectAsync(message, cancellationToken); await projection.WriteCheckpoint(transaction, e.Event.Position, cancellationToken); await transaction.CommitAsync(cancellationToken); }))); }
public async Task ShowWithStream() { //setup a projection schema (one of many ways) var projector = new AsyncSqlProjector( Resolve.WhenEqualToHandlerMessageType(new PortfolioProjection()), new TransactionalSqlCommandExecutor( new ConnectionStringSettings( "projac", @"Data Source=(localdb)\ProjectsV12;Initial Catalog=ProjacUsage;Integrated Security=SSPI;", "System.Data.SqlClient"), IsolationLevel.ReadCommitted)); await projector.ProjectAsync(new object[] { new DropSchema(), new CreateSchema() }); //setup a memory eventstore var store = new InMemoryStreamStore(); //setup a sample stream (using some sample events) var portfolioId = Guid.NewGuid(); var events = new object[] { new PortfolioAdded { Id = portfolioId, Name = "My Portfolio" }, new PortfolioRenamed { Id = portfolioId, Name = "Your Portfolio" }, new PortfolioRemoved { Id = portfolioId } }; var stream = string.Format("portfolio-{0}", portfolioId.ToString("N")); await store.AppendToStream( stream, ExpectedVersion.Any, events .Select(@event => new NewStreamMessage( Guid.NewGuid(), @event.GetType().FullName, JsonConvert.SerializeObject(@event))) .ToArray()); //project the sample stream (until end of stream) var result = await store.ReadStreamForwards(stream, StreamVersion.Start, 1, true); foreach (var rawMessage in result.Messages) { var @event = JsonConvert.DeserializeObject( await rawMessage.GetJsonData(), Type.GetType(rawMessage.Type, true)); await projector.ProjectAsync(@event); } while (!result.IsEnd) { result = await store.ReadStreamForwards(stream, result.NextStreamVersion, 1, true); foreach (var rawMessage in result.Messages) { var @event = JsonConvert.DeserializeObject( await rawMessage.GetJsonData(), Type.GetType(rawMessage.Type, true)); await projector.ProjectAsync(@event); } } }
public static async Task Assert(this NpgsqlProjectionScenario scenario, NpgsqlConnectionStringBuilder connectionStringBuilder = null) { if (scenario == null) { throw new ArgumentNullException(nameof(scenario)); } connectionStringBuilder ??= new NpgsqlConnectionStringBuilder { Host = "localhost", Username = "******" }; await using var sqlConnection = new NpgsqlConnection(connectionStringBuilder.ConnectionString); await sqlConnection.OpenAsync(); var projector = new AsyncSqlProjector( scenario.Resolver, new ConnectedSqlCommandExecutor(sqlConnection)); var result = await scenario.Verify(async connection => { try { foreach (var schema in scenario.Schemas) { await using var createSchema = connection.CreateCommand(); createSchema.CommandText = $@"CREATE SCHEMA IF NOT EXISTS {schema}"; await createSchema.ExecuteNonQueryAsync(); } foreach (var message in scenario.Messages) { try { await projector.ProjectAsync(message); } catch { throw; } } var compare = new CompareLogic(new ComparisonConfig { IgnoreCollectionOrder = true, IgnoreObjectTypes = true }); var comparisonResults = new List <ComparisonResult>(); for (var i = 0; i < scenario.Tables.Length; i++) { var table = scenario.Tables[i]; var rows = new List <object>(); await using var command = connection.CreateCommand(); command.CommandText = $@"SELECT {string.Join(", ", Array.ConvertAll(table.ColumnNames, Inflector.Underscore))} FROM {table.Schema}.{table.TableName}"; command.CommandType = CommandType.Text; await using var reader = await command.ExecuteReaderAsync(); while (await reader.ReadAsync()) { rows.Add(reader.ToObject(table.Type)); } comparisonResults.Add(compare.Compare(table.Rows, rows.ToArray())); } return(comparisonResults.All(x => x.AreEqual) ? VerificationResult.Pass() : VerificationResult.Fail(comparisonResults .Aggregate(new StringBuilder("Expected stuff but got the following differences: "), (builder, comparisonResult) => builder.Append(comparisonResult.DifferencesString)) .ToString())); } finally { foreach (var schema in scenario.Schemas) { await using var createSchema = connection.CreateCommand(); createSchema.CommandText = $@"DROP SCHEMA IF EXISTS {schema} CASCADE"; await createSchema.ExecuteNonQueryAsync(); } } }).Verification(sqlConnection, CancellationToken.None); Xunit.Assert.True(result.Passed, result.Message); }