private DocumentStore InitStore(TenancyStyle tenancyStyle, bool cleanSchema = true, bool useAppendEventForUpdateLock = false) { var databaseSchema = $"end_to_end_event_capture_{tenancyStyle.ToString().ToLower()}"; var store = StoreOptions(_ => { _.Events.DatabaseSchemaName = databaseSchema; _.Events.TenancyStyle = tenancyStyle; _.Events.UseAppendEventForUpdateLock = useAppendEventForUpdateLock; _.AutoCreateSchemaObjects = AutoCreate.All; if (tenancyStyle == TenancyStyle.Conjoined) { _.Policies.AllDocumentsAreMultiTenanted(); } _.Connection(ConnectionSource.ConnectionString); _.Events.Projections.InlineSelfAggregate <QuestParty>(); _.Events.AddEventType(typeof(MembersJoined)); _.Events.AddEventType(typeof(MembersDeparted)); _.Events.AddEventType(typeof(QuestStarted)); }, cleanSchema); return(store); }
public void run_multiple_aggregates_sync(TenancyStyle tenancyStyle) { #region sample_registering-quest-party var store = DocumentStore.For(_ => { _.Connection(ConnectionSource.ConnectionString); _.Events.TenancyStyle = tenancyStyle; _.DatabaseSchemaName = "quest_sample"; if (tenancyStyle == TenancyStyle.Conjoined) { _.Schema.For <QuestParty>().MultiTenanted(); } // This is all you need to create the QuestParty projected // view _.Events.Projections.SelfAggregate <QuestParty>(); }); #endregion sample_registering-quest-party StoreOptions(_ => { _.AutoCreateSchemaObjects = AutoCreate.All; _.Events.Projections.SelfAggregate <QuestParty>(); _.Events.Projections.SelfAggregate <QuestMonsters>(); }); var streamId = theSession.Events .StartStream <QuestParty>(started, joined, slayed1, slayed2, joined2).Id; theSession.SaveChanges(); theSession.Load <QuestMonsters>(streamId).Monsters.ShouldHaveTheSameElementsAs("Troll", "Dragon"); theSession.Load <QuestParty>(streamId).Members .ShouldHaveTheSameElementsAs("Garion", "Polgara", "Belgarath", "Silk", "Barak"); }
public void assert_on_max_event_id_on_event_stream_append( DocumentTracking sessionType, TenancyStyle tenancyStyle, string[] tenants) { var store = InitStore(tenancyStyle); var id = Guid.NewGuid(); When.CalledForEach(tenants, (tenantId, index) => { var started = new QuestStarted(); using (var session = store.OpenSession(tenantId, sessionType)) { // SAMPLE: append-events-assert-on-eventid session.Events.StartStream <Quest>(id, started); session.SaveChanges(); var joined = new MembersJoined { Members = new[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; // Events are appended into the stream only if the maximum event id for the stream // would be 3 after the append operation. session.Events.Append(id, 3, joined, departed); session.SaveChanges(); // ENDSAMPLE } }).ShouldThrowIf( (tenancyStyle == TenancyStyle.Single && tenants.Length > 1) || (tenancyStyle == TenancyStyle.Conjoined && tenants.SequenceEqual(SameTenants)) ); }
public void append_to_events_a_second_time_with_same_tenant_id(TenancyStyle tenancyStyle) { InitStore(tenancyStyle); Guid stream = Guid.NewGuid(); using (var session = theStore.OpenSession("Green")) { session.Events.Append(stream, new MembersJoined(), new MembersJoined()); session.SaveChanges(); } using (var session = theStore.OpenSession("Green")) { session.Events.Append(stream, new MembersJoined(), new MembersJoined()); session.SaveChanges(); } using (var session = theStore.OpenSession("Green")) { var events = session.Events.FetchStream(stream); foreach (var @event in events) { @event.TenantId.ShouldBe("Green"); } } }
public Task capture_events_to_a_new_stream_and_fetch_the_events_back_async(TenancyStyle tenancyStyle, string[] tenants) { var store = InitStore(tenancyStyle); return(When.CalledForEachAsync(tenants, async(tenantId, index) => { using (var session = store.OpenSession(tenantId, DocumentTracking.None)) { #region sample_start-stream-with-aggregate-type var joined = new MembersJoined { Members = new[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; var id = session.Events.StartStream <Quest>(joined, departed).Id; await session.SaveChangesAsync(); #endregion var streamEvents = await session.Events.FetchStreamAsync(id); streamEvents.Count().ShouldBe(2); streamEvents.ElementAt(0).Data.ShouldBeOfType <MembersJoined>(); streamEvents.ElementAt(0).Version.ShouldBe(1); streamEvents.ElementAt(1).Data.ShouldBeOfType <MembersDeparted>(); streamEvents.ElementAt(1).Version.ShouldBe(2); streamEvents.Each(e => e.Timestamp.ShouldNotBe(default(DateTimeOffset))); } }).ShouldSucceedAsync()); }
public void patch_inside_inline_projection_does_not_error_during_savechanges(TenancyStyle tenancyStyle) { StoreOptions(_ => { _.AutoCreateSchemaObjects = AutoCreate.All; _.Events.TenancyStyle = tenancyStyle; _.Events.InlineProjections.Add(new QuestPatchTestProjection()); }); theStore.Schema.ApplyAllConfiguredChangesToDatabase(); var aggregateId = Guid.NewGuid(); var quest = new Quest { Id = aggregateId, }; var questStarted = new QuestStarted { Id = aggregateId, Name = "New Quest", }; theSession.Events.Append(aggregateId, quest, questStarted); theSession.SaveChanges(); theSession.Events.FetchStreamState(aggregateId).Version.ShouldBe(2); }
capture_events_to_a_new_stream_and_fetch_the_events_back_with_stream_id_provided_in_another_database_schema( TenancyStyle tenancyStyle, string[] tenants) { var store = InitStore(tenancyStyle); When.CalledForEach(tenants, (tenantId, index) => { using (var session = store.OpenSession(tenantId, DocumentTracking.None)) { var joined = new MembersJoined { Members = new[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; var id = Guid.NewGuid(); session.Events.StartStream <Quest>(id, joined, departed); session.SaveChanges(); var streamEvents = session.Events.FetchStream(id); streamEvents.Count().ShouldBe(2); streamEvents.ElementAt(0).Data.ShouldBeOfType <MembersJoined>(); streamEvents.ElementAt(0).Version.ShouldBe(1); streamEvents.ElementAt(1).Data.ShouldBeOfType <MembersDeparted>(); streamEvents.ElementAt(1).Version.ShouldBe(2); streamEvents.Each(x => SpecificationExtensions.ShouldBeGreaterThan(x.Sequence, 0L)); } }).ShouldSucceed(); }
public void from_projection(TenancyStyle tenancyStyle) { var logger = new Logger(); // SAMPLE: viewprojection-from-class-with-injection-configuration StoreOptions(_ => { _.AutoCreateSchemaObjects = AutoCreate.All; _.Events.TenancyStyle = tenancyStyle; _.Events.InlineProjections.AggregateStreamsWith <QuestParty>(); _.Events.InlineProjections.Add(() => new PersistViewProjectionWithInjection(logger)); }); // ENDSAMPLE theSession.Events.StartStream <QuestParty>(streamId, started, joined); theSession.SaveChanges(); var document = theSession.Load <PersistedView>(streamId); document.Events.Count.ShouldBe(2); logger.Logs.Count.ShouldBe(0); //check injection theSession.Events.Append(streamId, paused); theSession.SaveChanges(); var document2 = theSession.Load <PersistedView>(streamId); document2.Events.Count.ShouldBe(3); logger.Logs.Count.ShouldBe(1); }
public void query_before_saving(TenancyStyle tenancyStyle, string[] tenants) { var store = InitStore(tenancyStyle); var questId = Guid.NewGuid(); When.CalledForEach(tenants, (tenantId, index) => { using (var session = store.OpenSession(tenantId, DocumentTracking.None)) { var parties = session.Query <QuestParty>().ToArray(); parties.Length.ShouldBeLessThanOrEqualTo(index); } //This SaveChanges will fail with missing method (ro collection configured?) using (var session = store.OpenSession(tenantId, DocumentTracking.None)) { var started = new QuestStarted { Name = "Destroy the One Ring" }; var joined1 = new MembersJoined(1, "Hobbiton", "Frodo", "Merry"); session.Events.StartStream <Quest>(questId, started, joined1); session.SaveChanges(); var party = session.Events.AggregateStream <QuestParty>(questId); party.Id.ShouldBe(questId); } }).ShouldThrowIf( (tenancyStyle == TenancyStyle.Single && tenants.Length > 1) || (tenancyStyle == TenancyStyle.Conjoined && tenants.SequenceEqual(SameTenants)) ); }
public void capture_events_to_a_new_stream_and_fetch_the_events_back_with_stream_id_provided( TenancyStyle tenancyStyle, string[] tenants) { var store = InitStore(tenancyStyle); When.CalledForEach(tenants, (tenantId, index) => { using (var session = store.OpenSession(tenantId, DocumentTracking.None)) { #region sample_start-stream-with-existing-guid var joined = new MembersJoined { Members = new[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; var id = Guid.NewGuid(); session.Events.StartStream <Quest>(id, joined, departed); session.SaveChanges(); #endregion var streamEvents = session.Events.FetchStream(id); streamEvents.Count().ShouldBe(2); streamEvents.ElementAt(0).Data.ShouldBeOfType <MembersJoined>(); streamEvents.ElementAt(0).Version.ShouldBe(1); streamEvents.ElementAt(1).Data.ShouldBeOfType <MembersDeparted>(); streamEvents.ElementAt(1).Version.ShouldBe(2); } }).ShouldSucceed(); }
public void live_aggregate_equals_inlined_aggregate_without_hidden_contracts(TenancyStyle tenancyStyle, string[] tenants) { var store = InitStore(tenancyStyle); var questId = Guid.NewGuid(); When.CalledForEach(tenants, (tenantId, index) => { using (var session = store.OpenSession(tenantId, DocumentTracking.None)) { //Note Id = questId, is we remove it from first message then AggregateStream will return party.Id=default(Guid) that is not equals to Load<QuestParty> result var started = new QuestStarted { /*Id = questId,*/ Name = "Destroy the One Ring" }; var joined1 = new MembersJoined(1, "Hobbiton", "Frodo", "Merry"); session.Events.StartStream <Quest>(questId, started, joined1); session.SaveChanges(); } using (var session = store.OpenSession(tenantId, DocumentTracking.None)) { var liveAggregate = session.Events.AggregateStream <QuestParty>(questId); var inlinedAggregate = session.Load <QuestParty>(questId); liveAggregate.Id.ShouldBe(inlinedAggregate.Id); inlinedAggregate.ToString().ShouldBe(liveAggregate.ToString()); } }).ShouldThrowIf( (tenancyStyle == TenancyStyle.Single && tenants.Length > 1) || (tenancyStyle == TenancyStyle.Conjoined && tenants.SequenceEqual(SameTenants)) ); }
public async Task Build_Projection_From_Stream(TenancyStyle tenancyStyle) { StoreOptions(_ => { _.Events.AsyncProjections.Add(new Projections.OrderProjection()); _.Events.TenancyStyle = tenancyStyle; }); var daemon = theStore.BuildProjectionDaemon(logger: new DebugDaemonLogger()); daemon.StartAll(); await PublishEvents(); await daemon.WaitForNonStaleResults(); using (var session = theStore.OpenSession()) { var order1 = session.Load <ReadModels.Order>(Order1Id); var order2 = session.Load <ReadModels.Order>(Order2Id); var order3 = session.Load <ReadModels.Order>(Order3Id); order1.CompanyName.ShouldBe("Mexico Railways"); order2.CompanyName.ShouldBe("Mexico Railways"); order3.CompanyName.ShouldBe("Microsoft"); } }
public void run_multiple_aggregates_sync(TenancyStyle tenancyStyle) { // SAMPLE: registering-quest-party var store = DocumentStore.For(_ => { _.Connection(ConnectionSource.ConnectionString); _.Events.TenancyStyle = tenancyStyle; // This is all you need to create the QuestParty projected // view _.Events.InlineProjections.AggregateStreamsWith <QuestParty>(); }); // ENDSAMPLE StoreOptions(_ => { _.AutoCreateSchemaObjects = AutoCreate.All; _.Events.InlineProjections.AggregateStreamsWith <QuestParty>(); _.Events.InlineProjections.AggregateStreamsWith <QuestMonsters>(); }); var streamId = theSession.Events .StartStream <QuestParty>(started, joined, slayed1, slayed2, joined2).Id; theSession.SaveChanges(); theSession.Load <QuestMonsters>(streamId).Monsters.ShouldHaveTheSameElementsAs("Troll", "Dragon"); theSession.Load <QuestParty>(streamId).Members .ShouldHaveTheSameElementsAs("Garion", "Polgara", "Belgarath", "Silk", "Barak"); }
public DeleteWhere(Type documentType, string sql, IWhereFragment @where, TenancyStyle tenancyStyle) { _where = @where; _tenancyStyle = tenancyStyle; DocumentType = documentType; Sql = sql; }
private DocumentStore InitStore(TenancyStyle tenancyStyle, bool cleanSchema = true, bool useAppendEventForUpdateLock = false) { var store = StoreOptions(_ => { _.Events.TenancyStyle = tenancyStyle; _.AutoCreateSchemaObjects = AutoCreate.All; if (tenancyStyle == TenancyStyle.Conjoined) { _.Policies.AllDocumentsAreMultiTenanted(); } _.Connection(ConnectionSource.ConnectionString); _.Projections.SelfAggregate <QuestParty>(); _.Events.AddEventType(typeof(MembersJoined)); _.Events.AddEventType(typeof(MembersDeparted)); _.Events.AddEventType(typeof(QuestStarted)); }, cleanSchema); return(store); }
private static DocumentStore InitStore(TenancyStyle tenancyStyle, bool cleanShema = true, bool useAppendEventForUpdateLock = false) { var databaseSchema = $"end_to_end_event_capture_{tenancyStyle.ToString().ToLower()}"; var store = DocumentStore.For(_ => { _.Events.DatabaseSchemaName = databaseSchema; _.Events.TenancyStyle = tenancyStyle; _.Events.UseAppendEventForUpdateLock = useAppendEventForUpdateLock; _.AutoCreateSchemaObjects = AutoCreate.All; if (tenancyStyle == TenancyStyle.Conjoined) { _.Policies.AllDocumentsAreMultiTenanted(); } _.Connection(ConnectionSource.ConnectionString); _.Events.InlineProjections.AggregateStreamsWith <QuestParty>(); _.Events.AddEventType(typeof(MembersJoined)); _.Events.AddEventType(typeof(MembersDeparted)); _.Events.AddEventType(typeof(QuestStarted)); }); if (cleanShema) { store.Advanced.Clean.CompletelyRemoveAll(); } return(store); }
public void sync_projection_of_events(TenancyStyle tenancyStyle) { StoreOptions(_ => { _.AutoCreateSchemaObjects = AutoCreate.All; _.Events.TenancyStyle = tenancyStyle; _.Events.InlineProjections.TransformEvents(new MonsterDefeatedTransform()); }); var streamId = theSession.Events .StartStream <QuestParty>(started, joined, slayed1, slayed2, joined2).Id; theSession.SaveChanges(); var monsterEvents = theSession.Events.FetchStream(streamId).OfType <Event <MonsterSlayed> >().ToArray(); monsterEvents.Length.ShouldBe(2); // precondition monsterEvents.Each(e => { var doc = theSession.Load <MonsterDefeated>(e.Id); doc.Monster.ShouldBe(e.Data.Name); }); }
public void capture_immutable_events(DocumentTracking sessionType, TenancyStyle tenancyStyle, string[] tenants) { var store = InitStore(tenancyStyle); var id = Guid.NewGuid(); When.CalledForEach(tenants, (tenantId, index) => { var immutableEvent = new ImmutableEvent(id, "some-name"); using (var session = store.OpenSession(tenantId, sessionType)) { session.Events.Append(id, immutableEvent); session.SaveChanges(); } using (var session = store.OpenSession(tenantId, sessionType)) { var streamEvents = session.Events.FetchStream(id); streamEvents.Count.ShouldBe(1); var @event = streamEvents.ElementAt(0).Data.ShouldBeOfType <ImmutableEvent>(); @event.Id.ShouldBe(id); @event.Name.ShouldBe("some-name"); } }).ShouldThrowIf( (tenancyStyle == TenancyStyle.Single && tenants.Length > 1) || (tenancyStyle == TenancyStyle.Conjoined && tenants.SequenceEqual(SameTenants)) ); }
public EntityMetadataQueryHandler(TenancyStyle tenancyStyle, object entity, IDocumentStorage storage, IDocumentMapping mapping) { _id = storage.Identity(entity); _tenancyStyle = tenancyStyle; _storage = storage; _mapping = mapping; var fieldIndex = 0; _fields = new Dictionary <string, int> { { DocumentMapping.VersionColumn, fieldIndex++ }, { DocumentMapping.LastModifiedColumn, fieldIndex++ }, { DocumentMapping.DotNetTypeColumn, fieldIndex++ } }; var queryableDocument = _mapping.ToQueryableDocument(); if (queryableDocument.SelectFields().Contains(DocumentMapping.DocumentTypeColumn)) { _fields.Add(DocumentMapping.DocumentTypeColumn, fieldIndex++); } if (queryableDocument.DeleteStyle == DeleteStyle.SoftDelete) { _fields.Add(DocumentMapping.DeletedColumn, fieldIndex++); _fields.Add(DocumentMapping.DeletedAtColumn, fieldIndex++); } if (tenancyStyle == TenancyStyle.Conjoined) { _fields.Add(TenantIdColumn.Name, fieldIndex); } }
public void capture_events_to_a_non_existing_stream_and_fetch_the_events_back_in_another_database_schema( DocumentTracking sessionType, TenancyStyle tenancyStyle, string[] tenants) { var store = InitStore(tenancyStyle); When.CalledForEach(tenants, (tenantId, index) => { using (var session = store.OpenSession(tenantId, sessionType)) { var joined = new MembersJoined { Members = new[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; var id = Guid.NewGuid(); session.Events.StartStream <Quest>(id, joined); session.Events.Append(id, departed); session.SaveChanges(); var streamEvents = session.Events.FetchStream(id); streamEvents.Count().ShouldBe(2); streamEvents.ElementAt(0).Data.ShouldBeOfType <MembersJoined>(); streamEvents.ElementAt(0).Version.ShouldBe(1); streamEvents.ElementAt(1).Data.ShouldBeOfType <MembersDeparted>(); streamEvents.ElementAt(1).Version.ShouldBe(2); } }).ShouldSucceed(); }
public void AdditiveFilters( [Header("User Supplied Where"), SelectionValues("x => x.UserName == \"Aubrey\"", "x => x.MaybeDeleted()")] string baseWhere, [Header("Soft Deleted")] bool softDeleted, [Header("Tenancy")] TenancyStyle tenancy, [Header("User")] out string user, [Header("AdminUser")] out string subclass ) { var store = buildStore(softDeleted, tenancy); using (var session = store.QuerySession()) { IQueryable <User> userQuery = null; IQueryable <AdminUser> adminQuery = null; if (baseWhere == "x => x.UserName == \"Aubrey\"") { userQuery = session.Query <User>().Where(x => x.UserName == "Aubrey"); adminQuery = session.Query <AdminUser>().Where(x => x.UserName == "Aubrey"); } else { userQuery = session.Query <User>().Where(x => x.MaybeDeleted()); adminQuery = session.Query <AdminUser>().Where(x => x.MaybeDeleted()); } var userCommand = userQuery.ToCommand(); var adminCommand = adminQuery.ToCommand(); user = extractWhereClause(userCommand); subclass = extractWhereClause(adminCommand); } }
public Task aggregate_stream_async_has_the_id(DocumentTracking sessionType, TenancyStyle tenancyStyle, string[] tenants) { var store = InitStore(tenancyStyle); var questId = Guid.NewGuid(); return(When.CalledForEachAsync(tenants, async(tenantId, index) => { using (var session = store.OpenSession(tenantId, sessionType)) { var parties = await session.Query <QuestParty>().ToListAsync(); parties.Count.ShouldBeLessThanOrEqualTo(index); } //This SaveChanges will fail with missing method (ro collection configured?) using (var session = store.OpenSession(tenantId, sessionType)) { var started = new QuestStarted { Name = "Destroy the One Ring" }; var joined1 = new MembersJoined(1, "Hobbiton", "Frodo", "Merry"); session.Events.StartStream <Quest>(questId, started, joined1); await session.SaveChangesAsync(); var party = await session.Events.AggregateStreamAsync <QuestParty>(questId); party.Id.ShouldBe(questId); } }).ShouldThrowIfAsync( (tenancyStyle == TenancyStyle.Single && tenants.Length > 1) || (tenancyStyle == TenancyStyle.Conjoined && tenants.SequenceEqual(SameTenants)) )); }
public DeleteById(TenancyStyle tenancyStyle, string sql, IDocumentStorage storage, object id, object document = null) { Sql = sql; _tenancyStyle = tenancyStyle; _storage = storage; Id = id ?? throw new ArgumentNullException(nameof(id)); Document = document; }
private void InitStore(TenancyStyle tenancyStyle, StreamIdentity streamIdentity = StreamIdentity.AsGuid) { StoreOptions(_ => { _.Events.TenancyStyle = tenancyStyle; _.Events.StreamIdentity = streamIdentity; _.Policies.AllDocumentsAreMultiTenanted(); }, true); }
public NpgsqlCommand LoadByArrayCommand <TKey>(TenancyStyle tenancyStyle, TKey[] ids) { var sql = _loadArraySql; if (tenancyStyle == TenancyStyle.Conjoined) { sql += $" and {TenantIdColumn.Name} = :{TenantIdArgument.ArgName}"; } return(new NpgsqlCommand(sql).With("ids", ids)); }
private void InitStore(TenancyStyle tenancyStyle, StreamIdentity streamIdentity = StreamIdentity.AsGuid) { var databaseSchema = $"{GetType().Name}_{tenancyStyle.ToString().ToLower()}"; StoreOptions(_ => { _.Events.DatabaseSchemaName = databaseSchema; _.Events.TenancyStyle = tenancyStyle; _.Events.StreamIdentity = streamIdentity; _.Policies.AllDocumentsAreMultiTenanted(); }); }
public void FiltersAre( [Header("Soft Deleted")] bool softDeleted, [Header("Tenancy")] TenancyStyle tenancy, [Header("User")] out string user, [Header("AdminUser")] out string subclass) { var store = buildStore(softDeleted, tenancy); user = store.Storage.MappingFor(typeof(User)).DefaultWhereFragment().ToSql(); subclass = store .Tenancy.Default.MappingFor(typeof(AdminUser)).As <IQueryableDocument>() .DefaultWhereFragment().ToSql(); }
private void InitStore(TenancyStyle tenancyStyle, StreamIdentity streamIdentity = StreamIdentity.AsGuid) { var databaseSchema = $"{GetType().Name}_{tenancyStyle.ToString().ToLower()}_{streamIdentity}"; using var conn = new NpgsqlConnection(ConnectionSource.ConnectionString); conn.Open(); conn.DropSchema(databaseSchema).GetAwaiter().GetResult(); StoreOptions(_ => { _.Events.DatabaseSchemaName = databaseSchema; _.Events.TenancyStyle = tenancyStyle; _.Events.StreamIdentity = streamIdentity; _.Policies.AllDocumentsAreMultiTenanted(); }); }
public void capture_events_to_an_existing_stream_and_fetch_the_events_back_in_another_database_schema( DocumentTracking sessionType, TenancyStyle tenancyStyle, string[] tenants) { var store = InitStore(tenancyStyle); var id = Guid.NewGuid(); When.CalledForEach(tenants, (tenantId, index) => { var started = new QuestStarted(); using (var session = store.OpenSession(tenantId, sessionType)) { session.Events.StartStream <Quest>(id, started); session.SaveChanges(); } using (var session = store.OpenSession(tenantId, sessionType)) { // SAMPLE: append-events var joined = new MembersJoined { Members = new[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; session.Events.Append(id, joined, departed); session.SaveChanges(); // ENDSAMPLE var streamEvents = session.Events.FetchStream(id); streamEvents.Count().ShouldBe(3); streamEvents.ElementAt(0).Data.ShouldBeOfType <QuestStarted>(); streamEvents.ElementAt(0).Version.ShouldBe(1); streamEvents.ElementAt(1).Data.ShouldBeOfType <MembersJoined>(); streamEvents.ElementAt(1).Version.ShouldBe(2); streamEvents.ElementAt(2).Data.ShouldBeOfType <MembersDeparted>(); streamEvents.ElementAt(2).Version.ShouldBe(3); } }).ShouldThrowIf( (tenancyStyle == TenancyStyle.Single && tenants.Length > 1) || (tenancyStyle == TenancyStyle.Conjoined && tenants.SequenceEqual(SameTenants)) ); }
public EventQueryHandler(ISelector <IEvent> selector, TIdentity streamId, int version = 0, DateTime?timestamp = null, TenancyStyle tenancyStyle = TenancyStyle.Single, string tenantId = null) { if (timestamp != null && timestamp.Value.Kind != DateTimeKind.Utc) { throw new ArgumentOutOfRangeException(nameof(timestamp), "This method only accepts UTC dates"); } if (_tenancyStyle == TenancyStyle.Conjoined && tenantId == null) { throw new ArgumentNullException(nameof(tenantId), $"{nameof(tenantId)} cannot be null for {TenancyStyle.Conjoined}"); } _selector = selector; _streamId = streamId; _version = version; _timestamp = timestamp; _tenancyStyle = tenancyStyle; _tenantId = tenantId; }