55 lines
1.0 KiB
Go
55 lines
1.0 KiB
Go
package handlers
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"time"
|
|
|
|
"gitea.futuresens.co.uk/futuresens/hardlink/db"
|
|
)
|
|
|
|
func (app *App) getDB(ctx context.Context) (*sql.DB, error) {
|
|
app.dbMu.Lock()
|
|
defer app.dbMu.Unlock()
|
|
|
|
// Fast path: db exists and is alive
|
|
if app.db != nil {
|
|
pingCtx, cancel := context.WithTimeout(ctx, 1*time.Second)
|
|
defer cancel()
|
|
|
|
if err := app.db.PingContext(pingCtx); err == nil {
|
|
return app.db, nil
|
|
}
|
|
|
|
// stale handle
|
|
_ = app.db.Close()
|
|
app.db = nil
|
|
}
|
|
|
|
// Reconnect once, bounded
|
|
dialCtx, cancel := context.WithTimeout(ctx, 3*time.Second)
|
|
defer cancel()
|
|
|
|
dbConn, err := db.InitMSSQL(
|
|
app.cfg.Dbport,
|
|
app.cfg.Dbuser,
|
|
app.cfg.Dbpassword,
|
|
app.cfg.Dbname,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Optional ping (InitMSSQL already pings, but this keeps semantics explicit)
|
|
pingCtx, cancel2 := context.WithTimeout(dialCtx, 1*time.Second)
|
|
defer cancel2()
|
|
|
|
if err := dbConn.PingContext(pingCtx); err != nil {
|
|
_ = dbConn.Close()
|
|
return nil, err
|
|
}
|
|
|
|
app.db = dbConn
|
|
return app.db, nil
|
|
}
|