Skip to content

Commit 95e61de

Browse files
Refactoring: replace pq driver to pgxpool
1 parent 50f6662 commit 95e61de

File tree

3 files changed

+160
-1684
lines changed

3 files changed

+160
-1684
lines changed

database/bun.go

Lines changed: 70 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import (
99
"time"
1010

1111
"github.com/dipdup-net/go-lib/config"
12+
pgx "github.com/jackc/pgx/v5"
13+
"github.com/jackc/pgx/v5/pgtype"
14+
"github.com/jackc/pgx/v5/pgxpool"
15+
"github.com/jackc/pgx/v5/stdlib"
1216
"github.com/pkg/errors"
1317
"github.com/uptrace/bun"
1418
"github.com/uptrace/bun/dialect/pgdialect"
@@ -18,6 +22,7 @@ import (
1822
type Bun struct {
1923
sqldb *sql.DB
2024
conn *bun.DB
25+
pool *pgxpool.Pool
2126
}
2227

2328
// NewBun -
@@ -30,26 +35,25 @@ func (db *Bun) DB() *bun.DB {
3035
return db.conn
3136
}
3237

38+
func (db *Bun) Pool() *pgxpool.Pool {
39+
return db.pool
40+
}
41+
3342
// Connect -
3443
func (db *Bun) Connect(ctx context.Context, cfg config.Database) error {
3544
if cfg.Kind != config.DBKindPostgres {
3645
return errors.Wrap(ErrUnsupportedDatabaseType, cfg.Kind)
3746
}
38-
if cfg.Path != "" {
39-
conn, err := sql.Open("postgres", cfg.Path)
40-
if err != nil {
41-
return err
42-
}
43-
db.sqldb = conn
44-
db.conn = bun.NewDB(db.sqldb, pgdialect.New())
45-
} else {
47+
48+
dsn := cfg.Path
49+
if dsn == "" {
4650
values := make(url.Values)
4751
values.Set("sslmode", "disable")
4852
if cfg.ApplicationName != "" {
4953
values.Set("application_name", cfg.ApplicationName)
5054
}
5155

52-
connStr := fmt.Sprintf(
56+
dsn = fmt.Sprintf(
5357
"postgres://%s:%s@%s:%d/%s",
5458
cfg.User,
5559
cfg.Password,
@@ -59,34 +63,77 @@ func (db *Bun) Connect(ctx context.Context, cfg config.Database) error {
5963
)
6064

6165
if len(values) > 0 {
62-
connStr = fmt.Sprintf("%s?%s", connStr, values.Encode())
66+
dsn = fmt.Sprintf("%s?%s", dsn, values.Encode())
6367
}
68+
}
6469

65-
conn, err := sql.Open("postgres", connStr)
70+
connCfg, err := pgxpool.ParseConfig(dsn)
71+
if err != nil {
72+
return errors.Wrap(err, "parse postgres config")
73+
}
74+
75+
connCfg.ConnConfig.RuntimeParams["TimeZone"] = "UTC"
76+
77+
connCfg.AfterConnect = func(ctx context.Context, conn *pgx.Conn) error {
78+
conn.TypeMap().RegisterType(&pgtype.Type{
79+
Name: "timestamp",
80+
OID: pgtype.TimestampOID,
81+
Codec: &pgtype.TimestampCodec{ScanLocation: time.UTC},
82+
})
83+
conn.TypeMap().RegisterType(&pgtype.Type{
84+
Name: "timestamptz",
85+
OID: pgtype.TimestamptzOID,
86+
Codec: &pgtype.TimestamptzCodec{ScanLocation: time.UTC},
87+
})
88+
89+
rows, err := conn.Query(ctx, "SELECT typname, oid FROM pg_type WHERE typtype = 'e'")
6690
if err != nil {
67-
return err
91+
return errors.Wrap(err, "query enum types")
92+
}
93+
defer rows.Close()
94+
for rows.Next() {
95+
var (
96+
name string
97+
oid uint32
98+
)
99+
if err := rows.Scan(&name, &oid); err != nil {
100+
return errors.Wrap(err, "scan row")
101+
}
102+
conn.TypeMap().RegisterType(&pgtype.Type{
103+
Name: name,
104+
OID: oid,
105+
Codec: pgtype.TextCodec{},
106+
})
107+
}
108+
109+
if err = rows.Err(); err != nil {
110+
return errors.Wrap(err, "rows iteration failed")
68111
}
69-
db.sqldb = conn
70-
db.conn = bun.NewDB(db.sqldb, pgdialect.New())
112+
113+
return nil
71114
}
115+
72116
maxOpenConns := 4 * runtime.GOMAXPROCS(0)
73-
maxIdleConns := maxOpenConns
74-
maxLifetime := time.Minute
75117
if cfg.MaxOpenConnections > 0 {
76118
maxOpenConns = cfg.MaxOpenConnections
77119
}
120+
connCfg.MaxConns = int32(maxOpenConns)
78121

79-
if cfg.MaxIdleConnections > 0 {
80-
maxIdleConns = cfg.MaxIdleConnections
81-
}
82-
122+
maxLifetime := time.Minute
83123
if cfg.MaxLifetimeConnections > 0 {
84124
maxLifetime = time.Duration(cfg.MaxLifetimeConnections) * time.Second
85125
}
126+
connCfg.MaxConnLifetime = maxLifetime
127+
128+
pool, err := pgxpool.NewWithConfig(ctx, connCfg)
129+
if err != nil {
130+
return errors.Wrap(err, "create pgxpool")
131+
}
132+
133+
db.pool = pool
134+
db.sqldb = stdlib.OpenDBFromPool(pool)
135+
db.conn = bun.NewDB(db.sqldb, pgdialect.New())
86136

87-
db.sqldb.SetMaxOpenConns(maxOpenConns)
88-
db.sqldb.SetMaxIdleConns(maxIdleConns)
89-
db.sqldb.SetConnMaxLifetime(maxLifetime)
90137
return nil
91138
}
92139

go.mod

Lines changed: 26 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7,49 +7,37 @@ require (
77
github.com/docker/go-connections v0.5.0
88
github.com/ebellocchia/go-base58 v0.1.0
99
github.com/go-playground/validator/v10 v10.26.0
10-
github.com/go-testfixtures/testfixtures/v3 v3.14.0
11-
github.com/golang/mock v1.6.0
10+
github.com/go-testfixtures/testfixtures/v3 v3.16.0
11+
github.com/golang/mock v1.7.0-rc.1
1212
github.com/gorilla/websocket v1.5.3
1313
github.com/iancoleman/strcase v0.3.0
14+
github.com/jackc/pgx/v5 v5.8.0
1415
github.com/json-iterator/go v1.1.12
1516
github.com/lib/pq v1.10.9
1617
github.com/pkg/errors v0.9.1
1718
github.com/prometheus/client_golang v1.22.0
1819
github.com/rs/zerolog v1.34.0
1920
github.com/sergi/go-diff v1.3.1
2021
github.com/shopspring/decimal v1.4.0
21-
github.com/stretchr/testify v1.10.0
22+
github.com/stretchr/testify v1.11.1
2223
github.com/testcontainers/testcontainers-go v0.37.0
2324
github.com/testcontainers/testcontainers-go/modules/postgres v0.37.0
2425
github.com/tidwall/gjson v1.18.0
25-
github.com/uptrace/bun v1.1.17
26-
github.com/uptrace/bun/dialect/pgdialect v1.1.17
26+
github.com/uptrace/bun v1.2.18
27+
github.com/uptrace/bun/dialect/pgdialect v1.2.18
2728
github.com/yhirose/go-peg v0.0.0-20210804202551-de25d6753cf1
28-
golang.org/x/crypto v0.45.0
29-
golang.org/x/text v0.31.0
29+
golang.org/x/crypto v0.48.0
30+
golang.org/x/text v0.34.0
3031
gopkg.in/yaml.v3 v3.0.1
3132
)
3233

3334
require (
34-
cel.dev/expr v0.16.0 // indirect
35-
cloud.google.com/go v0.116.0 // indirect
36-
cloud.google.com/go/auth v0.9.9 // indirect
37-
cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect
38-
cloud.google.com/go/compute/metadata v0.5.2 // indirect
39-
cloud.google.com/go/iam v1.2.1 // indirect
40-
cloud.google.com/go/longrunning v0.6.1 // indirect
41-
cloud.google.com/go/monitoring v1.21.1 // indirect
42-
cloud.google.com/go/spanner v1.73.0 // indirect
4335
dario.cat/mergo v1.0.1 // indirect
4436
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
45-
github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0 // indirect
46-
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.1 // indirect
4737
github.com/Microsoft/go-winio v0.6.2 // indirect
4838
github.com/beorn7/perks v1.0.1 // indirect
4939
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
50-
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
5140
github.com/cespare/xxhash/v2 v2.3.0 // indirect
52-
github.com/cncf/xds/go v0.0.0-20240822171458-6449f94b4d59 // indirect
5341
github.com/containerd/log v0.1.0 // indirect
5442
github.com/containerd/platforms v0.2.1 // indirect
5543
github.com/cpuguy83/dockercfg v0.3.2 // indirect
@@ -58,29 +46,26 @@ require (
5846
github.com/docker/docker v28.0.1+incompatible // indirect
5947
github.com/docker/go-units v0.5.0 // indirect
6048
github.com/ebitengine/purego v0.8.2 // indirect
61-
github.com/envoyproxy/go-control-plane v0.13.0 // indirect
62-
github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
6349
github.com/felixge/httpsnoop v1.0.4 // indirect
6450
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
65-
github.com/go-logr/logr v1.4.2 // indirect
51+
github.com/go-logr/logr v1.4.3 // indirect
6652
github.com/go-logr/stdr v1.2.2 // indirect
6753
github.com/go-ole/go-ole v1.2.6 // indirect
6854
github.com/go-playground/locales v0.14.1 // indirect
6955
github.com/go-playground/universal-translator v0.18.1 // indirect
56+
github.com/goccy/go-yaml v1.17.1 // indirect
7057
github.com/gogo/protobuf v1.3.2 // indirect
71-
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
72-
github.com/google/s2a-go v0.1.8 // indirect
7358
github.com/google/uuid v1.6.0 // indirect
74-
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
75-
github.com/googleapis/gax-go/v2 v2.13.0 // indirect
76-
github.com/googleapis/go-sql-spanner v1.7.4 // indirect
7759
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
60+
github.com/jackc/pgpassfile v1.0.0 // indirect
61+
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
62+
github.com/jackc/puddle/v2 v2.2.2 // indirect
7863
github.com/jinzhu/inflection v1.0.0 // indirect
7964
github.com/klauspost/compress v1.18.0 // indirect
8065
github.com/leodido/go-urn v1.4.0 // indirect
8166
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
8267
github.com/magiconair/properties v1.8.10 // indirect
83-
github.com/mattn/go-colorable v0.1.13 // indirect
68+
github.com/mattn/go-colorable v0.1.14 // indirect
8469
github.com/mattn/go-isatty v0.0.20 // indirect
8570
github.com/moby/docker-image-spec v1.3.1 // indirect
8671
github.com/moby/patternmatcher v0.6.0 // indirect
@@ -94,12 +79,12 @@ require (
9479
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
9580
github.com/opencontainers/go-digest v1.0.0 // indirect
9681
github.com/opencontainers/image-spec v1.1.1 // indirect
97-
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
9882
github.com/pmezard/go-difflib v1.0.0 // indirect
9983
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
10084
github.com/prometheus/client_model v0.6.1 // indirect
10185
github.com/prometheus/common v0.62.0 // indirect
10286
github.com/prometheus/procfs v0.15.1 // indirect
87+
github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect
10388
github.com/shirou/gopsutil/v4 v4.25.1 // indirect
10489
github.com/sirupsen/logrus v1.9.3 // indirect
10590
github.com/tidwall/match v1.1.1 // indirect
@@ -110,25 +95,15 @@ require (
11095
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
11196
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
11297
github.com/yusufpapurcu/wmi v1.2.4 // indirect
113-
go.opencensus.io v0.24.0 // indirect
114-
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
115-
go.opentelemetry.io/contrib/detectors/gcp v1.29.0 // indirect
116-
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect
117-
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
118-
go.opentelemetry.io/otel v1.35.0 // indirect
119-
go.opentelemetry.io/otel/metric v1.35.0 // indirect
120-
go.opentelemetry.io/otel/sdk v1.29.0 // indirect
121-
go.opentelemetry.io/otel/sdk/metric v1.29.0 // indirect
122-
go.opentelemetry.io/otel/trace v1.35.0 // indirect
123-
golang.org/x/net v0.47.0 // indirect
124-
golang.org/x/oauth2 v0.27.0 // indirect
125-
golang.org/x/sync v0.18.0 // indirect
126-
golang.org/x/sys v0.38.0 // indirect
127-
golang.org/x/time v0.7.0 // indirect
128-
google.golang.org/api v0.203.0 // indirect
129-
google.golang.org/genproto v0.0.0-20241015192408-796eee8c2d53 // indirect
130-
google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect
131-
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect
132-
google.golang.org/grpc v1.67.1 // indirect
133-
google.golang.org/protobuf v1.36.5 // indirect
98+
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
99+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
100+
go.opentelemetry.io/otel v1.40.0 // indirect
101+
go.opentelemetry.io/otel/metric v1.40.0 // indirect
102+
go.opentelemetry.io/otel/sdk v1.40.0 // indirect
103+
go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect
104+
go.opentelemetry.io/otel/trace v1.40.0 // indirect
105+
golang.org/x/net v0.49.0 // indirect
106+
golang.org/x/sync v0.19.0 // indirect
107+
golang.org/x/sys v0.41.0 // indirect
108+
google.golang.org/protobuf v1.36.6 // indirect
134109
)

0 commit comments

Comments
 (0)