package database import ( "database/sql" "fmt" "time" "proto-gen/internal/models" ) func (db *DB) CreateTask(task *models.Task) error { now := time.Now().UTC().Format(time.RFC3339) _, err := db.conn.Exec(` INSERT INTO tasks (id, status, language, proto_repo, proto_branch, target_repo, toolchain_image, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, task.ID, task.Status, task.Language, task.ProtoRepo, task.ProtoBranch, task.TargetRepo, task.ToolchainImage, now, now, ) return err } func (db *DB) GetTask(id string) (*models.Task, error) { var t models.Task var createdAt, updatedAt string err := db.conn.QueryRow(` SELECT id, status, language, proto_repo, proto_branch, proto_commit, target_repo, toolchain_image, image_digest, result_commit, error, log, retries, created_at, updated_at FROM tasks WHERE id = ?`, id, ).Scan(&t.ID, &t.Status, &t.Language, &t.ProtoRepo, &t.ProtoBranch, &t.ProtoCommit, &t.TargetRepo, &t.ToolchainImage, &t.ImageDigest, &t.ResultCommit, &t.Error, &t.Log, &t.Retries, &createdAt, &updatedAt) if err == sql.ErrNoRows { return nil, fmt.Errorf("task not found: %s", id) } if err != nil { return nil, err } t.CreatedAt, _ = time.Parse(time.RFC3339, createdAt) t.UpdatedAt, _ = time.Parse(time.RFC3339, updatedAt) return &t, nil } func (db *DB) UpdateTask(task *models.Task) error { now := time.Now().UTC().Format(time.RFC3339) _, err := db.conn.Exec(` UPDATE tasks SET status=?, proto_commit=?, image_digest=?, result_commit=?, error=?, log=?, retries=?, updated_at=? WHERE id=?`, task.Status, task.ProtoCommit, task.ImageDigest, task.ResultCommit, task.Error, task.Log, task.Retries, now, task.ID, ) return err } func (db *DB) ListTasks(status string, limit, offset int) ([]*models.Task, error) { query := `SELECT id, status, language, proto_repo, proto_branch, proto_commit, target_repo, toolchain_image, image_digest, result_commit, error, log, retries, created_at, updated_at FROM tasks` var args []interface{} if status != "" { query += ` WHERE status = ?` args = append(args, status) } query += ` ORDER BY created_at DESC LIMIT ? OFFSET ?` args = append(args, limit, offset) rows, err := db.conn.Query(query, args...) if err != nil { return nil, err } defer rows.Close() var tasks []*models.Task for rows.Next() { var t models.Task var createdAt, updatedAt string if err := rows.Scan(&t.ID, &t.Status, &t.Language, &t.ProtoRepo, &t.ProtoBranch, &t.ProtoCommit, &t.TargetRepo, &t.ToolchainImage, &t.ImageDigest, &t.ResultCommit, &t.Error, &t.Log, &t.Retries, &createdAt, &updatedAt); err != nil { return nil, err } t.CreatedAt, _ = time.Parse(time.RFC3339, createdAt) t.UpdatedAt, _ = time.Parse(time.RFC3339, updatedAt) tasks = append(tasks, &t) } return tasks, nil } func (db *DB) GetPendingTasks(limit int) ([]*models.Task, error) { return db.ListTasks(string(models.StatusPending), limit, 0) } func (db *DB) HasRunningTask(targetRepo string) (bool, error) { var count int err := db.conn.QueryRow(`SELECT COUNT(*) FROM tasks WHERE target_repo = ? AND status = 'running'`, targetRepo).Scan(&count) return count > 0, err }