예제 #1
0
        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);
        }
예제 #2
0
        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");
        }
예제 #3
0
        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))
                );
        }
예제 #4
0
        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");
                }
            }
        }
예제 #5
0
        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);
        }
예제 #7
0
        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();
        }
예제 #8
0
        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);
        }
예제 #9
0
        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))
                );
        }
예제 #10
0
        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();
        }
예제 #11
0
        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))
                );
        }
예제 #12
0
        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");
            }
        }
예제 #13
0
        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");
        }
예제 #14
0
 public DeleteWhere(Type documentType, string sql, IWhereFragment @where, TenancyStyle tenancyStyle)
 {
     _where        = @where;
     _tenancyStyle = tenancyStyle;
     DocumentType  = documentType;
     Sql           = sql;
 }
예제 #15
0
        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);
        }
예제 #16
0
        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);
        }
예제 #17
0
        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);
            });
        }
예제 #18
0
        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))
                );
        }
예제 #19
0
        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);
            }
        }
예제 #20
0
        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();
        }
예제 #21
0
        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);
            }
        }
예제 #22
0
        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))
                       ));
        }
예제 #23
0
        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;
        }
예제 #24
0
 private void InitStore(TenancyStyle tenancyStyle, StreamIdentity streamIdentity = StreamIdentity.AsGuid)
 {
     StoreOptions(_ =>
     {
         _.Events.TenancyStyle   = tenancyStyle;
         _.Events.StreamIdentity = streamIdentity;
         _.Policies.AllDocumentsAreMultiTenanted();
     }, true);
 }
예제 #25
0
        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));
        }
예제 #26
0
        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();
            });
        }
예제 #27
0
        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();
        }
예제 #28
0
        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();
            });
        }
예제 #29
0
        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))
                );
        }
예제 #30
0
        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;
        }