perf enhancement
This commit is contained in:
57
pgm.go
57
pgm.go
@@ -25,13 +25,15 @@ var (
|
||||
ErrConnStringMissing = errors.New("connection string is empty")
|
||||
)
|
||||
|
||||
// Errors
|
||||
// Common errors returned by pgm operations
|
||||
var (
|
||||
ErrInitTX = errors.New("failed to init db.tx")
|
||||
ErrCommitTX = errors.New("failed to commit db.tx")
|
||||
ErrNoRows = errors.New("no data found")
|
||||
)
|
||||
|
||||
// Config holds the configuration for initializing the connection pool.
|
||||
// All fields except ConnString are optional and will use pgx defaults if not set.
|
||||
type Config struct {
|
||||
ConnString string
|
||||
MaxConns int32
|
||||
@@ -40,7 +42,17 @@ type Config struct {
|
||||
MaxConnIdleTime time.Duration
|
||||
}
|
||||
|
||||
// InitPool will create new pgxpool.Pool and will keep it for its working
|
||||
// InitPool initializes the connection pool with the provided configuration.
|
||||
// It validates the configuration and panics if invalid.
|
||||
// This function should be called once at application startup.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// pgm.InitPool(pgm.Config{
|
||||
// ConnString: "postgres://user:pass@localhost/dbname",
|
||||
// MaxConns: 100,
|
||||
// MinConns: 5,
|
||||
// })
|
||||
func InitPool(conf Config) {
|
||||
if conf.ConnString == "" {
|
||||
panic(ErrConnStringMissing)
|
||||
@@ -88,9 +100,15 @@ func InitPool(conf Config) {
|
||||
poolPGX.Store(p)
|
||||
}
|
||||
|
||||
// GetPool instance
|
||||
// GetPool returns the initialized connection pool instance.
|
||||
// It panics with a descriptive message if InitPool() has not been called.
|
||||
// This is a fail-fast approach to catch programming errors early.
|
||||
func GetPool() *pgxpool.Pool {
|
||||
return poolPGX.Load()
|
||||
p := poolPGX.Load()
|
||||
if p == nil {
|
||||
panic("pgm: connection pool not initialized, call InitPool() first")
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// ClosePool closes the connection pool gracefully.
|
||||
@@ -102,7 +120,21 @@ func ClosePool() {
|
||||
}
|
||||
}
|
||||
|
||||
// BeginTx begins a pgx poll transaction
|
||||
// BeginTx begins a new database transaction from the connection pool.
|
||||
// Returns an error if the transaction cannot be started.
|
||||
// Remember to commit or rollback the transaction when done.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// tx, err := pgm.BeginTx(ctx)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// defer tx.Rollback(ctx) // rollback on error
|
||||
//
|
||||
// // ... do work ...
|
||||
//
|
||||
// return tx.Commit(ctx)
|
||||
func BeginTx(ctx context.Context) (pgx.Tx, error) {
|
||||
tx, err := poolPGX.Load().Begin(ctx)
|
||||
if err != nil {
|
||||
@@ -113,32 +145,43 @@ func BeginTx(ctx context.Context) (pgx.Tx, error) {
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
// IsNotFound error check
|
||||
// IsNotFound checks if an error is a "no rows" error from pgx.
|
||||
// Returns true if the error indicates no rows were found in a query result.
|
||||
func IsNotFound(err error) bool {
|
||||
return errors.Is(err, pgx.ErrNoRows)
|
||||
}
|
||||
|
||||
// PgTime as in UTC
|
||||
// PgTime converts a Go time.Time to PostgreSQL timestamptz type.
|
||||
// The time is stored as-is (preserves timezone information).
|
||||
func PgTime(t time.Time) pgtype.Timestamptz {
|
||||
return pgtype.Timestamptz{Time: t, Valid: true}
|
||||
}
|
||||
|
||||
// PgTimeNow returns the current time as PostgreSQL timestamptz type.
|
||||
func PgTimeNow() pgtype.Timestamptz {
|
||||
return pgtype.Timestamptz{Time: time.Now(), Valid: true}
|
||||
}
|
||||
|
||||
// TsAndQuery converts a text search query to use AND operator between terms.
|
||||
// Example: "hello world" becomes "hello & world"
|
||||
func TsAndQuery(q string) string {
|
||||
return strings.Join(strings.Fields(q), " & ")
|
||||
}
|
||||
|
||||
// TsPrefixAndQuery converts a text search query to use AND operator with prefix matching.
|
||||
// Example: "hello world" becomes "hello:* & world:*"
|
||||
func TsPrefixAndQuery(q string) string {
|
||||
return strings.Join(fieldsWithSufix(q, ":*"), " & ")
|
||||
}
|
||||
|
||||
// TsOrQuery converts a text search query to use OR operator between terms.
|
||||
// Example: "hello world" becomes "hello | world"
|
||||
func TsOrQuery(q string) string {
|
||||
return strings.Join(strings.Fields(q), " | ")
|
||||
}
|
||||
|
||||
// TsPrefixOrQuery converts a text search query to use OR operator with prefix matching.
|
||||
// Example: "hello world" becomes "hello:* | world:*"
|
||||
func TsPrefixOrQuery(q string) string {
|
||||
return strings.Join(fieldsWithSufix(q, ":*"), " | ")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user