chore: initial commit of ai site platform
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
50
platform/internal/crud/pool.go
Normal file
50
platform/internal/crud/pool.go
Normal file
@@ -0,0 +1,50 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user