Files
thamanyah/discovery/internal/db/repositories/videos.go
T
FahdShalhoub 6f9e04ee97
Build, Push and Deploy CMS / build-push-deploy (push) Successful in 2m35s
Build, Push and Deploy Discovery / build-push-deploy (push) Successful in 1m55s
Deploy Infrastructure / pulumi-up (push) Successful in 2s
FEAT: Discovery Video Service Subscription
2026-08-29 16:50:58 +03:00

60 lines
1.8 KiB
Go

package repositories
import (
"context"
"database/sql"
"errors"
"thamanyah/discovery/internal/models"
"github.com/lib/pq"
)
type VideoRepository struct {
SQLDB *sql.DB
}
var VideoRepo VideoRepository
// SaveVideo records an announced video, replacing what the catalogue already
// held for that id.
//
// The upsert is what makes the consumer safe to retry: the catalogue topic
// delivers at-least-once, so the same announcement can arrive twice, and a
// plain INSERT would fail the second time on the primary key. Re-announcing a
// video is also how it is corrected — a later announcement wins, which is why
// every column is overwritten rather than merged.
func (svc VideoRepository) SaveVideo(ctx context.Context, v models.Video) error {
_, err := svc.SQLDB.ExecContext(ctx, `
INSERT INTO videos (id, title, playback_url, categories)
VALUES ($1, $2, $3, $4)
ON CONFLICT (id) DO UPDATE
SET title = EXCLUDED.title,
playback_url = EXCLUDED.playback_url,
categories = EXCLUDED.categories,
updated_at = now()
`, v.ID, v.Title, v.PlaybackURL, pq.Array(v.Categories))
return err
}
// GetVideoByID reads the catalogue's copy of one video. It returns
// ErrVideoNotFound when the catalogue has not heard about it — which, for a
// video cms has only just made ready, is a matter of timing rather than a
// mistake.
func (svc VideoRepository) GetVideoByID(ctx context.Context, id string) (models.Video, error) {
var v models.Video
err := svc.SQLDB.QueryRowContext(ctx, `
SELECT id, title, playback_url, categories, created_at, updated_at
FROM videos
WHERE id = $1
`, id).Scan(&v.ID, &v.Title, &v.PlaybackURL, pq.Array(&v.Categories), &v.CreatedAt, &v.UpdatedAt)
if errors.Is(err, sql.ErrNoRows) {
return models.Video{}, ErrVideoNotFound
}
if err != nil {
return models.Video{}, err
}
return v, nil
}