Skip to content

Commit 5c63eab

Browse files
authored
feat(postgres): add support for eventstore.SequenceNumberGetter (#56)
1 parent 6da801f commit 5c63eab

File tree

4 files changed

+74
-6
lines changed

4 files changed

+74
-6
lines changed

eventstore/postgres/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ require (
99
github.com/docker/docker v20.10.2+incompatible // indirect
1010
github.com/docker/go-connections v0.4.0 // indirect
1111
github.com/docker/go-units v0.4.0 // indirect
12-
github.com/get-eventually/go-eventually v0.0.0-20210830220720-a038785a5316
12+
github.com/get-eventually/go-eventually v0.0.0-20210903204041-6da801fa7f4e
1313
github.com/gogo/protobuf v1.3.2 // indirect
1414
github.com/golang-migrate/migrate v3.5.4+incompatible
1515
github.com/gorilla/mux v1.8.0 // indirect

eventstore/postgres/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y
3232
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
3333
github.com/get-eventually/go-eventually v0.0.0-20210830220720-a038785a5316 h1:mdvJ8lYRc0BXPnkQczyF7EeV9xNnKTMh459lnetvDus=
3434
github.com/get-eventually/go-eventually v0.0.0-20210830220720-a038785a5316/go.mod h1:yOBDlloZ9BP1Hbmdp0lvkCC49esxLizZuytfjakJ5J4=
35+
github.com/get-eventually/go-eventually v0.0.0-20210903204041-6da801fa7f4e h1:9+YQjGoKqBYE0I2GPW3HVNb6k6T6dQHkvEcLORoIOgg=
36+
github.com/get-eventually/go-eventually v0.0.0-20210903204041-6da801fa7f4e/go.mod h1:yOBDlloZ9BP1Hbmdp0lvkCC49esxLizZuytfjakJ5J4=
3537
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
3638
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
3739
github.com/golang-migrate/migrate v3.5.4+incompatible h1:R7OzwvCJTCgwapPCiX6DyBiu2czIUMDCB118gFTKTUA=

eventstore/postgres/store.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ import (
1414
_ "github.com/golang-migrate/migrate/database/postgres" // postgres driver for migrate
1515
)
1616

17-
var _ eventstore.Store = &EventStore{}
17+
var (
18+
_ eventstore.Store = &EventStore{}
19+
_ eventstore.SequenceNumberGetter = &EventStore{}
20+
)
1821

1922
// EventStore is an eventstore.Store implementation which uses
2023
// PostgreSQL as backend datastore.
@@ -181,3 +184,23 @@ func (st *EventStore) appendEvent(
181184

182185
return newVersion, nil
183186
}
187+
188+
// LatestSequenceNumber returns the latest Sequence Number used by a Domain Event
189+
// committed to the Event Store.
190+
func (st EventStore) LatestSequenceNumber(ctx context.Context) (int64, error) {
191+
row := st.db.QueryRowContext(
192+
ctx,
193+
"SELECT max(global_sequence_number) FROM events",
194+
)
195+
196+
if err := row.Err(); err != nil {
197+
return 0, fmt.Errorf("postgres.EventStore: failed to get latest sequence number: %w", err)
198+
}
199+
200+
var sequenceNumber int64
201+
if err := row.Scan(&sequenceNumber); err != nil {
202+
return 0, fmt.Errorf("postgres.EventStore: failed to scan latest sequence number from sql row: %w", err)
203+
}
204+
205+
return sequenceNumber, nil
206+
}

eventstore/postgres/store_test.go

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
11
package postgres_test
22

33
import (
4+
"context"
45
"database/sql"
6+
"math"
57
"os"
68
"testing"
79

8-
"github.com/get-eventually/go-eventually/eventstore"
9-
"github.com/get-eventually/go-eventually/eventstore/postgres"
10-
"github.com/get-eventually/go-eventually/internal"
11-
1210
"github.com/stretchr/testify/assert"
1311
"github.com/stretchr/testify/require"
1412
"github.com/stretchr/testify/suite"
13+
14+
"github.com/get-eventually/go-eventually"
15+
"github.com/get-eventually/go-eventually/eventstore"
16+
"github.com/get-eventually/go-eventually/eventstore/postgres"
17+
"github.com/get-eventually/go-eventually/eventstore/stream"
18+
"github.com/get-eventually/go-eventually/internal"
1519
)
1620

21+
var firstInstance = stream.ID{
22+
Type: "first-type",
23+
Name: "my-instance-for-latest-number",
24+
}
25+
1726
const defaultPostgresURL = "postgres://postgres:postgres@localhost:5432/postgres?sslmode=disable"
1827

1928
func obtainEventStore(t *testing.T) (*sql.DB, postgres.EventStore) {
@@ -67,3 +76,37 @@ func TestStoreSuite(t *testing.T) {
6776
return store
6877
}))
6978
}
79+
80+
func TestLatestSequenceNumber(t *testing.T) {
81+
db, store := obtainEventStore(t)
82+
defer func() { assert.NoError(t, db.Close()) }()
83+
84+
require.NoError(t, store.Register(internal.IntPayload(0)))
85+
86+
ctx := context.Background()
87+
88+
for i := 1; i < 10; i++ {
89+
_, err := store.Append(
90+
ctx,
91+
firstInstance,
92+
eventstore.VersionCheck(int64(i-1)),
93+
eventually.Event{Payload: internal.IntPayload(i)},
94+
)
95+
96+
require.NoError(t, err)
97+
}
98+
99+
ch := make(chan eventstore.Event, 1)
100+
go func() {
101+
require.NoError(t, store.Stream(ctx, ch, stream.All{}, eventstore.SelectFromBeginning))
102+
}()
103+
104+
var latestSequenceNumber int64
105+
for event := range ch {
106+
latestSequenceNumber = int64(math.Max(float64(latestSequenceNumber), float64(event.SequenceNumber)))
107+
}
108+
109+
actual, err := store.LatestSequenceNumber(ctx)
110+
assert.NoError(t, err)
111+
assert.Equal(t, latestSequenceNumber, actual)
112+
}

0 commit comments

Comments
 (0)