Update environment variable for database connection and add user fixture script

This commit is contained in:
2026-03-22 16:44:49 -05:00
parent 8185a22e32
commit b39b07b144
3 changed files with 263 additions and 2 deletions

View File

@@ -1 +1 @@
DATABASE_URL=postgresql://postgres:password@localhost:5432/db PG_FROM_DB_URL=postgresql://postgres:password@localhost:5432/db

View File

@@ -16,7 +16,7 @@ func main() {
log.Fatal("Error al cargar el archivo .env") log.Fatal("Error al cargar el archivo .env")
} }
dbpool, err := pgxpool.New(context.Background(), os.Getenv("DATABASE_URL")) dbpool, err := pgxpool.New(context.Background(), os.Getenv("PG_FROM_DB_URL"))
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Unable to create connection pool: %v\n", err) fmt.Fprintf(os.Stderr, "Unable to create connection pool: %v\n", err)
os.Exit(1) os.Exit(1)

View File

@@ -0,0 +1,261 @@
package main
import (
"context"
"fmt"
"log"
"math"
"math/rand"
"os"
"time"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/joho/godotenv"
)
var (
firstNames = []string{
"Juan", "María", "Carlos", "Ana", "Miguel", "Rosa", "Pedro", "Isabel",
"Luis", "Carmen", "José", "Antonia", "Fernando", "Dolores", "Diego", "Margarita",
"Alejandro", "Francisca", "Antonio", "Juana", "Francisco", "Pilar", "Andrés", "Elena",
"Rafael", "Teresa", "Enrique", "Ángeles", "Jorge", "Soledad", "Ramón", "Asunción",
}
lastNames = []string{
"García", "Rodríguez", "González", "López", "Martínez", "Sánchez", "Peña", "Castellanos",
"Moreno", "Jiménez", "Hernández", "Díaz", "Ramírez", "Cruz", "Velasco", "Campos",
"Medina", "Ruiz", "Domínguez", "Delgado", "Flores", "Silver", "Torres", "Rivera",
"Vargas", "Castro", "Vega", "Rojas", "Parra", "Salazar", "Guzmán", "Ochoa",
}
domainNames = []string{
"gmail.com", "yahoo.com", "hotmail.com", "outlook.com", "empresa.com",
"mail.com", "correo.es", "example.com", "test.io", "domain.dev",
}
)
func init() {
rand.Seed(time.Now().UnixNano())
}
func randomFirstName() string {
return firstNames[rand.Intn(len(firstNames))]
}
func randomLastName() string {
return lastNames[rand.Intn(len(lastNames))]
}
func randomEmail() string {
firstName := randomFirstName()
lastName := randomLastName()
domain := domainNames[rand.Intn(len(domainNames))]
return fmt.Sprintf("%s.%s@%s", firstName, lastName, domain)
}
func randomAge() int {
return rand.Intn(70) + 18
}
func randomSalary() float64 {
return math.Round((rand.Float64()*100000 + 25000)) / 100
}
func randomBirthDate() time.Time {
years := rand.Intn(70) + 18
days := rand.Intn(365)
return time.Now().AddDate(-years, 0, -days)
}
func randomPhoneNumber() string {
return fmt.Sprintf("+34 6%d %d%d%d%d%d%d%d",
rand.Intn(10),
rand.Intn(10), rand.Intn(10), rand.Intn(10), rand.Intn(10),
rand.Intn(10), rand.Intn(10), rand.Intn(10),
)
}
func randomCity() string {
cities := []string{
"Madrid", "Barcelona", "Valencia", "Sevilla", "Bilbao",
"Zaragoza", "Málaga", "Murcia", "Palma", "Las Palmas",
"Córdoba", "Valladolid", "Vigo", "Gijón", "Hospitalet",
}
return cities[rand.Intn(len(cities))]
}
func randomHobbies() []string {
allHobbies := []string{
"lectura", "viajes", "cine", "música", "deportes",
"cocina", "fotografía", "gaming", "yoga", "senderismo",
"natación", "tenis", "ajedrez", "pintura", "jardinería",
}
numHobbies := rand.Intn(4) + 1
selected := make([]string, 0, numHobbies)
used := make(map[int]bool)
for len(selected) < numHobbies {
idx := rand.Intn(len(allHobbies))
if !used[idx] {
used[idx] = true
selected = append(selected, allHobbies[idx])
}
}
return selected
}
func createUsersTable(db *pgxpool.Pool, ctx context.Context) error {
createTableSQL := `
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
first_name VARCHAR(100) NOT NULL,
last_name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
age INTEGER NOT NULL CHECK (age >= 18),
birth_date DATE NOT NULL,
salary NUMERIC(12, 2),
phone_number VARCHAR(20),
is_active BOOLEAN DEFAULT true,
is_verified BOOLEAN DEFAULT false,
city VARCHAR(100),
hobbies TEXT[],
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
metadata JSONB
);
`
_, err := db.Exec(ctx, createTableSQL)
if err != nil {
return fmt.Errorf("error creating users table: %w", err)
}
return nil
}
func truncateUsersTable(db *pgxpool.Pool, ctx context.Context) error {
truncateSQL := `TRUNCATE TABLE users RESTART IDENTITY CASCADE;`
_, err := db.Exec(ctx, truncateSQL)
if err != nil {
return fmt.Errorf("error truncating users table: %w", err)
}
return nil
}
func insertUserRecord(db *pgxpool.Pool, ctx context.Context, userNum int) error {
firstName := randomFirstName()
lastName := randomLastName()
email := randomEmail()
age := randomAge()
birthDate := randomBirthDate()
salary := randomSalary()
phoneNumber := randomPhoneNumber()
isActive := rand.Intn(2) == 1
isVerified := rand.Intn(2) == 1
city := randomCity()
hobbies := randomHobbies()
metadata := fmt.Sprintf(
`{"user_number": %d, "registration_source": "%s", "tags": [%d, %d, %d]}`,
userNum,
[]string{"web", "mobile", "api"}[rand.Intn(3)],
rand.Intn(100),
rand.Intn(100),
rand.Intn(100),
)
insertSQL := `
INSERT INTO users (
first_name, last_name, email, age, birth_date, salary,
phone_number, is_active, is_verified, city, hobbies, metadata
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
ON CONFLICT (email) DO NOTHING;
`
_, err := db.Exec(
ctx,
insertSQL,
firstName,
lastName,
email,
age,
birthDate,
salary,
phoneNumber,
isActive,
isVerified,
city,
hobbies,
metadata,
)
if err != nil {
return fmt.Errorf("error inserting user %d: %w", userNum, err)
}
return nil
}
func main() {
err := godotenv.Load()
if err != nil {
log.Println("Warning: could not load .env file")
}
dbURL := os.Getenv("PG_FROM_DB_URL")
if dbURL == "" {
log.Fatal("PG_FROM_DB_URL environment variable not set")
}
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
db, err := pgxpool.New(ctx, dbURL)
if err != nil {
log.Fatalf("Unable to create connection pool: %v", err)
}
defer db.Close()
err = db.Ping(ctx)
if err != nil {
log.Fatalf("Unable to ping database: %v", err)
}
fmt.Println("✓ Connected to database successfully")
fmt.Println("Creating users table...")
err = createUsersTable(db, ctx)
if err != nil {
log.Fatalf("Failed to create table: %v", err)
}
fmt.Println("✓ Users table created/already exists")
fmt.Println("Clearing existing data...")
err = truncateUsersTable(db, ctx)
if err != nil {
log.Fatalf("Failed to truncate table: %v", err)
}
fmt.Println("✓ Table cleared")
fmt.Println("Inserting 1000 user records...")
for i := 1; i <= 1000; i++ {
err := insertUserRecord(db, ctx, i)
if err != nil {
log.Printf("Warning: failed to insert user %d: %v", i, err)
}
if i%100 == 0 {
fmt.Printf(" Progress: %d/1000 records inserted\n", i)
}
}
fmt.Println("✓ All 1000 user records inserted successfully")
var count int
err = db.QueryRow(ctx, "SELECT COUNT(*) FROM users;").Scan(&count)
if err != nil {
log.Printf("Warning: could not verify record count: %v", err)
} else {
fmt.Printf("✓ Final user count: %d\n", count)
}
fmt.Println("\n✅ Fixture creation completed successfully!")
}