Add tasks fixture script and remove users fixture script

This commit is contained in:
2026-03-22 16:59:24 -05:00
parent b39b07b144
commit 924fb0e82c
2 changed files with 148 additions and 261 deletions

View File

@@ -0,0 +1,148 @@
package main
import (
"context"
"fmt"
"log"
"math/rand"
"os"
"strings"
"time"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/joho/godotenv"
)
func createTasksTable(db *pgxpool.Pool, ctx context.Context) error {
createTableSQL := `
CREATE TABLE IF NOT EXISTS tasks (
id SERIAL PRIMARY KEY,
text TEXT NOT NULL,
completed BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);`
_, err := db.Exec(ctx, createTableSQL)
if err != nil {
return fmt.Errorf("error creating tasks table: %w", err)
}
return nil
}
func truncateTasksTable(db *pgxpool.Pool, ctx context.Context) error {
truncateSQL := `TRUNCATE TABLE tasks RESTART IDENTITY CASCADE;`
_, err := db.Exec(ctx, truncateSQL)
if err != nil {
return fmt.Errorf("error truncating tasks table: %w", err)
}
return nil
}
type Task struct {
Id int64
Text string
Completed bool
Created_at time.Time
Updated_at time.Time
}
func generateTasks(count int) []Task {
tasks := make([]Task, count)
for i := 1; i <= count; i++ {
tasks[i-1] = Task{
Text: fmt.Sprintf("random task Nº %v", i),
Completed: rand.Float64() > 0.5,
}
}
return tasks
}
func bulkInsertTasks(db *pgxpool.Pool, ctx context.Context, tasks []Task) error {
if len(tasks) == 0 {
return nil
}
var sb strings.Builder
sb.WriteString(`INSERT INTO tasks (text, completed) VALUES `)
args := make([]any, 0, len(tasks)*2)
for i, task := range tasks {
if i > 0 {
sb.WriteString(`, `)
}
fmt.Fprintf(&sb, `($%d, $%d)`, i*2+1, i*2+2)
args = append(args, task.Text, task.Completed)
}
sb.WriteString(`;`)
_, err := db.Exec(ctx, sb.String(), args...)
if err != nil {
return fmt.Errorf("error bulk inserting tasks: %w", 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(), 120*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()
fmt.Println("Creating tasks table...")
err = createTasksTable(db, ctx)
if err != nil {
log.Fatalf("Failed to create table: %v", err)
}
fmt.Println("✓ Tasks table created/already exists")
fmt.Println("Clearing existing data...")
err = truncateTasksTable(db, ctx)
if err != nil {
log.Fatalf("Failed to truncate table: %v", err)
}
fmt.Println("✓ Table cleared")
fmt.Println("Generating 1000 tasks records...")
tasks := generateTasks(1000)
fmt.Println("✓ Tasks generated")
fmt.Println("Performing bulk insert...")
err = bulkInsertTasks(db, ctx, tasks)
if err != nil {
log.Fatalf("Failed to bulk insert tasks: %v", err)
}
fmt.Println("✓ All 1000 task records inserted successfully")
var count int
err = db.QueryRow(ctx, "SELECT COUNT(*) FROM tasks;").Scan(&count)
if err != nil {
log.Printf("Warning: could not verify record count: %v", err)
} else {
fmt.Printf("✓ Final task count: %d\n", count)
}
fmt.Println("\nFixture creation completed successfully!")
}

View File

@@ -1,261 +0,0 @@
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!")
}