示例#1
0
        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 void Handle(SubscriptionIsLive @event)
        {
            _catchupDisposeCallback.Dispose();
            _isLive = true;

            _projector = new AsyncSqlProjector(_projection, new TransactionalSqlCommandExecutor(_settings, IsolationLevel.ReadCommitted));

            DispatchCommands();
        }
示例#3
0
        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();
        }
示例#4
0
            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 ProjacApprovalProcessorEventHandler(ConnectionStringSettings settings, IServiceBus bus)
        {
            _settings = settings;
            _bus      = bus;

            _queryExecutor = new SqlCommandExecutor(settings);

            _projection = ApprovalProcessorProjection.Instance.Concat(StoreCheckpointProjection.Instance);

            var connection = new SqlConnection(settings.ConnectionString);

            connection.Open();

            var projectionExecutor = new ConnectedSqlCommandExecutor(connection);

            _catchupDisposeCallback = new DisposeCallback(() =>
            {
                connection.Close();
                connection.Dispose();
            });

            _projector = new AsyncSqlProjector(_projection, projectionExecutor);
        }
示例#6
0
        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);
                }
            }
        }
示例#7
0
        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);
        }