// Patial Tech. // Author, Ankit Patial package pgm import ( "context" "errors" "log/slog" "sync/atomic" "time" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" ) var ( poolPGX atomic.Pointer[pgxpool.Pool] ErrConnStringMissing = errors.New("connection string is empty") ) type Config struct { ConnString string MaxConns int32 MinConns int32 MaxConnLifetime time.Duration MaxConnIdleTime time.Duration } // InitPool will create new pgxpool.Pool and will keep it for its working func InitPool(conf Config) { if conf.ConnString == "" { panic(ErrConnStringMissing) } cfg, err := pgxpool.ParseConfig(conf.ConnString) if err != nil { panic(err) } 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) } // GetPool instance func GetPool() *pgxpool.Pool { return poolPGX.Load() } // BeginTx begins a pgx poll transaction 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 } // IsNotFound error check func IsNotFound(err error) bool { return errors.Is(err, pgx.ErrNoRows) }