108 lines
3.2 KiB
Go
108 lines
3.2 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
type ArtistMonitorState string
|
|
|
|
const (
|
|
ArtistMonitored ArtistMonitorState = "monitored"
|
|
ArtistUnmonitored ArtistMonitorState = "unmonitored"
|
|
ArtistExcluded ArtistMonitorState = "excluded"
|
|
)
|
|
|
|
type Artist struct {
|
|
ID string
|
|
ExternalID string
|
|
Name string
|
|
ArtistType string
|
|
Country string
|
|
Genres []string
|
|
ImageURL string
|
|
MonitorState ArtistMonitorState
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
}
|
|
|
|
type ArtistRepository struct {
|
|
pool *pgxpool.Pool
|
|
}
|
|
|
|
func NewArtistRepository(pool *pgxpool.Pool) *ArtistRepository {
|
|
return &ArtistRepository{pool: pool}
|
|
}
|
|
|
|
func (r *ArtistRepository) Create(ctx context.Context, a *Artist) error {
|
|
_, err := r.pool.Exec(ctx,
|
|
`INSERT INTO artists (external_id, name, artist_type, country, genres, image_url, monitor_state)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
ON CONFLICT (external_id) DO UPDATE SET
|
|
name = EXCLUDED.name,
|
|
artist_type = EXCLUDED.artist_type,
|
|
country = EXCLUDED.country,
|
|
genres = EXCLUDED.genres,
|
|
image_url = EXCLUDED.image_url,
|
|
monitor_state = CASE
|
|
WHEN artists.monitor_state = 'excluded' THEN artists.monitor_state
|
|
ELSE EXCLUDED.monitor_state
|
|
END,
|
|
updated_at = NOW()
|
|
RETURNING id, created_at, updated_at`,
|
|
a.ExternalID, a.Name, a.ArtistType, a.Country, a.Genres, a.ImageURL, a.MonitorState,
|
|
)
|
|
if err != nil {
|
|
return fmt.Errorf("creating artist: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r *ArtistRepository) GetByExternalID(ctx context.Context, externalID string) (*Artist, error) {
|
|
a := &Artist{}
|
|
err := r.pool.QueryRow(ctx,
|
|
`SELECT id, external_id, name, artist_type, country, genres, image_url, monitor_state, created_at, updated_at
|
|
FROM artists WHERE external_id = $1`, externalID,
|
|
).Scan(&a.ID, &a.ExternalID, &a.Name, &a.ArtistType, &a.Country, &a.Genres, &a.ImageURL, &a.MonitorState, &a.CreatedAt, &a.UpdatedAt)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("getting artist: %w", err)
|
|
}
|
|
return a, nil
|
|
}
|
|
|
|
func (r *ArtistRepository) GetAll(ctx context.Context) ([]*Artist, error) {
|
|
rows, err := r.pool.Query(ctx,
|
|
`SELECT id, external_id, name, artist_type, country, genres, image_url, monitor_state, created_at, updated_at
|
|
FROM artists ORDER BY name ASC`,
|
|
)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("listing artists: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
var artists []*Artist
|
|
for rows.Next() {
|
|
a := &Artist{}
|
|
if err := rows.Scan(&a.ID, &a.ExternalID, &a.Name, &a.ArtistType, &a.Country, &a.Genres, &a.ImageURL, &a.MonitorState, &a.CreatedAt, &a.UpdatedAt); err != nil {
|
|
return nil, fmt.Errorf("scanning artist: %w", err)
|
|
}
|
|
artists = append(artists, a)
|
|
}
|
|
return artists, nil
|
|
}
|
|
|
|
func (r *ArtistRepository) GetByID(ctx context.Context, id string) (*Artist, error) {
|
|
a := &Artist{}
|
|
err := r.pool.QueryRow(ctx,
|
|
`SELECT id, external_id, name, artist_type, country, genres, image_url, monitor_state, created_at, updated_at
|
|
FROM artists WHERE id = $1`, id,
|
|
).Scan(&a.ID, &a.ExternalID, &a.Name, &a.ArtistType, &a.Country, &a.Genres, &a.ImageURL, &a.MonitorState, &a.CreatedAt, &a.UpdatedAt)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("getting artist: %w", err)
|
|
}
|
|
return a, nil
|
|
}
|