gohorsejobs/backend/internal/database/database.go
Tiago Yamamoto 1c7ef95c1a first commit
2025-12-09 19:04:48 -03:00

95 lines
2.4 KiB
Go
Executable file

package database
import (
"database/sql"
"fmt"
"log"
"os"
_ "github.com/lib/pq"
)
var DB *sql.DB
func InitDB() {
var err error
host := os.Getenv("DB_HOST")
if host == "" {
log.Fatal("DB_HOST environment variable not set")
}
user := os.Getenv("DB_USER")
if user == "" {
log.Fatal("DB_USER environment variable not set")
}
password := os.Getenv("DB_PASSWORD")
if password == "" {
log.Fatal("DB_PASSWORD environment variable not set")
}
dbname := os.Getenv("DB_NAME")
if dbname == "" {
log.Fatal("DB_NAME environment variable not set")
}
port := os.Getenv("DB_PORT")
if port == "" {
port = "5432"
}
connStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
host, port, user, password, dbname)
DB, err = sql.Open("postgres", connStr)
if err != nil {
log.Fatalf("Error opening database: %v", err)
}
if err = DB.Ping(); err != nil {
log.Fatalf("Error connecting to database: %v", err)
}
log.Println("Successfully connected to the database")
}
func RunMigrations() {
files, err := os.ReadDir("migrations")
if err != nil {
// Try fallback to relative path if running from cmd/api
files, err = os.ReadDir("../../migrations")
if err != nil {
log.Printf("Warning: Could not list migrations directory: %v", err)
return
}
}
// Sort files by name to ensure order (001, 002, ...)
// ReadDir returns sorted by name automatically, but let's be safe if logic changes?
// Actually ReadDir result is sorted by filename.
for _, file := range files {
if file.IsDir() {
continue
}
log.Printf("Running migration: %s", file.Name())
content, err := os.ReadFile("migrations/" + file.Name())
if err != nil {
// Try fallback
content, err = os.ReadFile("../../migrations/" + file.Name())
if err != nil {
log.Fatalf("Error reading migration file %s: %v", file.Name(), err)
}
}
_, err = DB.Exec(string(content))
if err != nil {
// Log warning but don't crash on "already exists" errors if possible,
// but pure SQL Exec might fail hard.
// Given the SQL files use IF NOT EXISTS, we should be fine.
// If one fails, it might be syntax.
log.Printf("Error running migration %s: %v", file.Name(), err)
// Continue or Fail? User wants robustness. Let's Warn and continue for now to avoid single failure blocking all
} else {
log.Printf("Migration %s executed successfully", file.Name())
}
}
log.Println("All migrations processed")
}