99 lines
1.7 KiB
Go
99 lines
1.7 KiB
Go
|
// Patial Tech.
|
||
|
// Author, Ankit Patial
|
||
|
|
||
|
package pgm
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"errors"
|
||
|
"log/slog"
|
||
|
"strings"
|
||
|
"sync"
|
||
|
"sync/atomic"
|
||
|
"time"
|
||
|
|
||
|
"github.com/jackc/pgx/v5"
|
||
|
"github.com/jackc/pgx/v5/pgxpool"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
poolPGX atomic.Pointer[pgxpool.Pool]
|
||
|
poolStringBuilder = sync.Pool{
|
||
|
New: func() any {
|
||
|
return new(strings.Builder)
|
||
|
},
|
||
|
}
|
||
|
|
||
|
ErrInitTX = errors.New("failed to init db.tx")
|
||
|
ErrCommitTX = errors.New("failed to commit db.tx")
|
||
|
ErrNoRows = errors.New("no data found")
|
||
|
)
|
||
|
|
||
|
type Config struct {
|
||
|
MaxConns int32
|
||
|
MinConns int32
|
||
|
MaxConnLifetime time.Duration
|
||
|
MaxConnIdleTime time.Duration
|
||
|
}
|
||
|
|
||
|
func Init(connString string, conf *Config) {
|
||
|
cfg, err := pgxpool.ParseConfig(connString)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
|
||
|
if conf != nil {
|
||
|
if conf.MaxConns > 0 {
|
||
|
cfg.MaxConns = conf.MaxConns // 100
|
||
|
}
|
||
|
|
||
|
if conf.MinConns > 0 {
|
||
|
cfg.MinConns = conf.MaxConns // 5
|
||
|
}
|
||
|
|
||
|
if conf.MaxConnLifetime > 0 {
|
||
|
cfg.MaxConnLifetime = conf.MaxConnLifetime // time.Minute * 10
|
||
|
}
|
||
|
|
||
|
if conf.MaxConnIdleTime > 0 {
|
||
|
cfg.MaxConnIdleTime = conf.MaxConnIdleTime // time.Minute * 5
|
||
|
}
|
||
|
}
|
||
|
|
||
|
p, err := pgxpool.NewWithConfig(context.Background(), cfg)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
|
||
|
if err = p.Ping(context.Background()); err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
|
||
|
poolPGX.Store(p)
|
||
|
}
|
||
|
|
||
|
func GetPool() *pgxpool.Pool {
|
||
|
return poolPGX.Load()
|
||
|
}
|
||
|
|
||
|
// get string builder from pool
|
||
|
func getSB() *strings.Builder {
|
||
|
return poolStringBuilder.Get().(*strings.Builder)
|
||
|
}
|
||
|
|
||
|
// put string builder back to pool
|
||
|
func putSB(sb *strings.Builder) {
|
||
|
sb.Reset()
|
||
|
poolStringBuilder.Put(sb)
|
||
|
}
|
||
|
|
||
|
func BeginTx(ctx context.Context) (pgx.Tx, error) {
|
||
|
tx, err := poolPGX.Load().Begin(ctx)
|
||
|
if err != nil {
|
||
|
slog.Error(err.Error())
|
||
|
return nil, errors.New("failed to open db tx")
|
||
|
}
|
||
|
|
||
|
return tx, err
|
||
|
}
|