105 lines
3.7 KiB
Go
105 lines
3.7 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
type Torrent struct {
|
|
ID string
|
|
AlbumID string
|
|
InfoHash string
|
|
Tracker string
|
|
Title string
|
|
Format string
|
|
Quality string
|
|
Source string
|
|
BitDepth int
|
|
SampleRate int
|
|
Seeders int
|
|
Peers int
|
|
Size int64
|
|
TrackCount int
|
|
HasCoverArt bool
|
|
HasCueSheet bool
|
|
HasRipLog bool
|
|
DownloadLink string
|
|
TorrentFile []byte
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
}
|
|
|
|
type TorrentRepository struct {
|
|
pool *pgxpool.Pool
|
|
}
|
|
|
|
func NewTorrentRepository(pool *pgxpool.Pool) *TorrentRepository {
|
|
return &TorrentRepository{pool: pool}
|
|
}
|
|
|
|
func (r *TorrentRepository) Create(ctx context.Context, t *Torrent) error {
|
|
_, err := r.pool.Exec(ctx,
|
|
`INSERT INTO torrents (album_id, info_hash, tracker, title, format, quality, source, bit_depth, sample_rate, seeders, peers, size, track_count, has_cover_art, has_cue_sheet, has_rip_log, download_link, torrent_file)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)
|
|
ON CONFLICT (info_hash) DO UPDATE SET
|
|
seeders = EXCLUDED.seeders,
|
|
peers = EXCLUDED.peers,
|
|
updated_at = NOW()`,
|
|
t.AlbumID, t.InfoHash, t.Tracker, t.Title, t.Format, t.Quality, t.Source, t.BitDepth, t.SampleRate, t.Seeders, t.Peers, t.Size, t.TrackCount, t.HasCoverArt, t.HasCueSheet, t.HasRipLog, t.DownloadLink, t.TorrentFile,
|
|
)
|
|
if err != nil {
|
|
return fmt.Errorf("creating torrent: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r *TorrentRepository) GetByInfoHash(ctx context.Context, infoHash string) (*Torrent, error) {
|
|
t := &Torrent{}
|
|
err := r.pool.QueryRow(ctx,
|
|
`SELECT id, album_id, info_hash, tracker, title, format, quality, source, bit_depth, sample_rate, seeders, peers, size, track_count, has_cover_art, has_cue_sheet, has_rip_log, download_link, torrent_file, created_at, updated_at
|
|
FROM torrents WHERE info_hash = $1`, infoHash,
|
|
).Scan(&t.ID, &t.AlbumID, &t.InfoHash, &t.Tracker, &t.Title, &t.Format, &t.Quality, &t.Source, &t.BitDepth, &t.SampleRate, &t.Seeders, &t.Peers, &t.Size, &t.TrackCount, &t.HasCoverArt, &t.HasCueSheet, &t.HasRipLog, &t.DownloadLink, &t.TorrentFile, &t.CreatedAt, &t.UpdatedAt)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("getting torrent: %w", err)
|
|
}
|
|
return t, nil
|
|
}
|
|
|
|
func (r *TorrentRepository) GetByAlbumID(ctx context.Context, albumID string) ([]*Torrent, error) {
|
|
rows, err := r.pool.Query(ctx,
|
|
`SELECT id, album_id, info_hash, tracker, title, format, quality, source, bit_depth, sample_rate, seeders, peers, size, track_count, has_cover_art, has_cue_sheet, has_rip_log, download_link, torrent_file, created_at, updated_at
|
|
FROM torrents WHERE album_id = $1 ORDER BY seeders DESC`, albumID,
|
|
)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("listing torrents: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
var torrents []*Torrent
|
|
for rows.Next() {
|
|
t := &Torrent{}
|
|
if err := rows.Scan(&t.ID, &t.AlbumID, &t.InfoHash, &t.Tracker, &t.Title, &t.Format, &t.Quality, &t.Source, &t.BitDepth, &t.SampleRate, &t.Seeders, &t.Peers, &t.Size, &t.TrackCount, &t.HasCoverArt, &t.HasCueSheet, &t.HasRipLog, &t.DownloadLink, &t.TorrentFile, &t.CreatedAt, &t.UpdatedAt); err != nil {
|
|
return nil, fmt.Errorf("scanning torrent: %w", err)
|
|
}
|
|
torrents = append(torrents, t)
|
|
}
|
|
return torrents, nil
|
|
}
|
|
|
|
func (r *TorrentRepository) HasAlbumInFormat(ctx context.Context, albumID string, format string) (bool, error) {
|
|
var exists bool
|
|
err := r.pool.QueryRow(ctx,
|
|
`SELECT EXISTS(
|
|
SELECT 1 FROM downloads
|
|
WHERE album_id = $1 AND format = $2 AND state IN ('completed', 'seeding')
|
|
)`, albumID, format,
|
|
).Scan(&exists)
|
|
if err != nil {
|
|
return false, fmt.Errorf("checking album format: %w", err)
|
|
}
|
|
return exists, nil
|
|
}
|