Skip to content

Commit 08c18f2

Browse files
committed
Migrate from github.com/jackc/pgx to github.com/jackc/pglogrepl
This commit migrates the PostgreSQL logical replication implementation from the legacy pgx v3 API to the modern pglogrepl library with pgx/v5. ## Changes ### Dependencies (go.mod) - Replaced github.com/jackc/pgx v3.6.2+incompatible with: - github.com/jackc/pglogrepl v0.0.0-20251213150135-2e8d0df862c1 - github.com/jackc/pgx/v5 v5.7.4 - Removed obsolete indirect dependencies (cockroachdb/apd, jackc/fake, etc.) ### Main Application (cmd/pgoutbox/init.go) - Created replicationConn wrapper struct that adapts *pgconn.PgConn to the replication interface expected by the listener - Wrapper implements: CreateReplicationSlot, DropReplicationSlot, StartReplication, ReceiveMessage, SendStandbyStatusUpdate, IsAlive, Close - Updated imports to use pgx/v5 and pglogrepl packages ### Listener (internal/listener/listener.go) - Changed lsn field type from uint64 to pglogrepl.LSN - Updated replication interface to use pglogrepl types: - CreateReplicationSlot returns pglogrepl.CreateReplicationSlotResult - StartReplication uses pglogrepl.LSN and pglogrepl.StartReplicationOptions - SendStandbyStatusUpdate uses pglogrepl.StandbyStatusUpdate - ReceiveMessage returns raw []byte instead of structured messages - Rewrote processRawMessage to handle raw byte messages using pglogrepl.ParseXLogData and pglogrepl.ParsePrimaryKeepaliveMessage - Updated SendStandbyStatus and AckWalMessage to take context parameter ### Repository (internal/listener/repository.go) - Updated to pgx/v5 API (QueryRow instead of QueryRowEx) - Close now takes context parameter - IsAlive uses IsClosed() method ### Tests - Updated all mock implementations for new interface signatures - Rewrote test helper functions to use pglogrepl types - Simplified test cases by removing obsolete NewStandbyStatus calls All listener tests pass.
1 parent e2de894 commit 08c18f2

File tree

321 files changed

+34848
-26670
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

321 files changed

+34848
-26670
lines changed

.github/copilot-instructions.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# pgoutbox - AI Coding Instructions
2+
3+
## Architecture & Data Flow
4+
5+
**pgoutbox** captures PostgreSQL changes via logical decoding and publishes to message brokers (NATS, Kafka, RabbitMQ, Google Pub/Sub).
6+
7+
```
8+
PostgreSQL WAL → pgx replication → Parser.ParseWalMessage() → WAL object → filter → Event → Publisher.Publish() → broker
9+
```
10+
11+
### Key Components
12+
- [internal/listener/listener.go](../internal/listener/listener.go) - Replication orchestration, slot/publication lifecycle
13+
- [internal/listener/transaction/parser.go](../internal/listener/transaction/parser.go) - WAL binary protocol decoding
14+
- [internal/publisher/](../internal/publisher/) - Broker adapters implementing `eventPublisher` interface
15+
- [apis/config.go](../apis/config.go) - Config types with Viper loading (env prefix: `WAL_`)
16+
- [apis/event.go](../apis/event.go) - Event struct with `SubjectName()` for topic construction
17+
18+
## Developer Workflows
19+
20+
```bash
21+
make build # Build for current OS/ARCH (Docker containerized)
22+
make test # Unit tests with race detector
23+
make lint # golangci-lint with gofmt, goimports, unparam
24+
make ci # verify + lint + build + unit-tests
25+
make fmt # Format source code
26+
```
27+
28+
All commands run in Docker (`ghcr.io/appscode/golang-dev:1.24`). Output: `bin/pgoutbox-{OS}-{ARCH}`.
29+
30+
**Local PostgreSQL**: `docker/docker-compose.yml` + `docker/scripts/` for test DB setup.
31+
32+
## Critical Patterns
33+
34+
### Interface-Based Mocking
35+
Listener depends on interfaces (`eventPublisher`, `parser`, `replication`, `repository`). Mock implementations in `*_mock_test.go` files:
36+
```go
37+
// internal/listener/listener.go
38+
type eventPublisher interface {
39+
Publish(context.Context, string, *apis.Event) error
40+
}
41+
```
42+
43+
### Configuration
44+
- YAML config + environment overrides (prefix `WAL_`, e.g., `WAL_DATABASE_HOST`)
45+
- Struct tags: both `mapstructure` and `json` required
46+
- Publisher types: `nats`, `kafka`, `rabbitmq`, `google_pubsub`
47+
48+
### Topic Naming
49+
Format: `{publisher.topic}.{publisher.topicPrefix}schemas.{schema}.tables.{table}`
50+
Override via `listener.topicsMap` in config.
51+
52+
### Logging
53+
Use `log/slog` with injected `*slog.Logger`:
54+
```go
55+
l.log.Debug("message", slog.String("key", value))
56+
```
57+
58+
## Common Tasks
59+
60+
| Task | Files to Modify |
61+
|------|-----------------|
62+
| Add publisher | `internal/publisher/{broker}.go` (implement `eventPublisher`), `cmd/pgoutbox/init.go` |
63+
| Add filter logic | `apis/config.go` (`FilterStruct`), `internal/listener/transaction/parser.go` |
64+
| Extend WAL parsing | `internal/listener/transaction/parser.go`, `transaction/data.go` |
65+
| Add metrics | `apis/metrics.go` (Prometheus counters) |
66+
67+
## Standards
68+
69+
- **License**: Apache 2.0 headers required (see `hack/license/`)
70+
- **Errors**: Wrap with `fmt.Errorf("context: %w", err)`
71+
- **Publication name**: Hardcoded as `_pgoutbox_`
72+
- **Replication slot**: Configured via `listener.slotName`, auto-created on startup

cmd/pgoutbox/init.go

Lines changed: 66 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,35 +25,83 @@ import (
2525
"kubeops.dev/pgoutbox/apis"
2626
"kubeops.dev/pgoutbox/internal/publisher"
2727

28-
"github.com/jackc/pgx"
28+
"github.com/jackc/pglogrepl"
29+
"github.com/jackc/pgx/v5"
30+
"github.com/jackc/pgx/v5/pgconn"
31+
"github.com/jackc/pgx/v5/pgproto3"
2932
"github.com/nats-io/nats.go"
3033
"k8s.io/apimachinery/pkg/util/wait"
3134
)
3235

36+
// replicationConn wraps pgconn.PgConn to implement the replication interface expected by the listener.
37+
type replicationConn struct {
38+
conn *pgconn.PgConn
39+
}
40+
41+
func newReplicationConn(conn *pgconn.PgConn) *replicationConn {
42+
return &replicationConn{conn: conn}
43+
}
44+
45+
func (r *replicationConn) CreateReplicationSlot(ctx context.Context, slotName, outputPlugin string) (pglogrepl.CreateReplicationSlotResult, error) {
46+
return pglogrepl.CreateReplicationSlot(ctx, r.conn, slotName, outputPlugin, pglogrepl.CreateReplicationSlotOptions{})
47+
}
48+
49+
func (r *replicationConn) DropReplicationSlot(ctx context.Context, slotName string) error {
50+
return pglogrepl.DropReplicationSlot(ctx, r.conn, slotName, pglogrepl.DropReplicationSlotOptions{})
51+
}
52+
53+
func (r *replicationConn) StartReplication(ctx context.Context, slotName string, startLsn pglogrepl.LSN, options pglogrepl.StartReplicationOptions) error {
54+
return pglogrepl.StartReplication(ctx, r.conn, slotName, startLsn, options)
55+
}
56+
57+
func (r *replicationConn) ReceiveMessage(ctx context.Context) ([]byte, error) {
58+
rawMsg, err := r.conn.ReceiveMessage(ctx)
59+
if err != nil {
60+
return nil, err
61+
}
62+
63+
if errMsg, ok := rawMsg.(*pgproto3.ErrorResponse); ok {
64+
return nil, fmt.Errorf("received error from postgres: %s", errMsg.Message)
65+
}
66+
67+
msg, ok := rawMsg.(*pgproto3.CopyData)
68+
if !ok {
69+
return nil, nil
70+
}
71+
72+
return msg.Data, nil
73+
}
74+
75+
func (r *replicationConn) SendStandbyStatusUpdate(ctx context.Context, status pglogrepl.StandbyStatusUpdate) error {
76+
return pglogrepl.SendStandbyStatusUpdate(ctx, r.conn, status)
77+
}
78+
79+
func (r *replicationConn) IsAlive() bool {
80+
return !r.conn.IsClosed()
81+
}
82+
83+
func (r *replicationConn) Close() error {
84+
return r.conn.Close(context.Background())
85+
}
86+
3387
// initPgxConnections initialise db and replication connections.
34-
func initPgxConnections(cfg *apis.DatabaseCfg, logger *slog.Logger, timeout time.Duration) (*pgx.Conn, *pgx.ReplicationConn, error) {
88+
func initPgxConnections(cfg *apis.DatabaseCfg, logger *slog.Logger, timeout time.Duration) (*pgx.Conn, *pgconn.PgConn, error) {
3589
var pgConn *pgx.Conn
36-
var pgReplicationConn *pgx.ReplicationConn
37-
38-
pgxConf := pgx.ConnConfig{
39-
LogLevel: pgx.LogLevelInfo,
40-
Logger: pgxLogger{logger},
41-
Host: cfg.Host,
42-
Port: cfg.Port,
43-
Database: cfg.Name,
44-
User: cfg.User,
45-
Password: cfg.Password,
46-
}
90+
var pgReplConn *pgconn.PgConn
91+
92+
connString := fmt.Sprintf("host=%s port=%d dbname=%s user=%s password=%s",
93+
cfg.Host, cfg.Port, cfg.Name, cfg.User, cfg.Password)
94+
replConnString := connString + " replication=database"
4795

4896
err := wait.PollUntilContextTimeout(context.TODO(), 5*time.Second, timeout, true, func(ctx context.Context) (bool, error) {
4997
var err error
50-
pgConn, err = pgx.Connect(pgxConf)
98+
pgConn, err = pgx.Connect(ctx, connString)
5199
if err != nil {
52100
logger.Error("db connection:", slog.String("error", err.Error()))
53101
return false, nil
54102
}
55103

56-
pgReplicationConn, err = pgx.ReplicationConnect(pgxConf)
104+
pgReplConn, err = pgconn.Connect(ctx, replConnString)
57105
if err != nil {
58106
logger.Error("db replication connection:", slog.String("error", err.Error()))
59107
return false, nil
@@ -65,12 +113,12 @@ func initPgxConnections(cfg *apis.DatabaseCfg, logger *slog.Logger, timeout time
65113
return nil, nil, fmt.Errorf("wait for db connection: %w", err)
66114
}
67115

68-
return pgConn, pgReplicationConn, nil
116+
return pgConn, pgReplConn, nil
69117
}
70118

71-
func configureReplicaIdentityToFull(pgConn *pgx.Conn, filterTables apis.FilterStruct) error {
119+
func configureReplicaIdentityToFull(ctx context.Context, pgConn *pgx.Conn, filterTables apis.FilterStruct) error {
72120
for table := range filterTables.Tables {
73-
_, err := pgConn.Exec(fmt.Sprintf("ALTER TABLE %s REPLICA IDENTITY FULL;", table))
121+
_, err := pgConn.Exec(ctx, fmt.Sprintf("ALTER TABLE %s REPLICA IDENTITY FULL;", table))
74122
if err != nil {
75123
return fmt.Errorf("change replica identity to FULL for table %s: %w", table, err)
76124
}
@@ -79,15 +127,6 @@ func configureReplicaIdentityToFull(pgConn *pgx.Conn, filterTables apis.FilterSt
79127
return nil
80128
}
81129

82-
type pgxLogger struct {
83-
logger *slog.Logger
84-
}
85-
86-
// Log DB message.
87-
func (l pgxLogger) Log(_ pgx.LogLevel, msg string, _ map[string]any) {
88-
l.logger.Debug(msg)
89-
}
90-
91130
type eventPublisher interface {
92131
Publish(context.Context, string, *apis.Event) error
93132
Close() error

cmd/pgoutbox/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func main() {
9090
return fmt.Errorf("pgx connection: %w", err)
9191
}
9292

93-
if err = configureReplicaIdentityToFull(conn, cfg.Listener.Filter); err != nil {
93+
if err = configureReplicaIdentityToFull(ctx, conn, cfg.Listener.Filter); err != nil {
9494
return fmt.Errorf("configure replica identity: %w", err)
9595
}
9696
pub, err := factoryPublisher(ctx, cfg.Publisher, logger)
@@ -108,7 +108,7 @@ func main() {
108108
cfg,
109109
logger,
110110
listener.NewRepository(conn),
111-
rConn,
111+
newReplicationConn(rConn),
112112
pub,
113113
transaction.NewBinaryParser(logger, binary.BigEndian),
114114
apis.NewMetrics(),

go.mod

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ require (
88
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
99
github.com/goccy/go-json v0.10.3
1010
github.com/google/uuid v1.6.0
11-
github.com/jackc/pgx v3.6.2+incompatible
11+
github.com/jackc/pglogrepl v0.0.0-20251213150135-2e8d0df862c1
12+
github.com/jackc/pgx/v5 v5.7.4
1213
github.com/magiconair/properties v1.8.7
1314
github.com/nats-io/nats.go v1.48.0
1415
github.com/prometheus/client_golang v1.20.5
@@ -29,7 +30,6 @@ require (
2930
cloud.google.com/go/iam v1.2.1 // indirect
3031
github.com/beorn7/perks v1.0.1 // indirect
3132
github.com/cespare/xxhash/v2 v2.3.0 // indirect
32-
github.com/cockroachdb/apd v1.1.0 // indirect
3333
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
3434
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
3535
github.com/eapache/go-resiliency v1.7.0 // indirect
@@ -39,7 +39,6 @@ require (
3939
github.com/fsnotify/fsnotify v1.7.0 // indirect
4040
github.com/go-logr/logr v1.4.2 // indirect
4141
github.com/go-logr/stdr v1.2.2 // indirect
42-
github.com/gofrs/uuid v4.4.0+incompatible // indirect
4342
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
4443
github.com/golang/snappy v0.0.4 // indirect
4544
github.com/google/s2a-go v0.1.8 // indirect
@@ -49,21 +48,21 @@ require (
4948
github.com/hashicorp/go-multierror v1.1.1 // indirect
5049
github.com/hashicorp/go-uuid v1.0.3 // indirect
5150
github.com/hashicorp/hcl v1.0.0 // indirect
52-
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect
51+
github.com/jackc/pgio v1.0.0 // indirect
52+
github.com/jackc/pgpassfile v1.0.0 // indirect
53+
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
5354
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
5455
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
5556
github.com/jcmturner/gofork v1.7.6 // indirect
5657
github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect
5758
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
5859
github.com/klauspost/compress v1.18.0 // indirect
59-
github.com/lib/pq v1.10.9 // indirect
6060
github.com/mitchellh/mapstructure v1.5.0 // indirect
6161
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
6262
github.com/nats-io/nkeys v0.4.11 // indirect
6363
github.com/nats-io/nuid v1.0.1 // indirect
6464
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
6565
github.com/pierrec/lz4/v4 v4.1.21 // indirect
66-
github.com/pkg/errors v0.9.1 // indirect
6766
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
6867
github.com/prometheus/client_model v0.6.1 // indirect
6968
github.com/prometheus/common v0.59.1 // indirect
@@ -73,7 +72,6 @@ require (
7372
github.com/russross/blackfriday/v2 v2.1.0 // indirect
7473
github.com/sagikazarmark/locafero v0.6.0 // indirect
7574
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
76-
github.com/shopspring/decimal v1.4.0 // indirect
7775
github.com/sourcegraph/conc v0.3.0 // indirect
7876
github.com/spf13/afero v1.11.0 // indirect
7977
github.com/spf13/cast v1.7.0 // indirect

go.sum

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF
2727
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
2828
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
2929
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
30-
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
31-
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
3230
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
3331
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
3432
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -60,8 +58,6 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
6058
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
6159
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
6260
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
63-
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
64-
github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
6561
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
6662
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
6763
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
@@ -109,10 +105,18 @@ github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/C
109105
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
110106
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
111107
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
112-
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=
113-
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
114-
github.com/jackc/pgx v3.6.2+incompatible h1:2zP5OD7kiyR3xzRYMhOcXVvkDZsImVXfj+yIyTQf3/o=
115-
github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
108+
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
109+
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
110+
github.com/jackc/pglogrepl v0.0.0-20251213150135-2e8d0df862c1 h1:2NGVj2lubRuA7vcciBVyYGLmaAeqb3utOBausclnkrE=
111+
github.com/jackc/pglogrepl v0.0.0-20251213150135-2e8d0df862c1/go.mod h1:YC4Mb92BuoJKDNno/uRIBKU9FOt+y2uMFLQqo2fMgN4=
112+
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
113+
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
114+
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
115+
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
116+
github.com/jackc/pgx/v5 v5.7.4 h1:9wKznZrhWa2QiHL+NjTSPP6yjl3451BX3imWDnokYlg=
117+
github.com/jackc/pgx/v5 v5.7.4/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
118+
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
119+
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
116120
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
117121
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
118122
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
@@ -131,8 +135,6 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
131135
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
132136
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
133137
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
134-
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
135-
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
136138
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
137139
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
138140
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
@@ -149,8 +151,6 @@ github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNH
149151
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
150152
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
151153
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
152-
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
153-
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
154154
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
155155
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
156156
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -175,8 +175,6 @@ github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3
175175
github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0=
176176
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
177177
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
178-
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
179-
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
180178
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
181179
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
182180
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
@@ -192,7 +190,9 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
192190
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
193191
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
194192
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
193+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
195194
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
195+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
196196
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
197197
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
198198
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=

0 commit comments

Comments
 (0)