Add database schema, ERD, and repository layer
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user