init
This commit is contained in:
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user