Files
mira/backend/internal/database/database.go
Cauê Faleiros 8c7e5fbbe4
All checks were successful
CI / backend (push) Successful in 13m19s
CI / frontend (push) Successful in 11m3s
CI / docker (push) Successful in 1m58s
first commit
2026-06-03 16:31:42 -03:00

78 lines
1.5 KiB
Go

package database
import (
"context"
"fmt"
"log/slog"
"os"
"path/filepath"
"sort"
"strings"
"time"
"github.com/jackc/pgx/v5/pgxpool"
)
type DB struct {
Pool *pgxpool.Pool
}
func Connect(ctx context.Context, databaseURL string) (*DB, error) {
cfg, err := pgxpool.ParseConfig(databaseURL)
if err != nil {
return nil, fmt.Errorf("parse database url: %w", err)
}
cfg.MaxConns = 10
cfg.MinConns = 1
cfg.MaxConnLifetime = time.Hour
cfg.MaxConnIdleTime = 30 * time.Minute
pool, err := pgxpool.NewWithConfig(ctx, cfg)
if err != nil {
return nil, fmt.Errorf("create database pool: %w", err)
}
if err := pool.Ping(ctx); err != nil {
pool.Close()
return nil, fmt.Errorf("ping database: %w", err)
}
return &DB{Pool: pool}, nil
}
func (db *DB) Close() {
if db != nil && db.Pool != nil {
db.Pool.Close()
}
}
func (db *DB) Migrate(ctx context.Context, logger *slog.Logger, migrationsDir string) error {
files, err := filepath.Glob(filepath.Join(migrationsDir, "*.sql"))
if err != nil {
return fmt.Errorf("list migrations: %w", err)
}
sort.Strings(files)
for _, file := range files {
sql, err := os.ReadFile(file)
if err != nil {
return fmt.Errorf("read migration %s: %w", file, err)
}
statement := strings.TrimSpace(string(sql))
if statement == "" {
continue
}
if _, err := db.Pool.Exec(ctx, statement); err != nil {
return fmt.Errorf("run migration %s: %w", file, err)
}
logger.Info("migration applied", "file", filepath.Base(file))
}
return nil
}