feat: add optional GORM pool and SQL logging adapter

This commit is contained in:
2026-09-24 22:25:44 +08:00
parent da8356e18b
commit b8ab6b3521
21 changed files with 1122 additions and 18 deletions

52
database/gormx/pool.go Normal file
View File

@@ -0,0 +1,52 @@
package gormx
import (
"context"
"database/sql"
"sync/atomic"
"gorm.io/gorm"
)
// GORM can call DB().Close on failed initialization. Do not expose the owner's
// sql.DB until initialization has succeeded; SQL methods remain fully usable.
// Dialects using context.Background during version probing are bounded by the
// startup context, which stops affecting queries as soon as Open succeeds.
type borrowedPool struct {
db *sql.DB
startup atomic.Pointer[startupContext]
}
type startupContext struct{ context.Context }
func (p *borrowedPool) operationContext(ctx context.Context) context.Context {
if startup := p.startup.Load(); startup != nil {
return startup.Context
}
return ctx
}
func (p *borrowedPool) GetDBConn() (*sql.DB, error) {
if p.startup.Load() != nil {
return nil, gorm.ErrInvalidDB
}
return p.db, nil
}
func (p *borrowedPool) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) {
return p.db.PrepareContext(p.operationContext(ctx), query)
}
func (p *borrowedPool) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) {
return p.db.ExecContext(p.operationContext(ctx), query, args...)
}
func (p *borrowedPool) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) {
return p.db.QueryContext(p.operationContext(ctx), query, args...)
}
func (p *borrowedPool) QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row {
return p.db.QueryRowContext(p.operationContext(ctx), query, args...)
}
func (p *borrowedPool) BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error) {
return p.db.BeginTx(p.operationContext(ctx), opts)
}
var _ gorm.ConnPool = (*borrowedPool)(nil)
var _ gorm.TxBeginner = (*borrowedPool)(nil)
var _ gorm.GetDBConnector = (*borrowedPool)(nil)