Files
ai_site/platform/internal/crud/pool.go
2026-07-31 10:31:17 +08:00

51 lines
1.0 KiB
Go

package crud
import (
"database/sql"
"fmt"
"sync"
"aijianzhan/platform/internal/meta"
"aijianzhan/platform/internal/schema"
)
// DBPool 按 database_per_app 缓存连接。
type DBPool struct {
mu sync.Mutex
baseDSN string
primary *sql.DB
dbs map[string]*sql.DB
}
func NewDBPool(defaultDB *sql.DB, baseDSN string) *DBPool {
return &DBPool{primary: defaultDB, baseDSN: baseDSN, dbs: map[string]*sql.DB{}}
}
func (p *DBPool) ForApp(app *meta.AppRecord) (*sql.DB, error) {
if p == nil {
return nil, fmt.Errorf("db pool nil")
}
if app == nil || app.DatabaseName == "" {
return p.primary, nil
}
p.mu.Lock()
defer p.mu.Unlock()
if db, ok := p.dbs[app.DatabaseName]; ok {
return db, nil
}
dsn, err := schema.DSNForDatabase(p.baseDSN, app.DatabaseName)
if err != nil {
return nil, err
}
db, err := sql.Open("postgres", dsn)
if err != nil {
return nil, err
}
if err := db.Ping(); err != nil {
_ = db.Close()
return nil, fmt.Errorf("ping app db %s: %w", app.DatabaseName, err)
}
p.dbs[app.DatabaseName] = db
return db, nil
}