package database import ( "database/sql" "time" ) // APIKey represents an API key record type APIKey struct { ID int64 Key string Description string CreatedAt time.Time UpdatedAt time.Time } // ProjectMapping represents a project to Jenkins job mapping type ProjectMapping struct { ID int64 RepositoryName string DefaultJob string BranchJobs []BranchJob BranchPatterns []BranchPattern CreatedAt time.Time UpdatedAt time.Time } // BranchJob represents a branch to job mapping type BranchJob struct { ID int64 ProjectID int64 BranchName string JobName string CreatedAt time.Time UpdatedAt time.Time } // BranchPattern represents a branch pattern to job mapping type BranchPattern struct { ID int64 ProjectID int64 Pattern string JobName string CreatedAt time.Time UpdatedAt time.Time } // TriggerLog represents a job trigger log entry type TriggerLog struct { ID int64 RepositoryName string BranchName string CommitSHA string JobName string Status string ErrorMessage string CreatedAt time.Time } // CreateAPIKey creates a new API key func (db *DB) CreateAPIKey(key *APIKey) error { query := ` INSERT INTO api_keys (key, description) VALUES (?, ?)` result, err := db.Exec(query, key.Key, key.Description) if err != nil { return err } key.ID, _ = result.LastInsertId() return nil } // GetAPIKey retrieves an API key by its value func (db *DB) GetAPIKey(key string) (*APIKey, error) { var apiKey APIKey query := ` SELECT id, key, description, created_at, updated_at FROM api_keys WHERE key = ?` err := db.QueryRow(query, key).Scan( &apiKey.ID, &apiKey.Key, &apiKey.Description, &apiKey.CreatedAt, &apiKey.UpdatedAt, ) if err == sql.ErrNoRows { return nil, nil } if err != nil { return nil, err } return &apiKey, nil } // DeleteAPIKey deletes an API key by its value func (db *DB) DeleteAPIKey(key string) error { query := `DELETE FROM api_keys WHERE key = ?` result, err := db.Exec(query, key) if err != nil { return err } affected, err := result.RowsAffected() if err != nil { return err } if affected == 0 { return sql.ErrNoRows } return nil } // GetAPIKeys retrieves all API keys func (db *DB) GetAPIKeys() ([]APIKey, error) { query := ` SELECT id, key, description, created_at, updated_at FROM api_keys ORDER BY created_at DESC` rows, err := db.Query(query) if err != nil { return nil, err } defer rows.Close() var keys []APIKey for rows.Next() { var key APIKey err := rows.Scan( &key.ID, &key.Key, &key.Description, &key.CreatedAt, &key.UpdatedAt, ) if err != nil { return nil, err } keys = append(keys, key) } return keys, nil } // CreateProjectMapping creates a new project mapping func (db *DB) CreateProjectMapping(project *ProjectMapping) error { tx, err := db.Begin() if err != nil { return err } defer tx.Rollback() // Insert project mapping query := ` INSERT INTO project_mappings (repository_name, default_job) VALUES (?, ?)` result, err := tx.Exec(query, project.RepositoryName, project.DefaultJob) if err != nil { return err } projectID, _ := result.LastInsertId() project.ID = projectID // Insert branch jobs for _, job := range project.BranchJobs { query = ` INSERT INTO branch_jobs (project_id, branch_name, job_name) VALUES (?, ?, ?)` _, err = tx.Exec(query, projectID, job.BranchName, job.JobName) if err != nil { return err } } // Insert branch patterns for _, pattern := range project.BranchPatterns { query = ` INSERT INTO branch_patterns (project_id, pattern, job_name) VALUES (?, ?, ?)` _, err = tx.Exec(query, projectID, pattern.Pattern, pattern.JobName) if err != nil { return err } } return tx.Commit() } // GetProjectMapping retrieves a project mapping by repository name func (db *DB) GetProjectMapping(repoName string) (*ProjectMapping, error) { var project ProjectMapping // Get project mapping query := ` SELECT id, repository_name, default_job, created_at, updated_at FROM project_mappings WHERE repository_name = ?` err := db.QueryRow(query, repoName).Scan( &project.ID, &project.RepositoryName, &project.DefaultJob, &project.CreatedAt, &project.UpdatedAt, ) if err == sql.ErrNoRows { return nil, nil } if err != nil { return nil, err } // Get branch jobs query = ` SELECT id, branch_name, job_name, created_at, updated_at FROM branch_jobs WHERE project_id = ?` rows, err := db.Query(query, project.ID) if err != nil { return nil, err } defer rows.Close() for rows.Next() { var job BranchJob err := rows.Scan( &job.ID, &job.BranchName, &job.JobName, &job.CreatedAt, &job.UpdatedAt, ) if err != nil { return nil, err } project.BranchJobs = append(project.BranchJobs, job) } // Get branch patterns query = ` SELECT id, pattern, job_name, created_at, updated_at FROM branch_patterns WHERE project_id = ?` rows, err = db.Query(query, project.ID) if err != nil { return nil, err } defer rows.Close() for rows.Next() { var pattern BranchPattern err := rows.Scan( &pattern.ID, &pattern.Pattern, &pattern.JobName, &pattern.CreatedAt, &pattern.UpdatedAt, ) if err != nil { return nil, err } project.BranchPatterns = append(project.BranchPatterns, pattern) } return &project, nil } // LogTrigger logs a job trigger event func (db *DB) LogTrigger(log *TriggerLog) error { query := ` INSERT INTO trigger_logs (repository_name, branch_name, commit_sha, job_name, status, error_message) VALUES (?, ?, ?, ?, ?, ?)` result, err := db.Exec(query, log.RepositoryName, log.BranchName, log.CommitSHA, log.JobName, log.Status, log.ErrorMessage, ) if err != nil { return err } log.ID, _ = result.LastInsertId() return nil } // GetTriggerLogs retrieves trigger logs with optional filters func (db *DB) GetTriggerLogs(repoName, branchName string, since time.Time, limit int) ([]TriggerLog, error) { query := ` SELECT id, repository_name, branch_name, commit_sha, job_name, status, error_message, created_at FROM trigger_logs WHERE 1=1` args := []interface{}{} if repoName != "" { query += " AND repository_name = ?" args = append(args, repoName) } if branchName != "" { query += " AND branch_name = ?" args = append(args, branchName) } if !since.IsZero() { query += " AND created_at >= ?" args = append(args, since) } query += " ORDER BY created_at DESC" if limit > 0 { query += " LIMIT ?" args = append(args, limit) } rows, err := db.Query(query, args...) if err != nil { return nil, err } defer rows.Close() var logs []TriggerLog for rows.Next() { var log TriggerLog err := rows.Scan( &log.ID, &log.RepositoryName, &log.BranchName, &log.CommitSHA, &log.JobName, &log.Status, &log.ErrorMessage, &log.CreatedAt, ) if err != nil { return nil, err } logs = append(logs, log) } return logs, nil }