Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decouple id types #19

Merged
merged 3 commits into from
Oct 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion GitVersion.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
mode: ContinuousDelivery
next-version: 0.2.0
next-version: 0.3.0
branches:
master:
tag: beta
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System.Linq;
using System.Threading.Tasks;
using RdbmsEventStore.EntityFramework.Tests.Infrastructure;
using RdbmsEventStore.EntityFramework.Tests.TestData;
using Xunit;

namespace RdbmsEventStore.EntityFramework.Tests.EventStoreTests
{
public class QueryEventsTests : EventStoreTestBase<long, string, LongStringEvent>
{
public QueryEventsTests(EventStoreFixture<long, string, LongStringEvent> fixture, AssemblyInitializerFixture initializer) : base(fixture, initializer)
{
_dbContext.Events.AddRange(_fixture.EventFactory.Create("stream-1", 0,
new FooEvent{Foo = "Foo"},
new BarEvent{Bar = "Bar"},
new FooEvent{Foo = "Baz"}));
_dbContext.Events.AddRange(_fixture.EventFactory.Create("stream-2", 0,
new FooEvent {Foo = "Boo"},
new BarEvent {Bar = "Far"}));
_dbContext.SaveChanges();
}

[Theory]
[InlineData("stream-1", 3)]
[InlineData("stream-2", 2)]
public async Task ReturnsEventsFromCorrectStreamOnly(string streamId, long expectedCount)
{
var store = _fixture.BuildEventStore(_dbContext);
var events = await store.Events(streamId);
Assert.Equal(expectedCount, events.Count());
}

[Theory]
[InlineData("stream-1", 2)]
[InlineData("stream-2", 1)]
public async Task ReturnsEventsAccordingToQuery(string streamId, long expectedCount)
{
var store = _fixture.BuildEventStore(_dbContext);
var events = await store.Events(streamId, es => es.Where(e => e.Type == "FooEvent"));
Assert.Equal(expectedCount, events.Count());
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@

namespace RdbmsEventStore.EntityFramework.Tests.EventStoreTests
{
public class WriteEventTests : EventStoreTestBase
public class WriteEventTests : EventStoreTestBase<Guid, Guid, GuidGuidEvent>
{
public WriteEventTests(EventStoreFixture fixture, AssemblyInitializerFixture initializer) : base(fixture, initializer)
public WriteEventTests(EventStoreFixture<Guid, Guid, GuidGuidEvent> fixture, AssemblyInitializerFixture initializer) : base(fixture, initializer)
{
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
using System;
using RdbmsEventStore.EntityFramework.Tests.TestData;
using RdbmsEventStore.EventRegistry;

namespace RdbmsEventStore.EntityFramework.Tests.Infrastructure
{
public class EventStoreFixture
public class EventStoreFixture<TId, TStreamId, TEvent>
where TId : IEquatable<TId>
where TStreamId : IEquatable<TStreamId>
where TEvent : Event<TId, TStreamId>, new()
{
public EventStoreFixture()
{
EventRegistry = new AssemblyEventRegistry(typeof(TestEvent), type => type.Name, type => !type.Name.StartsWith("<>"));
EventRegistry = new AssemblyEventRegistry(typeof(TEvent), type => type.Name, type => !type.Name.StartsWith("<>"));
EventSerializer = new DefaultEventSerializer();
EventFactory = new DefaultEventFactory<Guid, TestEvent>(EventRegistry, EventSerializer);
EventFactory = new DefaultEventFactory<TId, TStreamId, TEvent>(EventRegistry, EventSerializer);
WriteLock = new WriteLock();
}

public IEventRegistry EventRegistry { get; }
public IEventSerializer EventSerializer { get; }
public IEventFactory<Guid, TestEvent> EventFactory { get; }
public DefaultEventFactory<TId, TStreamId, TEvent> EventFactory { get; }
public IWriteLock WriteLock { get; }

public EntityFrameworkEventStore<Guid, EventStoreContext<TestEvent>, TestEvent> BuildEventStore(EventStoreContext<TestEvent> dbContext)
=> new EntityFrameworkEventStore<Guid, EventStoreContext<TestEvent>, TestEvent>(dbContext, EventFactory, WriteLock);
public EntityFrameworkEventStore<TId, TStreamId, EventStoreContext<TEvent>, TEvent> BuildEventStore(EventStoreContext<TEvent> dbContext)
=> new EntityFrameworkEventStore<TId, TStreamId, EventStoreContext<TEvent>, TEvent>(dbContext, EventFactory, WriteLock);
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
using System;
using RdbmsEventStore.EntityFramework.Tests.TestData;
using Xunit;

namespace RdbmsEventStore.EntityFramework.Tests.Infrastructure
{
[Collection(nameof(InMemoryDatabaseCollection))]
public class EventStoreTestBase :
IClassFixture<EventStoreFixture>,
IDisposable
public class EventStoreTestBase<TId, TStreamId, TEvent> : IClassFixture<EventStoreFixture<TId, TStreamId, TEvent>>, IDisposable
where TId : IEquatable<TId>
where TStreamId : IEquatable<TStreamId>
where TEvent : Event<TId, TStreamId>, new()
{
protected readonly EventStoreFixture _fixture;
protected readonly EventStoreContext<TestEvent> _dbContext;
protected readonly EventStoreFixture<TId, TStreamId, TEvent> _fixture;
protected readonly EventStoreContext<TEvent> _dbContext;

public EventStoreTestBase(EventStoreFixture fixture, AssemblyInitializerFixture initializer)
public EventStoreTestBase(EventStoreFixture<TId, TStreamId, TEvent> fixture, AssemblyInitializerFixture initializer)
{
EffortProviderFactory.ResetDb();
_fixture = fixture;
_dbContext = new EventStoreContext<TestEvent>();
_dbContext = new EventStoreContext<TEvent>();
}

public void Dispose()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using Xunit;
using RdbmsEventStore.EntityFramework.Tests.TestData;
using Xunit;

namespace RdbmsEventStore.EntityFramework.Tests.Infrastructure
{
public class SmokeTest : EventStoreTestBase
public class SmokeTest : EventStoreTestBase<long, long, LongLongEvent>
{
public SmokeTest(EventStoreFixture fixture, AssemblyInitializerFixture assemblyInitializer)
public SmokeTest(EventStoreFixture<long, long, LongLongEvent> fixture, AssemblyInitializerFixture assemblyInitializer)
: base(fixture, assemblyInitializer)
{
}
Expand Down
18 changes: 18 additions & 0 deletions src/RdbmsEventStore.EntityFramework.Tests/TestData/EventTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;

namespace RdbmsEventStore.EntityFramework.Tests.TestData
{
public class GuidGuidEvent : Event<Guid, Guid> { }
public class LongStringEvent : Event<long, string> { }
public class LongLongEvent : Event<long, long> { }

public class FooEvent
{
public string Foo { get; set; }
}

public class BarEvent
{
public string Bar { get; set; }
}
}
12 changes: 0 additions & 12 deletions src/RdbmsEventStore.EntityFramework.Tests/TestData/FooEvent.cs

This file was deleted.

This file was deleted.

15 changes: 8 additions & 7 deletions src/RdbmsEventStore.EntityFramework/EntityFrameworkEventStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,33 @@

namespace RdbmsEventStore.EntityFramework
{
public class EntityFrameworkEventStore<TId, TContext, TEvent> : IEventStore<TId, TEvent>
public class EntityFrameworkEventStore<TId, TStreamId, TContext, TEvent> : IEventStore<TId, TStreamId, TEvent>
where TId : IEquatable<TId>
where TStreamId : IEquatable<TStreamId>
where TContext : DbContext, IEventDbContext<TEvent>
where TEvent : Event<TId>, IEvent<TId>, new()
where TEvent : Event<TId, TStreamId>, IEvent<TId, TStreamId>, new()
{
private readonly TContext context;
private readonly IEventFactory<TId, TEvent> _eventFactory;
private readonly IEventFactory<TId, TStreamId, TEvent> _eventFactory;
private readonly IWriteLock _writeLock;

public EntityFrameworkEventStore(TContext context, IEventFactory<TId, TEvent> eventFactory, IWriteLock writeLock)
public EntityFrameworkEventStore(TContext context, IEventFactory<TId, TStreamId, TEvent> eventFactory, IWriteLock writeLock)
{
this.context = context;
_eventFactory = eventFactory;
_writeLock = writeLock;
}

public Task<IEnumerable<TEvent>> Events(TId streamId) => Events(streamId, query => query);
public Task<IEnumerable<TEvent>> Events(TStreamId streamId) => Events(streamId, query => query);

public async Task<IEnumerable<TEvent>> Events(TId streamId, Func<IQueryable<TEvent>, IQueryable<TEvent>> query)
public async Task<IEnumerable<TEvent>> Events(TStreamId streamId, Func<IQueryable<TEvent>, IQueryable<TEvent>> query)
=> await context.Events
.Where(e => e.StreamId.Equals(streamId))
.Apply(query)
.AsNoTracking()
.ToListAsync();

public async Task Commit(TId streamId, long versionBefore, params object[] payloads)
public async Task Commit(TStreamId streamId, long versionBefore, params object[] payloads)
{
using (await _writeLock.Aquire())
{
Expand Down
4 changes: 2 additions & 2 deletions src/RdbmsEventStore.EntityFramework/Event.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace RdbmsEventStore.EntityFramework
{
public class Event<TId> : IEvent<TId>, IMutableEvent<TId>
public class Event<TId, TStreamId> : IEvent<TId, TStreamId>, IMutableEvent<TId, TStreamId>
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
Expand All @@ -15,7 +15,7 @@ public class Event<TId> : IEvent<TId>, IMutableEvent<TId>

[Index(Order = 1)]
[Required]
public TId StreamId { get; set; }
public TStreamId StreamId { get; set; }

[Required]
[Index(Order = 2)]
Expand Down
6 changes: 3 additions & 3 deletions src/RdbmsEventStore.Tests/EventCollectionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace RdbmsEventStore.Tests
{
public class EventCollectionTests
{
private class TestEvent : IEvent<Guid>
private class TestEvent : IEvent<Guid, Guid>
{
public DateTimeOffset Timestamp { get; set; }
public Guid EventId { get; set; }
Expand All @@ -29,12 +29,12 @@ private static TestEvent Factory(Guid stream, long version, object payload)
Payload = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload))
};

private readonly EventCollection<Guid, TestEvent> _collection;
private readonly EventCollection<Guid, Guid, TestEvent> _collection;

public EventCollectionTests()
{
var streamId = Guid.NewGuid();
_collection = new EventCollection<Guid, TestEvent>(streamId, 0, Factory, new { Foo = "Foo" }, new { Bar = "Bar" });
_collection = new EventCollection<Guid, Guid, TestEvent>(streamId, 0, Factory, new { Foo = "Foo" }, new { Bar = "Bar" });
}

[Fact]
Expand Down
10 changes: 5 additions & 5 deletions src/RdbmsEventStore/DefaultEventFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

namespace RdbmsEventStore
{
public class DefaultEventFactory<TId, TEvent> : IEventFactory<TId, TEvent>
where TEvent : IMutableEvent<TId>, new()
public class DefaultEventFactory<TId, TStreamId, TEvent> : IEventFactory<TId, TStreamId, TEvent>
where TEvent : IMutableEvent<TId, TStreamId>, new()
{
private readonly IEventRegistry _registry;
private readonly IEventSerializer _serializer;
Expand All @@ -15,12 +15,12 @@ public DefaultEventFactory(IEventRegistry registry, IEventSerializer serializer)
_serializer = serializer;
}

public virtual IEnumerable<TEvent> Create(TId streamId, long version, params object[] payloads)
public virtual IEnumerable<TEvent> Create(TStreamId streamId, long version, params object[] payloads)
{
return new EventCollection<TId, TEvent>(streamId, version, CreateSingle, payloads);
return new EventCollection<TId, TStreamId, TEvent>(streamId, version, CreateSingle, payloads);
}

protected virtual TEvent CreateSingle(TId streamId, long version, object payload)
protected virtual TEvent CreateSingle(TStreamId streamId, long version, object payload)
{
return new TEvent
{
Expand Down
2 changes: 1 addition & 1 deletion src/RdbmsEventStore/DefaultMaterializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public DefaultMaterializer(IEventRegistry registry, IEventSerializer serializer)
_serializer = serializer;
}

public TState Unfold<TState, TId>(TState initialState, IEnumerable<IEvent<TId>> events, Func<TState, object, TState> applicator)
public TState Unfold<TState, TId, TStreamId>(TState initialState, IEnumerable<IEvent<TId, TStreamId>> events, Func<TState, object, TState> applicator)
=> events
.Select(@event =>
{
Expand Down
4 changes: 2 additions & 2 deletions src/RdbmsEventStore/EventCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

namespace RdbmsEventStore
{
public class EventCollection<TId, TEvent> : IEnumerable<TEvent> where TEvent : IEvent<TId>
public class EventCollection<TId, TStreamId, TEvent> : IEnumerable<TEvent> where TEvent : IEvent<TId, TStreamId>
{
private readonly IEnumerable<TEvent> _events;

public EventCollection(TId streamId, long currentVersion, Func<TId, long, object, TEvent> factory, params object[] payloads)
public EventCollection(TStreamId streamId, long currentVersion, Func<TStreamId, long, object, TEvent> factory, params object[] payloads)
{
_events = payloads.Select((payload, i) => factory(streamId, currentVersion + 1 + i, payload));
}
Expand Down
8 changes: 4 additions & 4 deletions src/RdbmsEventStore/IEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

namespace RdbmsEventStore
{
public interface IEvent<out TId>
public interface IEvent<out TId, out TStreamId>
{
DateTimeOffset Timestamp { get; }

TId EventId { get; }

TId StreamId { get; }
TStreamId StreamId { get; }

long Version { get; }

Expand All @@ -17,13 +17,13 @@ public interface IEvent<out TId>
byte[] Payload { get; }
}

public interface IMutableEvent<TId> : IEvent<TId>
public interface IMutableEvent<TId, TStreamId> : IEvent<TId, TStreamId>
{
new DateTimeOffset Timestamp { get; set; }

new TId EventId { get; set; }

new TId StreamId { get; set; }
new TStreamId StreamId { get; set; }

new long Version { get; set; }

Expand Down
4 changes: 2 additions & 2 deletions src/RdbmsEventStore/IEventFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace RdbmsEventStore
{
public interface IEventFactory<in TId, out TEvent> where TEvent : IEvent<TId>
public interface IEventFactory<in TId, in TStreamId, out TEvent> where TEvent : IEvent<TId, TStreamId>
{
IEnumerable<TEvent> Create(TId streamId, long version, params object[] payloads);
IEnumerable<TEvent> Create(TStreamId streamId, long version, params object[] payloads);
}
}
Loading