protected override Task fixtureSetup() { var joined = new MembersJoined { Members = new string[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; theStreamId = theSession.Events.StartStream <Quest>(joined, departed).Id; return(theSession.SaveChangesAsync()); }
public void isnew_on_start_stream_2() { var joined = new MembersJoined { Members = new string[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; theSession.Events.StartStream <Quest>(Guid.NewGuid(), joined, departed); theSession.PendingChanges.Streams().Single().ActionType.ShouldBe(StreamActionType.Start); }
public void should_be_existing_stream_on_append_event() { var joined = new MembersJoined { Members = new string[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; theSession.Events.Append(Guid.NewGuid(), joined, departed); theSession.PendingChanges.Streams().Single().ActionType .ShouldBe(StreamActionType.Append); }
public void capture_events_to_an_existing_stream_and_fetch_the_events_back_in_another_database_schema( 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, DocumentTracking.None)) { session.Events.StartStream <Quest>(id, started); session.SaveChanges(); } using (var session = store.OpenSession(tenantId, DocumentTracking.None)) { #region 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(); #endregion 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 void delete_stream_by_string_key_multi_tenanted() { StoreOptions(_ => { _.Events.StreamIdentity = StreamIdentity.AsString; _.Events.TenancyStyle = TenancyStyle.Conjoined; }); var stream1 = "one"; var stream2 = "two"; using (var session = theStore.LightweightSession("one")) { var joined = new MembersJoined { Members = new[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; session.Events.Append(stream1, joined, departed); var joined2 = new MembersJoined { Members = new[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed2 = new MembersDeparted { Members = new[] { "Thom" } }; session.Events.Append(stream2, joined2, departed2); session.SaveChanges(); } theStore.Advanced.Clean.DeleteSingleEventStream(stream1, "one"); using (var session = theStore.LightweightSession()) { session.Events.QueryAllRawEvents().ToList().All(x => x.StreamKey == stream2) .ShouldBeTrue(); } }
public void should_check_max_event_id_on_append() { var joined = new MembersJoined { Members = new string[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; var stream = theSession.Events.StartStream <Quest>(joined).Id; theSession.Events.Append(stream, 2, departed); theSession.SaveChanges(); var state = theSession.Events.FetchStreamState(stream); state.Id.ShouldBe(stream); state.Version.ShouldBe(2); }
public void should_not_append_events_when_unexpected_max_version_with_string_identifier() { UseStreamIdentity(StreamIdentity.AsString); var joined = new MembersJoined { Members = new string[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; var stream = "Another"; theSession.Events.Append(stream, joined); theSession.SaveChanges(); theSession.Events.Append(stream, 2, departed); using (var session = theStore.OpenSession()) { var joined3 = new MembersJoined { Members = new[] { "Egwene" } }; var departed3 = new MembersDeparted { Members = new[] { "Perrin" } }; session.Events.Append(stream, joined3, departed3); session.SaveChanges(); } Assert.Throws <EventStreamUnexpectedMaxEventIdException>(() => theSession.SaveChanges()); using (var session = theStore.OpenSession()) { var state = session.Events.FetchStreamState(stream); state.Key.ShouldBe(stream); state.Version.ShouldBe(3); } }
public void get_correct_events_from_single_stream() { var id = Guid.NewGuid(); var started = new QuestStarted(); using (var session = theStore.LightweightSession()) { session.Events.StartStream <Quest>(id, started); session.SaveChanges(); var events = listener.LastCommit .GetEvents() .ToList(); events.Count.ShouldBe(1); events.ElementAt(0).Data.ShouldBeOfType <QuestStarted>(); } using (var session = theStore.LightweightSession()) { var joined = new MembersJoined { Members = new string[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; session.Events.Append(id, joined, departed); session.SaveChanges(); var events = listener.LastCommit .GetEvents() .ToList(); events.Count.ShouldBe(2); events.ElementAt(0).Data.ShouldBeOfType <MembersJoined>(); events.ElementAt(1).Data.ShouldBeOfType <MembersDeparted>(); } }
public void assert_on_max_event_id_on_event_stream_append() { var id = "Sixteen"; var started = new QuestStarted(); using var session = theStore.LightweightSession(); 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(); }
public void delete_stream_by_guid_id_conjoined_tenancy() { StoreOptions(opts => opts.Events.TenancyStyle = TenancyStyle.Conjoined); var stream1 = Guid.NewGuid(); var stream2 = Guid.NewGuid(); using (var session = theStore.LightweightSession("one")) { var joined = new MembersJoined { Members = new[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; session.Events.Append(stream1, joined, departed); var joined2 = new MembersJoined { Members = new[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed2 = new MembersDeparted { Members = new[] { "Thom" } }; session.Events.Append(stream2, joined2, departed2); session.SaveChanges(); } theStore.Advanced.Clean.DeleteSingleEventStream(stream1, "one"); using (var session = theStore.LightweightSession()) { session.Events.QueryAllRawEvents().ToList().All(x => x.StreamId == stream2) .ShouldBeTrue(); } }
public void should_check_max_event_id_on_append_with_string_identifier() { UseStreamIdentity(StreamIdentity.AsString); var joined = new MembersJoined { Members = new string[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; var stream = "First"; theSession.Events.Append(stream, joined); theSession.Events.Append(stream, 2, departed); theSession.SaveChanges(); var state = theSession.Events.FetchStreamState(stream); state.Key.ShouldBe(stream); state.Version.ShouldBe(2); }
public void capture_events_to_a_new_stream_and_fetch_the_events_back_in_another_database_schema() { using var session = theStore.LightweightSession(); var joined = new MembersJoined { Members = new[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; var id = "Thirteen"; 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); }
public void capture_events_to_a_new_stream_and_fetch_the_events_back() { var joined = new MembersJoined { Members = new[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; var id = "First"; theSession.Events.StartStream <Quest>(id, joined, departed); theSession.SaveChanges(); var streamEvents = theSession.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(e => e.Timestamp.ShouldNotBe(default(DateTimeOffset))); }
public void capture_events_to_an_existing_stream_and_fetch_the_events_back() { var id = "Twelth"; var started = new QuestStarted(); using (var session = theStore.LightweightSession()) { session.Events.StartStream <Quest>(id, started); session.SaveChanges(); } using (var session = theStore.LightweightSession()) { var joined = new MembersJoined { Members = new[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; session.Events.Append(id, joined); session.Events.Append(id, departed); session.SaveChanges(); 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); } }
public void live_aggregate_equals_inlined_aggregate_without_hidden_contracts() { var questId = "Fifth"; using (var session = theStore.LightweightSession()) { //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 = theStore.LightweightSession()) { var liveAggregate = session.Events.AggregateStream <QuestPartyWithStringIdentifier>(questId); var inlinedAggregate = session.Load <QuestPartyWithStringIdentifier>(questId); liveAggregate.Id.ShouldBe(inlinedAggregate.Id); inlinedAggregate.ToString().ShouldBe(liveAggregate.ToString()); } }
public async Task delete_stream_by_guid_id_async() { var stream1 = Guid.NewGuid(); var stream2 = Guid.NewGuid(); using (var session = theStore.LightweightSession()) { var joined = new MembersJoined { Members = new[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; session.Events.Append(stream1, joined, departed); var joined2 = new MembersJoined { Members = new[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed2 = new MembersDeparted { Members = new[] { "Thom" } }; session.Events.Append(stream2, joined2, departed2); await session.SaveChangesAsync(); } await theStore.Advanced.Clean.DeleteSingleEventStreamAsync(stream1); using (var session = theStore.LightweightSession()) { session.Events.QueryAllRawEvents().ToList().All(x => x.StreamId == stream2) .ShouldBeTrue(); } }
public static MemberJoined[] From(MembersJoined @event) { return(@event.Members.Select(x => new MemberJoined(@event.Day, @event.Location, x)).ToArray()); }
public void open_persisted_stream_in_new_store_with_same_settings() { var questId = "Sixth"; using (var session = theStore.LightweightSession()) { //Note "Id = questId" @see live_aggregate_equals_inlined_aggregate... 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(); } // events-aggregate-on-the-fly - works with same store using (var session = theStore.LightweightSession()) { // questId is the id of the stream var party = session.Events.AggregateStream <QuestPartyWithStringIdentifier>(questId); party.ShouldNotBeNull(); var party_at_version_3 = session.Events .AggregateStream <QuestPartyWithStringIdentifier>(questId, 3); party_at_version_3.ShouldNotBeNull(); var party_yesterday = session.Events .AggregateStream <QuestPartyWithStringIdentifier>(questId, timestamp: DateTime.UtcNow.AddDays(-1)); party_yesterday.ShouldBeNull(); } using (var session = theStore.LightweightSession()) { var party = session.Load <QuestPartyWithStringIdentifier>(questId); SpecificationExtensions.ShouldNotBeNull(party); } var newStore = new DocumentStore(theStore.Options); //Inline is working using (var session = newStore.LightweightSession()) { var party = session.Load <QuestPartyWithStringIdentifier>(questId); party.ShouldNotBeNull(); } //GetAll using (var session = theStore.LightweightSession()) { var parties = session.Events.QueryRawEventDataOnly <QuestPartyWithStringIdentifier>().ToArray(); foreach (var party in parties) { party.ShouldNotBeNull(); } } //This AggregateStream fail with NPE using (var session = newStore.LightweightSession()) { // questId is the id of the stream var party = session.Events.AggregateStream <QuestPartyWithStringIdentifier>(questId);//Here we get NPE party.ShouldNotBeNull(); var party_at_version_3 = session.Events .AggregateStream <QuestPartyWithStringIdentifier>(questId, 3); party_at_version_3.ShouldNotBeNull(); var party_yesterday = session.Events .AggregateStream <QuestPartyWithStringIdentifier>(questId, timestamp: DateTime.UtcNow.AddDays(-1)); party_yesterday.ShouldBeNull(); } }
public void open_persisted_stream_in_new_store_with_same_settings(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" @see live_aggregate_equals_inlined_aggregate... 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(); } // events-aggregate-on-the-fly - works with same store using (var session = store.OpenSession(tenantId, DocumentTracking.None)) { // questId is the id of the stream var party = session.Events.AggregateStream <QuestParty>(questId); party.Id.ShouldBe(questId); party.ShouldNotBeNull(); var party_at_version_3 = session.Events .AggregateStream <QuestParty>(questId, 3); party_at_version_3.ShouldNotBeNull(); var party_yesterday = session.Events .AggregateStream <QuestParty>(questId, timestamp: DateTimeOffset.UtcNow.AddDays(-1)); party_yesterday.ShouldBeNull(); } using (var session = store.OpenSession(tenantId, DocumentTracking.None)) { var party = session.Load <QuestParty>(questId); party.Id.ShouldBe(questId); } var newStore = InitStore(tenancyStyle, false); //Inline is working using (var session = store.OpenSession(tenantId, DocumentTracking.None)) { var party = session.Load <QuestParty>(questId); SpecificationExtensions.ShouldNotBeNull(party); } //GetAll using (var session = store.OpenSession(tenantId, DocumentTracking.None)) { var parties = session.Events.QueryRawEventDataOnly <QuestParty>().ToArray(); foreach (var party in parties) { SpecificationExtensions.ShouldNotBeNull(party); } } //This AggregateStream fail with NPE using (var session = store.OpenSession(tenantId, DocumentTracking.None)) { // questId is the id of the stream var party = session.Events.AggregateStream <QuestParty>(questId);//Here we get NPE party.Id.ShouldBe(questId); var party_at_version_3 = session.Events .AggregateStream <QuestParty>(questId, 3); party_at_version_3.Id.ShouldBe(questId); var party_yesterday = session.Events .AggregateStream <QuestParty>(questId, timestamp: DateTimeOffset.UtcNow.AddDays(-1)); party_yesterday.ShouldBeNull(); } }).ShouldThrowIf( (tenancyStyle == TenancyStyle.Single && tenants.Length > 1) || (tenancyStyle == TenancyStyle.Conjoined && tenants.SequenceEqual(SameTenants)) ); }
public void SampleCopyAndTransformStream() { #region sample_scenario-copyandtransformstream-setup var started = new QuestStarted { Name = "Find the Orb" }; var joined = new MembersJoined { Day = 2, Location = "Faldor's Farm", Members = new[] { "Garion", "Polgara", "Belgarath" } }; var slayed1 = new MonsterSlayed { Name = "Troll" }; var slayed2 = new MonsterSlayed { Name = "Dragon" }; using (var session = theStore.OpenSession()) { session.Events.StartStream <Quest>(started.Name, started, joined, slayed1, slayed2); session.SaveChanges(); } #endregion #region sample_scenario-copyandtransformstream-transform using (var session = theStore.OpenSession()) { var events = session.Events.FetchStream(started.Name); var transformedEvents = events.SelectMany(x => { switch (x.Data) { case MonsterSlayed monster: { // Trolls we remove from our transformed stream return(monster.Name.Equals("Troll") ? new object[] { } : new[] { monster }); } case MembersJoined members: { // MembersJoined events we transform into a series of events return(MemberJoined.From(members)); } } return(new[] { x.Data }); }).Where(x => x != null).ToArray(); var moveTo = $"{started.Name} without Trolls"; // We copy the transformed events to a new stream session.Events.StartStream <Quest>(moveTo, transformedEvents); // And additionally mark the old stream as moved. Furthermore, we assert on the new expected stream version to guard against any racing updates session.Events.Append(started.Name, events.Count + 1, new StreamMovedTo { To = moveTo }); // Transactionally update the streams. session.SaveChanges(); } #endregion }
protected bool Equals(MembersJoined other) { return(QuestId.Equals(other.QuestId) && Day == other.Day && Location == other.Location && Members.SequenceEqual(other.Members)); }
public void running_synchronously() { var logger = new RecordingSessionLogger(); Guid streamId = Guid.NewGuid(); using (var session = theStore.OpenSession()) { session.Logger = logger; var joined = new MembersJoined { Members = new[] { "Rand", "Matt", "Perrin", "Thom" } }; var departed = new MembersDeparted { Members = new[] { "Thom" } }; session.Events.StartStream <Quest>(streamId, joined, departed); session.SaveChanges(); var events = logger.LastCommit.GetEvents().ToArray(); events.Select(x => x.Version) .ShouldHaveTheSameElementsAs(1, 2); events.Each(x => SpecificationExtensions.ShouldBeGreaterThan(x.Sequence, 0L)); events.Select(x => x.Sequence).Distinct().Count().ShouldBe(2); } using (var session = theStore.OpenSession()) { session.Logger = logger; var joined2 = new MembersJoined { Members = new[] { "Egwene" } }; var departed2 = new MembersDeparted { Members = new[] { "Perrin" } }; session.Events.Append(streamId, joined2, departed2); session.SaveChanges(); logger.LastCommit.GetEvents().Select(x => x.Version) .ShouldHaveTheSameElementsAs(3, 4); } using (var session = theStore.OpenSession()) { session.Logger = logger; var joined3 = new MembersJoined { Members = new[] { "Egwene" } }; var departed3 = new MembersDeparted { Members = new[] { "Perrin" } }; session.Events.Append(streamId, joined3, departed3); session.SaveChanges(); logger.LastCommit.GetEvents().Select(x => x.Version) .ShouldHaveTheSameElementsAs(5, 6); } }