42 lines
1.1 KiB
Go
42 lines
1.1 KiB
Go
package db
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
"log/slog"
|
|
|
|
_ "github.com/microsoft/go-mssqldb"
|
|
)
|
|
|
|
// Open creates an MSSQL connection pool and validates connectivity.
|
|
func Open(ctx context.Context, dsn, name string) (*sql.DB, error) {
|
|
pool, err := sql.Open("sqlserver", dsn)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("open %s: %w", name, err)
|
|
}
|
|
pool.SetMaxOpenConns(15)
|
|
pool.SetMaxIdleConns(5)
|
|
if err := pool.PingContext(ctx); err != nil {
|
|
return nil, fmt.Errorf("ping %s: %w", name, err)
|
|
}
|
|
slog.Info("mssql connected", "db", name)
|
|
return pool, nil
|
|
}
|
|
|
|
// QueryFirst runs each SQL query in order, returning rows from the first one
|
|
// that succeeds. Used for schema-fallback queries.
|
|
func QueryFirst(ctx context.Context, pool *sql.DB, queries []string) (*sql.Rows, error) {
|
|
var lastErr error
|
|
for _, q := range queries {
|
|
rows, err := pool.QueryContext(ctx, q)
|
|
if err != nil {
|
|
slog.Warn("query variant failed, trying next", "err", err)
|
|
lastErr = err
|
|
continue
|
|
}
|
|
return rows, nil
|
|
}
|
|
return nil, fmt.Errorf("all query variants failed: %w", lastErr)
|
|
}
|