All checks were successful
ci/woodpecker/push/build-image Pipeline was successful
72 lines
1.6 KiB
Go
72 lines
1.6 KiB
Go
package postgres
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/url"
|
|
"strings"
|
|
|
|
"gitea.maximumdirect.net/ejr/weatherapi/internal/platform/config"
|
|
"gitea.maximumdirect.net/ejr/weatherapi/internal/platform/datasource"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
type Factory struct{}
|
|
|
|
func (Factory) Driver() string {
|
|
return "postgres"
|
|
}
|
|
|
|
func (Factory) Open(ctx context.Context, cfg config.DatabaseConfig) (datasource.DataSource, error) {
|
|
dsn, err := buildDSN(cfg.Params.URI, cfg.Params.Username, cfg.Params.Password)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("open postgres datasource %q: %w", cfg.Name, err)
|
|
}
|
|
|
|
pool, err := pgxpool.New(ctx, dsn)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("open postgres datasource %q: %w", cfg.Name, err)
|
|
}
|
|
|
|
if err := pool.Ping(ctx); err != nil {
|
|
pool.Close()
|
|
return nil, fmt.Errorf("open postgres datasource %q: ping: %w", cfg.Name, err)
|
|
}
|
|
|
|
return &DataSource{pool: pool}, nil
|
|
}
|
|
|
|
type DataSource struct {
|
|
pool *pgxpool.Pool
|
|
}
|
|
|
|
func (d *DataSource) Pool() *pgxpool.Pool {
|
|
if d == nil {
|
|
return nil
|
|
}
|
|
return d.pool
|
|
}
|
|
|
|
func (d *DataSource) Close() {
|
|
if d == nil || d.pool == nil {
|
|
return
|
|
}
|
|
d.pool.Close()
|
|
}
|
|
|
|
func buildDSN(uri, username, password string) (string, error) {
|
|
u, err := url.Parse(strings.TrimSpace(uri))
|
|
if err != nil {
|
|
return "", fmt.Errorf("invalid params.uri: %w", err)
|
|
}
|
|
if strings.TrimSpace(u.Scheme) == "" {
|
|
return "", fmt.Errorf("invalid params.uri: missing scheme")
|
|
}
|
|
if strings.TrimSpace(u.Host) == "" {
|
|
return "", fmt.Errorf("invalid params.uri: missing host")
|
|
}
|
|
|
|
u.User = url.UserPassword(strings.TrimSpace(username), strings.TrimSpace(password))
|
|
return u.String(), nil
|
|
}
|