This commit is contained in:
2026-08-22 02:59:16 +02:00
commit 6a5bb1d699
100 changed files with 17409 additions and 0 deletions
+94
View File
@@ -0,0 +1,94 @@
package downloads
import (
"context"
"database/sql"
"errors"
"fmt"
"github.com/google/uuid"
)
type Repository struct {
db *sql.DB
}
func NewRepository(db *sql.DB) *Repository {
return &Repository{db: db}
}
var ErrNotFound = errors.New("download job not found")
func (r *Repository) Create(ctx context.Context, galleryID uuid.UUID, visitorID string) (Job, error) {
job := Job{ID: uuid.New(), GalleryID: galleryID, VisitorID: visitorID, Status: StatusQueued}
_, err := r.db.ExecContext(ctx, `
INSERT INTO download_jobs (id, gallery_id, visitor_id, status)
VALUES ($1, $2, $3, $4)
`, job.ID, job.GalleryID, job.VisitorID, job.Status)
if err != nil {
return Job{}, fmt.Errorf("create download job: %w", err)
}
return r.GetForVisitor(ctx, job.ID, galleryID, visitorID)
}
func (r *Repository) GetForVisitor(ctx context.Context, jobID, galleryID uuid.UUID, visitorID string) (Job, error) {
return r.get(ctx, `
WHERE id = $1 AND gallery_id = $2 AND visitor_id = $3
`, jobID, galleryID, visitorID)
}
func (r *Repository) Get(ctx context.Context, jobID uuid.UUID) (Job, error) {
return r.get(ctx, `WHERE id = $1`, jobID)
}
func (r *Repository) get(ctx context.Context, predicate string, args ...any) (Job, error) {
var (
job Job
storageKey, jobError, createdAt, updatedAt sql.NullString
completedAt sql.NullString
)
err := r.db.QueryRowContext(ctx, `
SELECT id, gallery_id, visitor_id, status, storage_key, error, created_at, updated_at, completed_at
FROM download_jobs
`+predicate+`
`, args...).Scan(
&job.ID, &job.GalleryID, &job.VisitorID, &job.Status, &storageKey, &jobError,
&createdAt, &updatedAt, &completedAt,
)
if errors.Is(err, sql.ErrNoRows) {
return Job{}, ErrNotFound
}
if err != nil {
return Job{}, fmt.Errorf("find download job: %w", err)
}
job.StorageKey = storageKey.String
job.Error = jobError.String
job.CreatedAt = createdAt.String
job.UpdatedAt = updatedAt.String
job.CompletedAt = completedAt.String
return job, nil
}
func (r *Repository) MarkProcessing(ctx context.Context, jobID uuid.UUID) error {
_, err := r.db.ExecContext(ctx, `
UPDATE download_jobs SET status = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2
`, StatusProcessing, jobID)
return err
}
func (r *Repository) MarkReady(ctx context.Context, jobID uuid.UUID, storageKey string) error {
_, err := r.db.ExecContext(ctx, `
UPDATE download_jobs SET status = $1, storage_key = $2, error = NULL,
updated_at = CURRENT_TIMESTAMP, completed_at = CURRENT_TIMESTAMP
WHERE id = $3
`, StatusReady, storageKey, jobID)
return err
}
func (r *Repository) MarkFailed(ctx context.Context, jobID uuid.UUID, message string) error {
_, err := r.db.ExecContext(ctx, `
UPDATE download_jobs SET status = $1, error = $2, updated_at = CURRENT_TIMESTAMP
WHERE id = $3
`, StatusFailed, message, jobID)
return err
}