From 5a28b46b98e74e1a6948464de9b4719e4e8ca4ed Mon Sep 17 00:00:00 2001 From: Gene Armstrong Date: Wed, 8 Oct 2025 09:44:18 -0700 Subject: [PATCH] chore: export the pg.Store struct --- go.mod | 17 +++++++++-------- go.sum | 28 ++++++++++++++-------------- store/pg/pg.go | 32 ++++++++++++++++---------------- store/pg/pg_test.go | 6 +++--- 4 files changed, 42 insertions(+), 41 deletions(-) diff --git a/go.mod b/go.mod index 1b8f4dd..173bc4b 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,12 @@ module github.com/nrfta/go-outbox -go 1.21 -toolchain go1.24.1 +go 1.23.0 + +toolchain go1.24.4 require ( github.com/lib/pq v1.10.9 - github.com/nats-io/nats.go v1.36.0 + github.com/nats-io/nats.go v1.45.0 github.com/neighborly/go-pghelpers v0.9.0 github.com/onsi/ginkgo v1.11.0 github.com/onsi/gomega v1.27.8 @@ -19,18 +20,18 @@ require ( github.com/go-sql-driver/mysql v1.7.1 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/hpcloud/tail v1.0.0 // indirect - github.com/klauspost/compress v1.17.9 // indirect - github.com/nats-io/nkeys v0.4.7 // indirect + github.com/klauspost/compress v1.18.0 // indirect + github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/neighborly/go-errors v0.2.0 // indirect github.com/pierrec/lz4/v4 v4.1.18 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/twmb/franz-go/pkg/kmsg v1.6.1 // indirect - golang.org/x/crypto v0.35.0 // indirect + golang.org/x/crypto v0.37.0 // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.25.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.22.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect gopkg.in/fsnotify.v1 v1.4.7 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect diff --git a/go.sum b/go.sum index 6b6112e..afd9dda 100644 --- a/go.sum +++ b/go.sum @@ -20,15 +20,15 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/nats-io/nats.go v1.36.0 h1:suEUPuWzTSse/XhESwqLxXGuj8vGRuPRoG7MoRN/qyU= -github.com/nats-io/nats.go v1.36.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8= -github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI= -github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc= +github.com/nats-io/nats.go v1.45.0 h1:/wGPbnYXDM0pLKFjZTX+2JOw9TQPoIgTFrUaH97giwA= +github.com/nats-io/nats.go v1.45.0/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g= +github.com/nats-io/nkeys v0.4.11 h1:q44qGV008kYd9W1b1nEBkNzvnWxtRSQ7A8BoqRrcfa0= +github.com/nats-io/nkeys v0.4.11/go.mod h1:szDimtgmfOi9n25JpfIdGw12tZFYXqhGxjhVxsatHVE= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neighborly/go-errors v0.2.0 h1:MKrcBKLyIt385UFERVQ/5QTiVx1VJa8w9lficUjxleU= @@ -57,8 +57,8 @@ go.uber.org/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU= go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= -golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -69,18 +69,18 @@ golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= +golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= diff --git a/store/pg/pg.go b/store/pg/pg.go index 737d788..088d825 100644 --- a/store/pg/pg.go +++ b/store/pg/pg.go @@ -21,7 +21,7 @@ type execQuerier interface { QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row } -type pgStore struct { +type Store struct { db execQuerier tableName string connStr string @@ -29,16 +29,16 @@ type pgStore struct { logger *slog.Logger } -type option func(s *pgStore) +type option func(s *Store) func WithTableName(tn string) option { - return func(s *pgStore) { + return func(s *Store) { s.tableName = tn } } func WithLogger(logger *slog.Logger) option { - return func(s *pgStore) { + return func(s *Store) { if logger == nil { logger = slog.Default() } @@ -47,10 +47,10 @@ func WithLogger(logger *slog.Logger) option { } } -var _ outbox.Store = &pgStore{} +var _ outbox.Store = &Store{} -func NewStore(db execQuerier, connStr string, opts ...option) (*pgStore, error) { - s := &pgStore{ +func NewStore(db execQuerier, connStr string, opts ...option) (*Store, error) { + s := &Store{ db, "outbox", connStr, @@ -80,7 +80,7 @@ func NewStore(db execQuerier, connStr string, opts ...option) (*pgStore, error) return s, nil } -func (s pgStore) CreateRecordTx(ctx context.Context, tx *sql.Tx, r outbox.Record) (*outbox.Record, error) { +func (s Store) CreateRecordTx(ctx context.Context, tx *sql.Tx, r outbox.Record) (*outbox.Record, error) { query := fmt.Sprintf(` INSERT INTO %s VALUES ($1, $2); `, s.tableName) @@ -93,7 +93,7 @@ func (s pgStore) CreateRecordTx(ctx context.Context, tx *sql.Tx, r outbox.Record return &r, nil } -func (s pgStore) Listen() <-chan xid.ID { +func (s Store) Listen() <-chan xid.ID { var ( logger = s.logger.With("method", "Listen") listener = pq.NewListener( @@ -148,7 +148,7 @@ func (s pgStore) Listen() <-chan xid.ID { return idChan } -func (s pgStore) getRecordIDs() ([]xid.ID, error) { +func (s Store) getRecordIDs() ([]xid.ID, error) { var res []xid.ID ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) defer cancel() @@ -180,7 +180,7 @@ func (s pgStore) getRecordIDs() ([]xid.ID, error) { return res, nil } -func (s pgStore) GetWithLock(ctx context.Context, id xid.ID) (*outbox.Record, error) { +func (s Store) GetWithLock(ctx context.Context, id xid.ID) (*outbox.Record, error) { if _, ok := s.db.(*sql.Tx); !ok { return nil, errors.New("get method must be called inside a transaction") } @@ -209,7 +209,7 @@ func (s pgStore) GetWithLock(ctx context.Context, id xid.ID) (*outbox.Record, er return &res, nil } -func (s pgStore) Delete(ctx context.Context, id xid.ID) error { +func (s Store) Delete(ctx context.Context, id xid.ID) error { query := fmt.Sprintf(` DELETE FROM %s WHERE id = $1; `, s.tableName) @@ -222,7 +222,7 @@ func (s pgStore) Delete(ctx context.Context, id xid.ID) error { return nil } -func (s pgStore) ProcessTx(ctx context.Context, fn func(outbox.Store) bool) error { +func (s Store) ProcessTx(ctx context.Context, fn func(outbox.Store) bool) error { db, ok := s.db.(interface { BeginTx(context.Context, *sql.TxOptions) (*sql.Tx, error) }) @@ -235,7 +235,7 @@ func (s pgStore) ProcessTx(ctx context.Context, fn func(outbox.Store) bool) erro return fmt.Errorf("unable to create transaction: %v", err) } - store := pgStore{ + store := Store{ db: tx, tableName: s.tableName, } @@ -247,7 +247,7 @@ func (s pgStore) ProcessTx(ctx context.Context, fn func(outbox.Store) bool) erro return tx.Commit() } -func (s pgStore) Update(ctx context.Context, record *outbox.Record) error { +func (s Store) Update(ctx context.Context, record *outbox.Record) error { if record == nil { return errors.New("record cannot be nil") } @@ -271,7 +271,7 @@ func (s pgStore) Update(ctx context.Context, record *outbox.Record) error { return nil } -func (s pgStore) init() error { +func (s Store) init() error { var ( fnName = strings.ReplaceAll(fmt.Sprintf("notify_%s_channel", s.tableName), ".", "_") triggerName = strings.ReplaceAll(fmt.Sprintf("%s_insert_notification", s.tableName), ".", "_") diff --git a/store/pg/pg_test.go b/store/pg/pg_test.go index c9a7448..9d7a58f 100644 --- a/store/pg/pg_test.go +++ b/store/pg/pg_test.go @@ -26,7 +26,7 @@ var _ = Describe("pgStore", func() { Describe("#CreateRecordTx", func() { var ( - subject *pgStore + subject *Store ctx context.Context tx *sql.Tx @@ -60,7 +60,7 @@ var _ = Describe("pgStore", func() { Describe("#GetWithLock", func() { var ( - subject *pgStore + subject *Store ctx context.Context id xid.ID ) @@ -232,7 +232,7 @@ var _ = Describe("pgStore", func() { }) }) -func createStore(opts ...option) *pgStore { +func createStore(opts ...option) *Store { s, err := NewStore(db, connStr, opts...) Expect(err).To(Succeed()) return s