homelabby/internal/store/store.go
Mikkel Georgsen 4bc22dc7b9 feat(06-01): add pgx/v5 store with connection pool and migrations
- Store struct wrapping pgxpool.Pool with NewStore/Close/Pool
- RunMigrations creates conversations + messages tables idempotently
- DSN never logged to avoid credential exposure (T-06-01-02)
- All queries parameterized (T-06-01-01)
2026-04-10 07:31:08 +00:00

43 lines
1.1 KiB
Go

package store
import (
"context"
"fmt"
"github.com/jackc/pgx/v5/pgxpool"
)
// Store holds the PostgreSQL connection pool and exposes methods for
// chat persistence. All operations are parameterized (T-06-01-01).
type Store struct {
pool *pgxpool.Pool
}
// NewStore creates a new Store by connecting to PostgreSQL via pgxpool.
// It pings the pool to verify connectivity before returning.
// The DSN is sourced from the HWLAB_DATABASE_URL env var — it is never
// logged here to avoid leaking credentials (T-06-01-02).
func NewStore(ctx context.Context, dsn string) (*Store, error) {
pool, err := pgxpool.New(ctx, dsn)
if err != nil {
return nil, fmt.Errorf("store: open pool: %w", err)
}
if err := pool.Ping(ctx); err != nil {
pool.Close()
return nil, fmt.Errorf("store: ping: %w", err)
}
return &Store{pool: pool}, nil
}
// Pool returns the underlying pgxpool.Pool for direct use in migrations
// and tests.
func (s *Store) Pool() *pgxpool.Pool {
return s.pool
}
// Close releases all connections in the pool. Safe to call more than once.
func (s *Store) Close() {
s.pool.Close()
}