This repository was archived by the owner on Dec 14, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpgxutil.go
More file actions
78 lines (64 loc) · 1.76 KB
/
pgxutil.go
File metadata and controls
78 lines (64 loc) · 1.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package pgxutil
import (
"context"
"errors"
"fmt"
"time"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgxpool"
)
type DB struct {
pool *pgxpool.Pool
}
// New creates a new wrapper for pgx.
func New(pool *pgxpool.Pool) (*DB, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
if err := pool.Ping(ctx); err != nil {
return nil, err
}
db := &DB{
pool: pool,
}
return db, nil
}
// InWriteTx runs the given function within a transaction with a given isolation level.
func (db *DB) InWriteTx(ctx context.Context, level pgx.TxIsoLevel, fn func(tx pgx.Tx) error) error {
return db.inTx(ctx, level, "", fn)
}
// InReadTx runs the given function within a read-only transaction with read commited isolation level.
func (db *DB) InReadTx(ctx context.Context, fn func(tx pgx.Tx) error) error {
return db.inTx(ctx, pgx.ReadCommitted, pgx.ReadOnly, fn)
}
func (db *DB) inTx(ctx context.Context, level pgx.TxIsoLevel, access pgx.TxAccessMode,
fn func(tx pgx.Tx) error) (err error) {
conn, errAcq := db.pool.Acquire(ctx)
if errAcq != nil {
return fmt.Errorf("acquiring connection: %w", errAcq)
}
defer conn.Release()
opts := pgx.TxOptions{
IsoLevel: level,
AccessMode: access,
}
tx, errBegin := conn.BeginTx(ctx, opts)
if errBegin != nil {
return fmt.Errorf("begin tx: %w", errBegin)
}
defer func() {
errRollback := tx.Rollback(ctx)
if !(errRollback == nil || errors.Is(errRollback, pgx.ErrTxClosed)) {
err = errRollback
}
}()
if err := fn(tx); err != nil {
if errRollback := tx.Rollback(ctx); errRollback != nil {
return fmt.Errorf("rollback tx: %v (original: %w)", errRollback, err)
}
return err
}
if err := tx.Commit(ctx); err != nil {
return fmt.Errorf("commit tx: %w", err)
}
return nil
}