package database import ( "context" "fmt" "time" "github.com/jackc/pgx/v5/pgxpool" ) type Track struct { ID string ExternalID string AlbumID string Title string DurationMS int ISRC string DiscNumber int TrackNumber int CreatedAt time.Time } type TrackRepository struct { pool *pgxpool.Pool } func NewTrackRepository(pool *pgxpool.Pool) *TrackRepository { return &TrackRepository{pool: pool} } func (r *TrackRepository) Create(ctx context.Context, t *Track) error { _, err := r.pool.Exec(ctx, `INSERT INTO tracks (external_id, album_id, title, duration_ms, isrc, disc_number, track_number) VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT (external_id) DO UPDATE SET title = EXCLUDED.title, duration_ms = EXCLUDED.duration_ms, isrc = EXCLUDED.isrc, disc_number = EXCLUDED.disc_number, track_number = EXCLUDED.track_number`, t.ExternalID, t.AlbumID, t.Title, t.DurationMS, t.ISRC, t.DiscNumber, t.TrackNumber, ) if err != nil { return fmt.Errorf("creating track: %w", err) } return nil } func (r *TrackRepository) GetByAlbumID(ctx context.Context, albumID string) ([]*Track, error) { rows, err := r.pool.Query(ctx, `SELECT id, external_id, album_id, title, duration_ms, isrc, disc_number, track_number, created_at FROM tracks WHERE album_id = $1 ORDER BY disc_number, track_number`, albumID, ) if err != nil { return nil, fmt.Errorf("listing tracks: %w", err) } defer rows.Close() var tracks []*Track for rows.Next() { t := &Track{} if err := rows.Scan(&t.ID, &t.ExternalID, &t.AlbumID, &t.Title, &t.DurationMS, &t.ISRC, &t.DiscNumber, &t.TrackNumber, &t.CreatedAt); err != nil { return nil, fmt.Errorf("scanning track: %w", err) } tracks = append(tracks, t) } return tracks, nil }