package db import ( "database/sql" "fmt" "log/slog" "os" "path/filepath" _ "github.com/mattn/go-sqlite3" ) // DB represents the database connection type DB struct { *sql.DB logger *slog.Logger } // New creates a new database connection func New(dbPath string) (*DB, error) { logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ Level: slog.LevelDebug, })) // Ensure directory exists if err := os.MkdirAll(filepath.Dir(dbPath), 0755); err != nil { return nil, fmt.Errorf("failed to create database directory: %w", err) } // Open database connection sqlDB, err := sql.Open("sqlite3", dbPath) if err != nil { return nil, fmt.Errorf("failed to open database: %w", err) } // Create database instance db := &DB{ DB: sqlDB, logger: logger, } // Initialize schema if err := db.initSchema(); err != nil { db.Close() return nil, fmt.Errorf("failed to initialize schema: %w", err) } return db, nil } // initSchema creates the database tables if they don't exist func (db *DB) initSchema() error { // Create groups table _, err := db.Exec(` CREATE TABLE IF NOT EXISTS groups ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE, description TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) `) if err != nil { return fmt.Errorf("failed to create groups table: %w", err) } // Create racers table _, err = db.Exec(` CREATE TABLE IF NOT EXISTS racers ( id INTEGER PRIMARY KEY AUTOINCREMENT, first_name TEXT NOT NULL, last_name TEXT NOT NULL, car_number TEXT NOT NULL UNIQUE, car_weight REAL NOT NULL, group_id INTEGER NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (group_id) REFERENCES groups(id) ) `) if err != nil { return fmt.Errorf("failed to create racers table: %w", err) } // Create races table _, err = db.Exec(` CREATE TABLE IF NOT EXISTS races ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, status TEXT NOT NULL DEFAULT 'pending', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) `) if err != nil { return fmt.Errorf("failed to create races table: %w", err) } // Create race_results table _, err = db.Exec(` CREATE TABLE IF NOT EXISTS race_results ( id INTEGER PRIMARY KEY AUTOINCREMENT, race_id INTEGER NOT NULL, racer_id INTEGER NOT NULL, lane INTEGER NOT NULL, time REAL, place INTEGER, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (race_id) REFERENCES races(id), FOREIGN KEY (racer_id) REFERENCES racers(id), UNIQUE(race_id, lane) ) `) if err != nil { return fmt.Errorf("failed to create race_results table: %w", err) } return nil }