git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/db/db.go (about) 1 package db 2 3 import ( 4 "context" 5 "database/sql" 6 "time" 7 8 // import pgx driver 9 _ "github.com/jackc/pgx/v5/stdlib" 10 "github.com/jmoiron/sqlx" 11 ) 12 13 // Queryer allows to query a database. 14 type Queryer interface { 15 Get(ctx context.Context, dest any, query string, args ...any) error 16 Select(ctx context.Context, dest any, query string, args ...any) error 17 Query(ctx context.Context, query string, args ...any) (*sql.Rows, error) 18 Exec(ctx context.Context, query string, args ...any) (sql.Result, error) 19 Rebind(query string) (ret string) 20 } 21 22 // DB represents a pool of zero or more underlying connections. It must be safe for concurrent use 23 // by multiple goroutines. 24 type DB interface { 25 Ping(ctx context.Context) error 26 SetMaxIdleConns(n int) 27 SetMaxOpenConns(n int) 28 SetConnMaxLifetime(d time.Duration) 29 Stats() sql.DBStats 30 Queryer 31 Txer 32 } 33 34 // Txer is the ability to start transactions 35 type Txer interface { 36 Begin(ctx context.Context) (Tx, error) 37 BeginTx(ctx context.Context, opts *sql.TxOptions) (Tx, error) 38 Transaction(ctx context.Context, fn func(tx Tx) error) (err error) 39 } 40 41 // Tx represents an in-progress database transaction. 42 type Tx interface { 43 Commit() error 44 Rollback() error 45 Queryer 46 } 47 48 // Connect to a database and verify the connections with a ping. 49 // See https://www.alexedwards.net/blog/configuring-sqldb 50 // and https://making.pusher.com/production-ready-connection-pooling-in-go 51 // https://brandur.org/fragments/postgres-parameters 52 // for the details 53 func Connect(databaseURL string, poolSize int) (ret *Database, err error) { 54 sqlxDB, err := sqlx.Connect("pgx", databaseURL) 55 if err != nil { 56 return 57 } 58 59 ret = &Database{ 60 sqlxDB: sqlxDB, 61 } 62 63 ret.SetMaxOpenConns(poolSize) 64 ret.SetMaxIdleConns(int(poolSize / 2)) 65 ret.SetConnMaxLifetime(30 * time.Minute) 66 return 67 }