download.go
⎇
Raw
1package repository
2
3import (
4 "database/sql"
5
6 "vidarchive/internal/models"
7)
8
9type DownloadRepository struct {
10 db *sql.DB
11}
12
13func NewDownloadRepository(db *sql.DB) *DownloadRepository {
14 return &DownloadRepository{db: db}
15}
16
17func (r *DownloadRepository) Create(d *models.Download) error {
18 result, err := r.db.Exec(
19 `INSERT INTO downloads (url, status, preset_id, format_override, custom_flags, output_dir)
20 VALUES (?, ?, ?, ?, ?, ?)`,
21 d.URL, d.Status, d.PresetID, d.FormatOverride, d.CustomFlags, d.OutputDir,
22 )
23 if err != nil {
24 return err
25 }
26 d.ID, _ = result.LastInsertId()
27 return nil
28}
29
30func (r *DownloadRepository) GetByID(id int64) (*models.Download, error) {
31 row := r.db.QueryRow(
32 `SELECT id, url, status, logs, error_message, preset_id, format_override, custom_flags, output_dir, started_at, completed_at, created_at
33 FROM downloads WHERE id = ?`, id,
34 )
35 return scanDownload(row)
36}
37
38func (r *DownloadRepository) GetAll(status, sortBy string) ([]*models.Download, error) {
39 query := `SELECT id, url, status, logs, error_message, preset_id, format_override, custom_flags, output_dir, started_at, completed_at, created_at
40 FROM downloads WHERE 1=1`
41 var args []interface{}
42
43 if status != "" && status != "all" {
44 query += ` AND status = ?`
45 args = append(args, status)
46 }
47
48 switch sortBy {
49 case "date":
50 query += ` ORDER BY created_at DESC`
51 case "status":
52 query += ` ORDER BY status, created_at DESC`
53 default:
54 query += ` ORDER BY created_at DESC`
55 }
56
57 rows, err := r.db.Query(query, args...)
58 if err != nil {
59 return nil, err
60 }
61 defer rows.Close()
62
63 var downloads []*models.Download
64 for rows.Next() {
65 d, err := scanDownload(rows)
66 if err != nil {
67 return nil, err
68 }
69 downloads = append(downloads, d)
70 }
71 return downloads, rows.Err()
72}
73
74func (r *DownloadRepository) GetQueued(limit int) ([]*models.Download, error) {
75 rows, err := r.db.Query(
76 `SELECT id, url, status, logs, error_message, preset_id, format_override, custom_flags, output_dir, started_at, completed_at, created_at
77 FROM downloads WHERE status = 'queued' ORDER BY created_at ASC LIMIT ?`,
78 limit,
79 )
80 if err != nil {
81 return nil, err
82 }
83 defer rows.Close()
84
85 var downloads []*models.Download
86 for rows.Next() {
87 d, err := scanDownload(rows)
88 if err != nil {
89 return nil, err
90 }
91 downloads = append(downloads, d)
92 }
93 return downloads, rows.Err()
94}
95
96func (r *DownloadRepository) UpdateStatus(id int64, status string) error {
97 _, err := r.db.Exec(`UPDATE downloads SET status = ? WHERE id = ?`, status, id)
98 return err
99}
100
101func (r *DownloadRepository) UpdateLogs(id int64, logs string) error {
102 _, err := r.db.Exec(`UPDATE downloads SET logs = ? WHERE id = ?`, logs, id)
103 return err
104}
105
106func (r *DownloadRepository) AppendLogs(id int64, logs string) error {
107 _, err := r.db.Exec(
108 `UPDATE downloads SET logs = COALESCE(logs, '') || ? WHERE id = ?`,
109 logs, id,
110 )
111 return err
112}
113
114func (r *DownloadRepository) MarkStarted(id int64) error {
115 _, err := r.db.Exec(
116 `UPDATE downloads SET status = 'downloading', started_at = CURRENT_TIMESTAMP WHERE id = ?`,
117 id,
118 )
119 return err
120}
121
122func (r *DownloadRepository) MarkCompleted(id int64, status string) error {
123 _, err := r.db.Exec(
124 `UPDATE downloads SET status = ?, completed_at = CURRENT_TIMESTAMP WHERE id = ?`,
125 status, id,
126 )
127 return err
128}
129
130func (r *DownloadRepository) MarkError(id int64, errMsg string) error {
131 _, err := r.db.Exec(
132 `UPDATE downloads SET status = 'error', error_message = ? WHERE id = ?`,
133 errMsg, id,
134 )
135 return err
136}
137
138func (r *DownloadRepository) Delete(id int64) error {
139 _, err := r.db.Exec(`DELETE FROM downloads WHERE id = ?`, id)
140 return err
141}
142
143func (r *DownloadRepository) DeleteAll() error {
144 _, err := r.db.Exec(`DELETE FROM downloads`)
145 return err
146}
147
148func (r *DownloadRepository) UpdateStatusWhere(oldStatus, newStatus string) error {
149 _, err := r.db.Exec(
150 `UPDATE downloads SET status = ? WHERE status = ?`,
151 newStatus, oldStatus,
152 )
153 return err
154}
155
156func scanDownload(row interface{ Scan(...interface{}) error }) (*models.Download, error) {
157 var d models.Download
158 err := row.Scan(
159 &d.ID, &d.URL, &d.Status,
160 &d.Logs, &d.ErrorMessage, &d.PresetID, &d.FormatOverride, &d.CustomFlags, &d.OutputDir,
161 &d.StartedAt, &d.CompletedAt, &d.CreatedAt,
162 )
163 if err != nil {
164 return nil, err
165 }
166 return &d, nil
167}
168