- Changed the build process to include a web UI build stage using Node.js. - Updated Go build stage to copy web UI files to the correct location. - Removed the main.go file as it is no longer needed. - Added SQLite database configuration to example config. - Updated dependencies in go.mod and go.sum, including new packages for JWT and SQLite. - Modified .gitignore to include new database and configuration files. Signed-off-by: zhenyus <zhenyus@mathmast.com>
359 lines
6.9 KiB
Go
359 lines
6.9 KiB
Go
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
|
|
}
|