chore: move LoadForUpdate to seporate interface

This commit is contained in:
Jon Lundy 2022-09-30 14:56:10 -06:00
parent 129968d179
commit e7df4cc479
Signed by untrusted user who does not match committer: xuu
GPG Key ID: C63E6D61F3035024
4 changed files with 109 additions and 13 deletions

View File

@ -16,7 +16,8 @@ type EventLog interface {
Append(ctx context.Context, events event.Events, version uint64) (uint64, error) Append(ctx context.Context, events event.Events, version uint64) (uint64, error)
FirstIndex(context.Context) (uint64, error) FirstIndex(context.Context) (uint64, error)
LastIndex(context.Context) (uint64, error) LastIndex(context.Context) (uint64, error)
}
type EventLogWithUpdate interface {
LoadForUpdate(context.Context, event.Aggregate, func(context.Context, event.Aggregate) error) (uint64, error) LoadForUpdate(context.Context, event.Aggregate, func(context.Context, event.Aggregate) error) (uint64, error)
} }

View File

@ -111,7 +111,14 @@ func (w *wrapper) LoadForUpdate(ctx context.Context, a event.Aggregate, fn func(
ctx, span := lg.Span(ctx) ctx, span := lg.Span(ctx)
defer span.End() defer span.End()
return w.up.LoadForUpdate(ctx, a, fn) up := w.up
for up != nil {
if up, ok := up.(driver.EventLogWithUpdate); ok {
return up.LoadForUpdate(ctx, a, fn)
}
up = es.Unwrap(up)
}
return 0, es.ErrNoDriver
} }
func DefaultProjection(e event.Event) []event.Event { func DefaultProjection(e event.Event) []event.Event {

View File

@ -4,26 +4,107 @@ import (
"context" "context"
"testing" "testing"
"github.com/matryer/is"
"github.com/sour-is/ev/pkg/es"
"github.com/sour-is/ev/pkg/es/driver" "github.com/sour-is/ev/pkg/es/driver"
"github.com/sour-is/ev/pkg/es/driver/projecter"
"github.com/sour-is/ev/pkg/es/event"
) )
type mockDriver struct { type mockDriver struct {
onOpen func() onOpen func(context.Context, string) (driver.Driver, error)
onEventLog func() onEventLog func(context.Context, string) (driver.EventLog, error)
}
// EventLog implements driver.Driver
func (*mockDriver) EventLog(ctx context.Context, streamID string) (driver.EventLog, error) {
panic("unimplemented")
} }
// Open implements driver.Driver // Open implements driver.Driver
func (*mockDriver) Open(ctx context.Context, dsn string) (driver.Driver, error) { func (m *mockDriver) Open(ctx context.Context, dsn string) (driver.Driver, error) {
if m.onOpen != nil {
return m.onOpen(ctx, dsn)
}
panic("unimplemented")
}
// EventLog implements driver.Driver
func (m *mockDriver) EventLog(ctx context.Context, streamID string) (driver.EventLog, error) {
if m.onEventLog != nil {
return m.onEventLog(ctx, streamID)
}
panic("unimplemented") panic("unimplemented")
} }
var _ driver.Driver = (*mockDriver)(nil) var _ driver.Driver = (*mockDriver)(nil)
func TestProjecter(t *testing.T) { type mockEventLog struct {
onAppend func(context.Context, event.Events, uint64) (uint64, error)
onFirstIndex func(context.Context) (uint64, error)
onLastIndex func(context.Context) (uint64, error)
onRead func(context.Context, int64, int64) (event.Events, error)
}
// Append implements driver.EventLog
func (m *mockEventLog) Append(ctx context.Context, events event.Events, version uint64) (uint64, error) {
if m.onAppend != nil {
return m.onAppend(ctx, events, version)
}
panic("unimplemented")
}
// FirstIndex implements driver.EventLog
func (m *mockEventLog) FirstIndex(ctx context.Context) (uint64, error) {
if m.onFirstIndex != nil {
return m.onFirstIndex(ctx)
}
panic("unimplemented")
}
// LastIndex implements driver.EventLog
func (m *mockEventLog) LastIndex(ctx context.Context) (uint64, error) {
if m.onLastIndex != nil {
return m.onLastIndex(ctx)
}
panic("unimplemented")
}
// Read implements driver.EventLog
func (m *mockEventLog) Read(ctx context.Context, pos int64, count int64) (event.Events, error) {
if m.onRead != nil {
return m.onRead(ctx, pos, count)
}
panic("unimplemented")
}
var _ driver.EventLog = (*mockEventLog)(nil)
func TestProjecter(t *testing.T) {
is := is.New(t)
ctx := context.Background()
mockEL := &mockEventLog{}
mockEL.onRead = func(ctx context.Context, i1, i2 int64) (event.Events, error) {
return event.NewEvents(), nil
}
mock := &mockDriver{}
mock.onOpen = func(ctx context.Context, s string) (driver.Driver, error) {
return mock, nil
}
mock.onEventLog = func(ctx context.Context, s string) (driver.EventLog, error) {
return mockEL, nil
}
es.Init(ctx)
es.Register(ctx, "mock", mock)
es, err := es.Open(
ctx,
"mock:",
projecter.New(ctx, projecter.DefaultProjection),
)
is.NoErr(err)
_, err = es.Read(ctx, "test", 0, 1)
is.NoErr(err)
} }

View File

@ -182,7 +182,14 @@ func (w *wrapper) LoadForUpdate(ctx context.Context, a event.Aggregate, fn func(
ctx, span := lg.Span(ctx) ctx, span := lg.Span(ctx)
defer span.End() defer span.End()
return w.up.LoadForUpdate(ctx, a, fn) up := w.up
for up != nil {
if up, ok := up.(driver.EventLogWithUpdate); ok {
return up.LoadForUpdate(ctx, a, fn)
}
up = es.Unwrap(up)
}
return 0, es.ErrNoDriver
} }
type position struct { type position struct {