package database import ( "database/sql" "fmt" _ "github.com/mattn/go-sqlite3" ) // DB represents the database connection type DB struct { *sql.DB } // Config holds database configuration type Config struct { Path string } // New creates a new database connection func New(config Config) (*DB, error) { db, err := sql.Open("sqlite3", config.Path) if err != nil { return nil, fmt.Errorf("failed to open database: %v", err) } if err := db.Ping(); err != nil { return nil, fmt.Errorf("failed to ping database: %v", err) } if err := initSchema(db); err != nil { return nil, fmt.Errorf("failed to initialize schema: %v", err) } return &DB{db}, nil } // initSchema creates the database schema if it doesn't exist func initSchema(db *sql.DB) error { schema := ` CREATE TABLE IF NOT EXISTS api_keys ( id INTEGER PRIMARY KEY AUTOINCREMENT, key TEXT NOT NULL UNIQUE, description TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS project_mappings ( id INTEGER PRIMARY KEY AUTOINCREMENT, repository_name TEXT NOT NULL, default_job TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE(repository_name) ); CREATE TABLE IF NOT EXISTS branch_jobs ( id INTEGER PRIMARY KEY AUTOINCREMENT, project_id INTEGER NOT NULL, branch_name TEXT NOT NULL, job_name TEXT NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES project_mappings(id) ON DELETE CASCADE, UNIQUE(project_id, branch_name) ); CREATE TABLE IF NOT EXISTS branch_patterns ( id INTEGER PRIMARY KEY AUTOINCREMENT, project_id INTEGER NOT NULL, pattern TEXT NOT NULL, job_name TEXT NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES project_mappings(id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS trigger_logs ( id INTEGER PRIMARY KEY AUTOINCREMENT, repository_name TEXT NOT NULL, branch_name TEXT NOT NULL, commit_sha TEXT NOT NULL, job_name TEXT NOT NULL, status TEXT NOT NULL, error_message TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX IF NOT EXISTS idx_trigger_logs_repo ON trigger_logs(repository_name); CREATE INDEX IF NOT EXISTS idx_trigger_logs_branch ON trigger_logs(branch_name); CREATE INDEX IF NOT EXISTS idx_trigger_logs_created ON trigger_logs(created_at); ` _, err := db.Exec(schema) return err } // Close closes the database connection func (db *DB) Close() error { return db.DB.Close() }