package main import ( "database/sql" "fmt" "path/filepath" "fn-registry/functions/infra" ) // OpenConnections opens all database connections defined in the config. // basePath is the directory of the YAML file — file-based drivers (sqlite, duckdb) // resolve relative paths from there. func OpenConnections(conns map[string]ConnConfig, basePath string) (map[string]*sql.DB, error) { pool := make(map[string]*sql.DB, len(conns)) for name, cfg := range conns { db, err := openOne(name, cfg, basePath) if err != nil { // Close already opened connections on failure. CloseConnections(pool) return nil, err } pool[name] = db } return pool, nil } func openOne(name string, cfg ConnConfig, basePath string) (*sql.DB, error) { switch cfg.Driver { case "sqlite": return infra.SQLiteOpen(cfg.Path, basePath) case "postgres": port := cfg.Port if port == 0 { port = 5432 } return infra.PostgresOpen(cfg.Host, port, cfg.User, cfg.Password, cfg.Database, cfg.SSLMode) case "duckdb": p := cfg.Path if basePath != "" && p != "" && p != ":memory:" && !filepath.IsAbs(p) { p = filepath.Join(basePath, p) } return infra.DuckDBOpen(p) case "clickhouse": port := cfg.Port if port == 0 { port = 9000 } return infra.ClickHouseOpen(cfg.Host, port, cfg.User, cfg.Password, cfg.Database) default: return nil, fmt.Errorf("connection %q: unsupported driver %q", name, cfg.Driver) } } // CloseConnections closes all database connections. func CloseConnections(pool map[string]*sql.DB) { for _, db := range pool { infra.DBClose(db) } }