feat: data lifecycle rewrite, download clients, wanted list, and central catalog index
Ships the fresh-start schema cleanup: rebuilt explore catalog index pipeline (dump import, artifact fetch/build, incremental listen-count refresh), a new download subsystem (Lidarr/Prowlarr/qBittorrent/SABnzbd/ slskd/yt-dlp providers, staging, reconciliation, wanted list), and the supporting schema/query/store changes across backend and frontend. Also includes two smaller follow-ups: bump the central index's rebuild-after cadence from 90 to 180 days, and remove the Explore "library only" online/offline toggle entirely (frontend-only, no backend counterpart) rather than carry unused UI/state. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y2Agd9af5hE7qzti2ackiS
This commit is contained in:
@@ -35,7 +35,7 @@ func (q *Queries) CountAudioFilesByLibrary(ctx context.Context, libraryID int64)
|
||||
|
||||
const createAudioFile = `-- name: CreateAudioFile :one
|
||||
INSERT INTO audio_files (file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
RETURNING id, file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id, play_count, last_played, tag_status, group_key
|
||||
RETURNING id, file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id, play_count, last_played, tag_status, group_key, modified_at
|
||||
`
|
||||
|
||||
type CreateAudioFileParams struct {
|
||||
@@ -84,6 +84,7 @@ func (q *Queries) CreateAudioFile(ctx context.Context, arg CreateAudioFileParams
|
||||
&i.LastPlayed,
|
||||
&i.TagStatus,
|
||||
&i.GroupKey,
|
||||
&i.ModifiedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@@ -92,9 +93,9 @@ const createAudioFileWithGroupKey = `-- name: CreateAudioFileWithGroupKey :one
|
||||
INSERT INTO audio_files (
|
||||
file_path, length_milliseconds, file_type_id, recording_id,
|
||||
sample_rate, bit_depth, channels, bitrate, file_size, basename,
|
||||
library_id, group_key, tag_status
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
RETURNING id, file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id, play_count, last_played, tag_status, group_key
|
||||
library_id, group_key, tag_status, modified_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
RETURNING id, file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id, play_count, last_played, tag_status, group_key, modified_at
|
||||
`
|
||||
|
||||
type CreateAudioFileWithGroupKeyParams struct {
|
||||
@@ -111,6 +112,7 @@ type CreateAudioFileWithGroupKeyParams struct {
|
||||
LibraryID int64
|
||||
GroupKey string
|
||||
TagStatus string
|
||||
ModifiedAt int64
|
||||
}
|
||||
|
||||
func (q *Queries) CreateAudioFileWithGroupKey(ctx context.Context, arg CreateAudioFileWithGroupKeyParams) (AudioFile, error) {
|
||||
@@ -128,6 +130,7 @@ func (q *Queries) CreateAudioFileWithGroupKey(ctx context.Context, arg CreateAud
|
||||
arg.LibraryID,
|
||||
arg.GroupKey,
|
||||
arg.TagStatus,
|
||||
arg.ModifiedAt,
|
||||
)
|
||||
var i AudioFile
|
||||
err := row.Scan(
|
||||
@@ -147,6 +150,7 @@ func (q *Queries) CreateAudioFileWithGroupKey(ctx context.Context, arg CreateAud
|
||||
&i.LastPlayed,
|
||||
&i.TagStatus,
|
||||
&i.GroupKey,
|
||||
&i.ModifiedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@@ -203,7 +207,7 @@ func (q *Queries) GetAllAudioFilePaths(ctx context.Context) ([]GetAllAudioFilePa
|
||||
}
|
||||
|
||||
const getAllAudioFiles = `-- name: GetAllAudioFiles :many
|
||||
SELECT id, file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id, play_count, last_played, tag_status, group_key FROM audio_files
|
||||
SELECT id, file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id, play_count, last_played, tag_status, group_key, modified_at FROM audio_files
|
||||
`
|
||||
|
||||
func (q *Queries) GetAllAudioFiles(ctx context.Context) ([]AudioFile, error) {
|
||||
@@ -232,6 +236,7 @@ func (q *Queries) GetAllAudioFiles(ctx context.Context) ([]AudioFile, error) {
|
||||
&i.LastPlayed,
|
||||
&i.TagStatus,
|
||||
&i.GroupKey,
|
||||
&i.ModifiedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -527,7 +532,7 @@ func (q *Queries) GetAllTracksWithFullMetadataByLibrary(ctx context.Context, lib
|
||||
}
|
||||
|
||||
const getAudioFile = `-- name: GetAudioFile :one
|
||||
SELECT id, file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id, play_count, last_played, tag_status, group_key FROM audio_files
|
||||
SELECT id, file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id, play_count, last_played, tag_status, group_key, modified_at FROM audio_files
|
||||
WHERE id = ? LIMIT 1
|
||||
`
|
||||
|
||||
@@ -551,12 +556,13 @@ func (q *Queries) GetAudioFile(ctx context.Context, id int64) (AudioFile, error)
|
||||
&i.LastPlayed,
|
||||
&i.TagStatus,
|
||||
&i.GroupKey,
|
||||
&i.ModifiedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getAudioFileByPath = `-- name: GetAudioFileByPath :one
|
||||
SELECT id, file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id, play_count, last_played, tag_status, group_key FROM audio_files
|
||||
SELECT id, file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id, play_count, last_played, tag_status, group_key, modified_at FROM audio_files
|
||||
WHERE file_path = ? LIMIT 1
|
||||
`
|
||||
|
||||
@@ -580,6 +586,7 @@ func (q *Queries) GetAudioFileByPath(ctx context.Context, filePath string) (Audi
|
||||
&i.LastPlayed,
|
||||
&i.TagStatus,
|
||||
&i.GroupKey,
|
||||
&i.ModifiedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@@ -597,7 +604,7 @@ func (q *Queries) GetAudioFileGroupKey(ctx context.Context, id int64) (string, e
|
||||
}
|
||||
|
||||
const getAudioFilesByLibrary = `-- name: GetAudioFilesByLibrary :many
|
||||
SELECT id, file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id, play_count, last_played, tag_status, group_key FROM audio_files WHERE library_id = ?
|
||||
SELECT id, file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id, play_count, last_played, tag_status, group_key, modified_at FROM audio_files WHERE library_id = ?
|
||||
`
|
||||
|
||||
func (q *Queries) GetAudioFilesByLibrary(ctx context.Context, libraryID int64) ([]AudioFile, error) {
|
||||
@@ -626,6 +633,7 @@ func (q *Queries) GetAudioFilesByLibrary(ctx context.Context, libraryID int64) (
|
||||
&i.LastPlayed,
|
||||
&i.TagStatus,
|
||||
&i.GroupKey,
|
||||
&i.ModifiedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -854,7 +862,7 @@ func (q *Queries) GetAudioFilesByReleaseGroupByLibrary(ctx context.Context, arg
|
||||
}
|
||||
|
||||
const getAudioFilesNeedingMetadata = `-- name: GetAudioFilesNeedingMetadata :many
|
||||
SELECT id, file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id, play_count, last_played, tag_status, group_key FROM audio_files
|
||||
SELECT id, file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id, play_count, last_played, tag_status, group_key, modified_at FROM audio_files
|
||||
WHERE recording_id = 0
|
||||
`
|
||||
|
||||
@@ -884,6 +892,7 @@ func (q *Queries) GetAudioFilesNeedingMetadata(ctx context.Context) ([]AudioFile
|
||||
&i.LastPlayed,
|
||||
&i.TagStatus,
|
||||
&i.GroupKey,
|
||||
&i.ModifiedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -898,6 +907,20 @@ func (q *Queries) GetAudioFilesNeedingMetadata(ctx context.Context) ([]AudioFile
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getLibraryMaxModifiedAt = `-- name: GetLibraryMaxModifiedAt :one
|
||||
SELECT CAST(COALESCE(MAX(modified_at), 0) AS INTEGER) FROM audio_files
|
||||
WHERE library_id = ?
|
||||
`
|
||||
|
||||
// Newest recorded mtime in a library, for the startup soft scan. 0 when
|
||||
// the library is empty or no row has a baseline yet.
|
||||
func (q *Queries) GetLibraryMaxModifiedAt(ctx context.Context, libraryID int64) (int64, error) {
|
||||
row := q.db.QueryRowContext(ctx, getLibraryMaxModifiedAt, libraryID)
|
||||
var column_1 int64
|
||||
err := row.Scan(&column_1)
|
||||
return column_1, err
|
||||
}
|
||||
|
||||
const getRandomAudioFilePath = `-- name: GetRandomAudioFilePath :one
|
||||
SELECT file_path FROM audio_files
|
||||
ORDER BY RANDOM()
|
||||
@@ -1139,18 +1162,20 @@ func (q *Queries) UpdateAudioFile(ctx context.Context, arg UpdateAudioFileParams
|
||||
|
||||
const updateAudioFileRecording = `-- name: UpdateAudioFileRecording :exec
|
||||
UPDATE audio_files
|
||||
SET recording_id = ?, sample_rate = ?, bit_depth = ?, channels = ?, bitrate = ?, file_size = ?
|
||||
SET recording_id = ?, sample_rate = ?, bit_depth = ?, channels = ?, bitrate = ?, file_size = ?, length_milliseconds = ?, modified_at = ?
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
type UpdateAudioFileRecordingParams struct {
|
||||
RecordingID int64
|
||||
SampleRate int64
|
||||
BitDepth int64
|
||||
Channels int64
|
||||
Bitrate int64
|
||||
FileSize int64
|
||||
ID int64
|
||||
RecordingID int64
|
||||
SampleRate int64
|
||||
BitDepth int64
|
||||
Channels int64
|
||||
Bitrate int64
|
||||
FileSize int64
|
||||
LengthMilliseconds int64
|
||||
ModifiedAt int64
|
||||
ID int64
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateAudioFileRecording(ctx context.Context, arg UpdateAudioFileRecordingParams) error {
|
||||
@@ -1161,7 +1186,29 @@ func (q *Queries) UpdateAudioFileRecording(ctx context.Context, arg UpdateAudioF
|
||||
arg.Channels,
|
||||
arg.Bitrate,
|
||||
arg.FileSize,
|
||||
arg.LengthMilliseconds,
|
||||
arg.ModifiedAt,
|
||||
arg.ID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const updateAudioFileStat = `-- name: UpdateAudioFileStat :exec
|
||||
UPDATE audio_files
|
||||
SET modified_at = ?, file_size = ?
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
type UpdateAudioFileStatParams struct {
|
||||
ModifiedAt int64
|
||||
FileSize int64
|
||||
ID int64
|
||||
}
|
||||
|
||||
// Records the on-disk mtime/size without re-reading tags. Used to
|
||||
// backfill the staleness baseline for files the scan skipped, and to
|
||||
// re-baseline after YellowJacket's own tag writer rewrites a file.
|
||||
func (q *Queries) UpdateAudioFileStat(ctx context.Context, arg UpdateAudioFileStatParams) error {
|
||||
_, err := q.db.ExecContext(ctx, updateAudioFileStat, arg.ModifiedAt, arg.FileSize, arg.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -0,0 +1,959 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.30.0
|
||||
// source: download.sql
|
||||
|
||||
package sqlcgen
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
)
|
||||
|
||||
const createDownloadItem = `-- name: CreateDownloadItem :exec
|
||||
INSERT INTO download_items (
|
||||
id, request_id, provider_id, transport_id, external_id,
|
||||
candidate, state, staging_dir, bytes_total
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`
|
||||
|
||||
type CreateDownloadItemParams struct {
|
||||
ID string
|
||||
RequestID string
|
||||
ProviderID int64
|
||||
TransportID sql.NullInt64
|
||||
ExternalID string
|
||||
Candidate string
|
||||
State string
|
||||
StagingDir string
|
||||
BytesTotal int64
|
||||
}
|
||||
|
||||
func (q *Queries) CreateDownloadItem(ctx context.Context, arg CreateDownloadItemParams) error {
|
||||
_, err := q.db.ExecContext(ctx, createDownloadItem,
|
||||
arg.ID,
|
||||
arg.RequestID,
|
||||
arg.ProviderID,
|
||||
arg.TransportID,
|
||||
arg.ExternalID,
|
||||
arg.Candidate,
|
||||
arg.State,
|
||||
arg.StagingDir,
|
||||
arg.BytesTotal,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const createDownloadProvider = `-- name: CreateDownloadProvider :one
|
||||
INSERT INTO download_providers (kind, name, enabled, priority, settings)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
RETURNING id
|
||||
`
|
||||
|
||||
type CreateDownloadProviderParams struct {
|
||||
Kind string
|
||||
Name string
|
||||
Enabled int64
|
||||
Priority int64
|
||||
Settings string
|
||||
}
|
||||
|
||||
func (q *Queries) CreateDownloadProvider(ctx context.Context, arg CreateDownloadProviderParams) (int64, error) {
|
||||
row := q.db.QueryRowContext(ctx, createDownloadProvider,
|
||||
arg.Kind,
|
||||
arg.Name,
|
||||
arg.Enabled,
|
||||
arg.Priority,
|
||||
arg.Settings,
|
||||
)
|
||||
var id int64
|
||||
err := row.Scan(&id)
|
||||
return id, err
|
||||
}
|
||||
|
||||
const createDownloadRequest = `-- name: CreateDownloadRequest :exec
|
||||
INSERT INTO download_requests (
|
||||
id, library_id, source, want_id, release_mbid, release_group_mbid,
|
||||
recording_mbid, artist, album, query, expected, state
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`
|
||||
|
||||
type CreateDownloadRequestParams struct {
|
||||
ID string
|
||||
LibraryID int64
|
||||
Source string
|
||||
WantID sql.NullInt64
|
||||
ReleaseMbid sql.NullString
|
||||
ReleaseGroupMbid sql.NullString
|
||||
RecordingMbid sql.NullString
|
||||
Artist string
|
||||
Album string
|
||||
Query string
|
||||
Expected string
|
||||
State string
|
||||
}
|
||||
|
||||
func (q *Queries) CreateDownloadRequest(ctx context.Context, arg CreateDownloadRequestParams) error {
|
||||
_, err := q.db.ExecContext(ctx, createDownloadRequest,
|
||||
arg.ID,
|
||||
arg.LibraryID,
|
||||
arg.Source,
|
||||
arg.WantID,
|
||||
arg.ReleaseMbid,
|
||||
arg.ReleaseGroupMbid,
|
||||
arg.RecordingMbid,
|
||||
arg.Artist,
|
||||
arg.Album,
|
||||
arg.Query,
|
||||
arg.Expected,
|
||||
arg.State,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteDownloadProvider = `-- name: DeleteDownloadProvider :exec
|
||||
DELETE FROM download_providers
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteDownloadProvider(ctx context.Context, id int64) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteDownloadProvider, id)
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteDownloadRequest = `-- name: DeleteDownloadRequest :exec
|
||||
DELETE FROM download_requests
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteDownloadRequest(ctx context.Context, id string) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteDownloadRequest, id)
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteDownloadWant = `-- name: DeleteDownloadWant :exec
|
||||
DELETE FROM download_wants WHERE id = ?
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteDownloadWant(ctx context.Context, id int64) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteDownloadWant, id)
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteFinishedDownloadRequests = `-- name: DeleteFinishedDownloadRequests :exec
|
||||
DELETE FROM download_requests
|
||||
WHERE state IN ('complete', 'cancelled', 'failed')
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteFinishedDownloadRequests(ctx context.Context) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteFinishedDownloadRequests)
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteSatisfiedDownloadWants = `-- name: DeleteSatisfiedDownloadWants :exec
|
||||
DELETE FROM download_wants WHERE state = 'satisfied'
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteSatisfiedDownloadWants(ctx context.Context) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteSatisfiedDownloadWants)
|
||||
return err
|
||||
}
|
||||
|
||||
const getDownloadItem = `-- name: GetDownloadItem :one
|
||||
SELECT id, request_id, provider_id, transport_id, external_id, candidate,
|
||||
state, staging_dir, bytes_done, bytes_total, imported_paths,
|
||||
error, created_at, updated_at
|
||||
FROM download_items
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
func (q *Queries) GetDownloadItem(ctx context.Context, id string) (DownloadItem, error) {
|
||||
row := q.db.QueryRowContext(ctx, getDownloadItem, id)
|
||||
var i DownloadItem
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.RequestID,
|
||||
&i.ProviderID,
|
||||
&i.TransportID,
|
||||
&i.ExternalID,
|
||||
&i.Candidate,
|
||||
&i.State,
|
||||
&i.StagingDir,
|
||||
&i.BytesDone,
|
||||
&i.BytesTotal,
|
||||
&i.ImportedPaths,
|
||||
&i.Error,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getDownloadProvider = `-- name: GetDownloadProvider :one
|
||||
SELECT id, kind, name, enabled, priority, settings, created_at
|
||||
FROM download_providers
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
func (q *Queries) GetDownloadProvider(ctx context.Context, id int64) (DownloadProvider, error) {
|
||||
row := q.db.QueryRowContext(ctx, getDownloadProvider, id)
|
||||
var i DownloadProvider
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Kind,
|
||||
&i.Name,
|
||||
&i.Enabled,
|
||||
&i.Priority,
|
||||
&i.Settings,
|
||||
&i.CreatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getDownloadRequest = `-- name: GetDownloadRequest :one
|
||||
SELECT id, library_id, source, want_id, release_mbid, release_group_mbid,
|
||||
recording_mbid, artist, album, query, expected, state, error,
|
||||
created_at, updated_at
|
||||
FROM download_requests
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
func (q *Queries) GetDownloadRequest(ctx context.Context, id string) (DownloadRequest, error) {
|
||||
row := q.db.QueryRowContext(ctx, getDownloadRequest, id)
|
||||
var i DownloadRequest
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.LibraryID,
|
||||
&i.Source,
|
||||
&i.WantID,
|
||||
&i.ReleaseMbid,
|
||||
&i.ReleaseGroupMbid,
|
||||
&i.RecordingMbid,
|
||||
&i.Artist,
|
||||
&i.Album,
|
||||
&i.Query,
|
||||
&i.Expected,
|
||||
&i.State,
|
||||
&i.Error,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getDownloadWant = `-- name: GetDownloadWant :one
|
||||
SELECT id, mbid, entity, library_id, artist, title, scope, secondary, state, parent_id, attempts, last_error, last_tried_at, next_try_at, external_ids, created_at, updated_at FROM download_wants WHERE id = ?
|
||||
`
|
||||
|
||||
func (q *Queries) GetDownloadWant(ctx context.Context, id int64) (DownloadWant, error) {
|
||||
row := q.db.QueryRowContext(ctx, getDownloadWant, id)
|
||||
var i DownloadWant
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Mbid,
|
||||
&i.Entity,
|
||||
&i.LibraryID,
|
||||
&i.Artist,
|
||||
&i.Title,
|
||||
&i.Scope,
|
||||
&i.Secondary,
|
||||
&i.State,
|
||||
&i.ParentID,
|
||||
&i.Attempts,
|
||||
&i.LastError,
|
||||
&i.LastTriedAt,
|
||||
&i.NextTryAt,
|
||||
&i.ExternalIds,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getDownloadWantByMBID = `-- name: GetDownloadWantByMBID :one
|
||||
SELECT id, mbid, entity, library_id, artist, title, scope, secondary, state, parent_id, attempts, last_error, last_tried_at, next_try_at, external_ids, created_at, updated_at FROM download_wants WHERE mbid = ? AND library_id = ?
|
||||
`
|
||||
|
||||
type GetDownloadWantByMBIDParams struct {
|
||||
Mbid string
|
||||
LibraryID int64
|
||||
}
|
||||
|
||||
func (q *Queries) GetDownloadWantByMBID(ctx context.Context, arg GetDownloadWantByMBIDParams) (DownloadWant, error) {
|
||||
row := q.db.QueryRowContext(ctx, getDownloadWantByMBID, arg.Mbid, arg.LibraryID)
|
||||
var i DownloadWant
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Mbid,
|
||||
&i.Entity,
|
||||
&i.LibraryID,
|
||||
&i.Artist,
|
||||
&i.Title,
|
||||
&i.Scope,
|
||||
&i.Secondary,
|
||||
&i.State,
|
||||
&i.ParentID,
|
||||
&i.Attempts,
|
||||
&i.LastError,
|
||||
&i.LastTriedAt,
|
||||
&i.NextTryAt,
|
||||
&i.ExternalIds,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const listChildDownloadWants = `-- name: ListChildDownloadWants :many
|
||||
SELECT id, mbid, entity, library_id, artist, title, scope, secondary, state, parent_id, attempts, last_error, last_tried_at, next_try_at, external_ids, created_at, updated_at FROM download_wants WHERE parent_id = ? ORDER BY id
|
||||
`
|
||||
|
||||
func (q *Queries) ListChildDownloadWants(ctx context.Context, parentID sql.NullInt64) ([]DownloadWant, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listChildDownloadWants, parentID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []DownloadWant
|
||||
for rows.Next() {
|
||||
var i DownloadWant
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Mbid,
|
||||
&i.Entity,
|
||||
&i.LibraryID,
|
||||
&i.Artist,
|
||||
&i.Title,
|
||||
&i.Scope,
|
||||
&i.Secondary,
|
||||
&i.State,
|
||||
&i.ParentID,
|
||||
&i.Attempts,
|
||||
&i.LastError,
|
||||
&i.LastTriedAt,
|
||||
&i.NextTryAt,
|
||||
&i.ExternalIds,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listDownloadItemsForRequest = `-- name: ListDownloadItemsForRequest :many
|
||||
SELECT id, request_id, provider_id, transport_id, external_id, candidate,
|
||||
state, staging_dir, bytes_done, bytes_total, imported_paths,
|
||||
error, created_at, updated_at
|
||||
FROM download_items
|
||||
WHERE request_id = ?
|
||||
ORDER BY created_at
|
||||
`
|
||||
|
||||
func (q *Queries) ListDownloadItemsForRequest(ctx context.Context, requestID string) ([]DownloadItem, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listDownloadItemsForRequest, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []DownloadItem
|
||||
for rows.Next() {
|
||||
var i DownloadItem
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.RequestID,
|
||||
&i.ProviderID,
|
||||
&i.TransportID,
|
||||
&i.ExternalID,
|
||||
&i.Candidate,
|
||||
&i.State,
|
||||
&i.StagingDir,
|
||||
&i.BytesDone,
|
||||
&i.BytesTotal,
|
||||
&i.ImportedPaths,
|
||||
&i.Error,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listDownloadProviders = `-- name: ListDownloadProviders :many
|
||||
SELECT id, kind, name, enabled, priority, settings, created_at
|
||||
FROM download_providers
|
||||
ORDER BY priority DESC, name
|
||||
`
|
||||
|
||||
func (q *Queries) ListDownloadProviders(ctx context.Context) ([]DownloadProvider, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listDownloadProviders)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []DownloadProvider
|
||||
for rows.Next() {
|
||||
var i DownloadProvider
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Kind,
|
||||
&i.Name,
|
||||
&i.Enabled,
|
||||
&i.Priority,
|
||||
&i.Settings,
|
||||
&i.CreatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listDownloadRequests = `-- name: ListDownloadRequests :many
|
||||
SELECT id, library_id, source, want_id, release_mbid, release_group_mbid,
|
||||
recording_mbid, artist, album, query, expected, state, error,
|
||||
created_at, updated_at
|
||||
FROM download_requests
|
||||
ORDER BY created_at DESC
|
||||
LIMIT ?
|
||||
`
|
||||
|
||||
func (q *Queries) ListDownloadRequests(ctx context.Context, limit int64) ([]DownloadRequest, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listDownloadRequests, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []DownloadRequest
|
||||
for rows.Next() {
|
||||
var i DownloadRequest
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.LibraryID,
|
||||
&i.Source,
|
||||
&i.WantID,
|
||||
&i.ReleaseMbid,
|
||||
&i.ReleaseGroupMbid,
|
||||
&i.RecordingMbid,
|
||||
&i.Artist,
|
||||
&i.Album,
|
||||
&i.Query,
|
||||
&i.Expected,
|
||||
&i.State,
|
||||
&i.Error,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listDownloadWants = `-- name: ListDownloadWants :many
|
||||
SELECT id, mbid, entity, library_id, artist, title, scope, secondary, state, parent_id, attempts, last_error, last_tried_at, next_try_at, external_ids, created_at, updated_at FROM download_wants
|
||||
ORDER BY
|
||||
CASE state WHEN 'wanted' THEN 0 WHEN 'paused' THEN 1 ELSE 2 END,
|
||||
artist, title
|
||||
`
|
||||
|
||||
func (q *Queries) ListDownloadWants(ctx context.Context) ([]DownloadWant, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listDownloadWants)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []DownloadWant
|
||||
for rows.Next() {
|
||||
var i DownloadWant
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Mbid,
|
||||
&i.Entity,
|
||||
&i.LibraryID,
|
||||
&i.Artist,
|
||||
&i.Title,
|
||||
&i.Scope,
|
||||
&i.Secondary,
|
||||
&i.State,
|
||||
&i.ParentID,
|
||||
&i.Attempts,
|
||||
&i.LastError,
|
||||
&i.LastTriedAt,
|
||||
&i.NextTryAt,
|
||||
&i.ExternalIds,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listDownloadWantsByEntity = `-- name: ListDownloadWantsByEntity :many
|
||||
SELECT id, mbid, entity, library_id, artist, title, scope, secondary, state, parent_id, attempts, last_error, last_tried_at, next_try_at, external_ids, created_at, updated_at FROM download_wants
|
||||
WHERE entity = ? AND state = ?
|
||||
ORDER BY id
|
||||
`
|
||||
|
||||
type ListDownloadWantsByEntityParams struct {
|
||||
Entity string
|
||||
State string
|
||||
}
|
||||
|
||||
func (q *Queries) ListDownloadWantsByEntity(ctx context.Context, arg ListDownloadWantsByEntityParams) ([]DownloadWant, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listDownloadWantsByEntity, arg.Entity, arg.State)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []DownloadWant
|
||||
for rows.Next() {
|
||||
var i DownloadWant
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Mbid,
|
||||
&i.Entity,
|
||||
&i.LibraryID,
|
||||
&i.Artist,
|
||||
&i.Title,
|
||||
&i.Scope,
|
||||
&i.Secondary,
|
||||
&i.State,
|
||||
&i.ParentID,
|
||||
&i.Attempts,
|
||||
&i.LastError,
|
||||
&i.LastTriedAt,
|
||||
&i.NextTryAt,
|
||||
&i.ExternalIds,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listDueDownloadWants = `-- name: ListDueDownloadWants :many
|
||||
SELECT id, mbid, entity, library_id, artist, title, scope, secondary, state, parent_id, attempts, last_error, last_tried_at, next_try_at, external_ids, created_at, updated_at FROM download_wants
|
||||
WHERE state = 'wanted'
|
||||
AND entity <> 'artist'
|
||||
AND (next_try_at IS NULL OR next_try_at <= CURRENT_TIMESTAMP)
|
||||
ORDER BY attempts, created_at
|
||||
LIMIT ?
|
||||
`
|
||||
|
||||
// Everything the reconciler should act on this pass: wanted, not an
|
||||
// artist subscription (those expand rather than download), and either
|
||||
// never tried or past its backoff.
|
||||
func (q *Queries) ListDueDownloadWants(ctx context.Context, limit int64) ([]DownloadWant, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listDueDownloadWants, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []DownloadWant
|
||||
for rows.Next() {
|
||||
var i DownloadWant
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Mbid,
|
||||
&i.Entity,
|
||||
&i.LibraryID,
|
||||
&i.Artist,
|
||||
&i.Title,
|
||||
&i.Scope,
|
||||
&i.Secondary,
|
||||
&i.State,
|
||||
&i.ParentID,
|
||||
&i.Attempts,
|
||||
&i.LastError,
|
||||
&i.LastTriedAt,
|
||||
&i.NextTryAt,
|
||||
&i.ExternalIds,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listLiveDownloadItems = `-- name: ListLiveDownloadItems :many
|
||||
SELECT id, request_id, provider_id, transport_id, external_id, candidate,
|
||||
state, staging_dir, bytes_done, bytes_total, imported_paths,
|
||||
error, created_at, updated_at
|
||||
FROM download_items
|
||||
WHERE state NOT IN ('complete', 'cancelled', 'failed')
|
||||
ORDER BY created_at
|
||||
`
|
||||
|
||||
func (q *Queries) ListLiveDownloadItems(ctx context.Context) ([]DownloadItem, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listLiveDownloadItems)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []DownloadItem
|
||||
for rows.Next() {
|
||||
var i DownloadItem
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.RequestID,
|
||||
&i.ProviderID,
|
||||
&i.TransportID,
|
||||
&i.ExternalID,
|
||||
&i.Candidate,
|
||||
&i.State,
|
||||
&i.StagingDir,
|
||||
&i.BytesDone,
|
||||
&i.BytesTotal,
|
||||
&i.ImportedPaths,
|
||||
&i.Error,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listLiveDownloadRequests = `-- name: ListLiveDownloadRequests :many
|
||||
SELECT id, library_id, source, want_id, release_mbid, release_group_mbid,
|
||||
recording_mbid, artist, album, query, expected, state, error,
|
||||
created_at, updated_at
|
||||
FROM download_requests
|
||||
WHERE state NOT IN ('complete', 'cancelled', 'failed')
|
||||
ORDER BY created_at
|
||||
`
|
||||
|
||||
func (q *Queries) ListLiveDownloadRequests(ctx context.Context) ([]DownloadRequest, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listLiveDownloadRequests)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []DownloadRequest
|
||||
for rows.Next() {
|
||||
var i DownloadRequest
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.LibraryID,
|
||||
&i.Source,
|
||||
&i.WantID,
|
||||
&i.ReleaseMbid,
|
||||
&i.ReleaseGroupMbid,
|
||||
&i.RecordingMbid,
|
||||
&i.Artist,
|
||||
&i.Album,
|
||||
&i.Query,
|
||||
&i.Expected,
|
||||
&i.State,
|
||||
&i.Error,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const recordDownloadWantAttempt = `-- name: RecordDownloadWantAttempt :exec
|
||||
UPDATE download_wants
|
||||
SET attempts = attempts + 1,
|
||||
last_error = ?,
|
||||
last_tried_at = CURRENT_TIMESTAMP,
|
||||
next_try_at = ?,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
type RecordDownloadWantAttemptParams struct {
|
||||
LastError string
|
||||
NextTryAt sql.NullTime
|
||||
ID int64
|
||||
}
|
||||
|
||||
func (q *Queries) RecordDownloadWantAttempt(ctx context.Context, arg RecordDownloadWantAttemptParams) error {
|
||||
_, err := q.db.ExecContext(ctx, recordDownloadWantAttempt, arg.LastError, arg.NextTryAt, arg.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
const satisfyDownloadWant = `-- name: SatisfyDownloadWant :exec
|
||||
UPDATE download_wants
|
||||
SET state = 'satisfied', last_error = '', next_try_at = NULL,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
func (q *Queries) SatisfyDownloadWant(ctx context.Context, id int64) error {
|
||||
_, err := q.db.ExecContext(ctx, satisfyDownloadWant, id)
|
||||
return err
|
||||
}
|
||||
|
||||
const setDownloadItemExternalID = `-- name: SetDownloadItemExternalID :exec
|
||||
UPDATE download_items
|
||||
SET external_id = ?, updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
type SetDownloadItemExternalIDParams struct {
|
||||
ExternalID string
|
||||
ID string
|
||||
}
|
||||
|
||||
func (q *Queries) SetDownloadItemExternalID(ctx context.Context, arg SetDownloadItemExternalIDParams) error {
|
||||
_, err := q.db.ExecContext(ctx, setDownloadItemExternalID, arg.ExternalID, arg.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
const setDownloadItemImported = `-- name: SetDownloadItemImported :exec
|
||||
UPDATE download_items
|
||||
SET imported_paths = ?, state = 'complete', error = '',
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
type SetDownloadItemImportedParams struct {
|
||||
ImportedPaths string
|
||||
ID string
|
||||
}
|
||||
|
||||
func (q *Queries) SetDownloadItemImported(ctx context.Context, arg SetDownloadItemImportedParams) error {
|
||||
_, err := q.db.ExecContext(ctx, setDownloadItemImported, arg.ImportedPaths, arg.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
const setDownloadItemProgress = `-- name: SetDownloadItemProgress :exec
|
||||
UPDATE download_items
|
||||
SET bytes_done = ?, bytes_total = ?, updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
type SetDownloadItemProgressParams struct {
|
||||
BytesDone int64
|
||||
BytesTotal int64
|
||||
ID string
|
||||
}
|
||||
|
||||
func (q *Queries) SetDownloadItemProgress(ctx context.Context, arg SetDownloadItemProgressParams) error {
|
||||
_, err := q.db.ExecContext(ctx, setDownloadItemProgress, arg.BytesDone, arg.BytesTotal, arg.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
const setDownloadItemState = `-- name: SetDownloadItemState :exec
|
||||
UPDATE download_items
|
||||
SET state = ?, error = ?, updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
type SetDownloadItemStateParams struct {
|
||||
State string
|
||||
Error string
|
||||
ID string
|
||||
}
|
||||
|
||||
func (q *Queries) SetDownloadItemState(ctx context.Context, arg SetDownloadItemStateParams) error {
|
||||
_, err := q.db.ExecContext(ctx, setDownloadItemState, arg.State, arg.Error, arg.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
const setDownloadRequestState = `-- name: SetDownloadRequestState :exec
|
||||
UPDATE download_requests
|
||||
SET state = ?, error = ?, updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
type SetDownloadRequestStateParams struct {
|
||||
State string
|
||||
Error string
|
||||
ID string
|
||||
}
|
||||
|
||||
func (q *Queries) SetDownloadRequestState(ctx context.Context, arg SetDownloadRequestStateParams) error {
|
||||
_, err := q.db.ExecContext(ctx, setDownloadRequestState, arg.State, arg.Error, arg.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
const setDownloadWantExternalIDs = `-- name: SetDownloadWantExternalIDs :exec
|
||||
UPDATE download_wants
|
||||
SET external_ids = ?, updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
type SetDownloadWantExternalIDsParams struct {
|
||||
ExternalIds string
|
||||
ID int64
|
||||
}
|
||||
|
||||
func (q *Queries) SetDownloadWantExternalIDs(ctx context.Context, arg SetDownloadWantExternalIDsParams) error {
|
||||
_, err := q.db.ExecContext(ctx, setDownloadWantExternalIDs, arg.ExternalIds, arg.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
const setDownloadWantState = `-- name: SetDownloadWantState :exec
|
||||
UPDATE download_wants
|
||||
SET state = ?, last_error = ?, updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
type SetDownloadWantStateParams struct {
|
||||
State string
|
||||
LastError string
|
||||
ID int64
|
||||
}
|
||||
|
||||
func (q *Queries) SetDownloadWantState(ctx context.Context, arg SetDownloadWantStateParams) error {
|
||||
_, err := q.db.ExecContext(ctx, setDownloadWantState, arg.State, arg.LastError, arg.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
const updateDownloadProvider = `-- name: UpdateDownloadProvider :exec
|
||||
UPDATE download_providers
|
||||
SET name = ?, enabled = ?, priority = ?, settings = ?
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
type UpdateDownloadProviderParams struct {
|
||||
Name string
|
||||
Enabled int64
|
||||
Priority int64
|
||||
Settings string
|
||||
ID int64
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateDownloadProvider(ctx context.Context, arg UpdateDownloadProviderParams) error {
|
||||
_, err := q.db.ExecContext(ctx, updateDownloadProvider,
|
||||
arg.Name,
|
||||
arg.Enabled,
|
||||
arg.Priority,
|
||||
arg.Settings,
|
||||
arg.ID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const upsertDownloadWant = `-- name: UpsertDownloadWant :one
|
||||
|
||||
INSERT INTO download_wants (
|
||||
mbid, entity, library_id, artist, title, scope, secondary,
|
||||
parent_id, next_try_at
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
|
||||
ON CONFLICT(mbid, library_id) DO UPDATE SET
|
||||
artist = CASE WHEN excluded.artist <> '' THEN excluded.artist
|
||||
ELSE download_wants.artist END,
|
||||
title = CASE WHEN excluded.title <> '' THEN excluded.title
|
||||
ELSE download_wants.title END,
|
||||
scope = excluded.scope,
|
||||
secondary = excluded.secondary,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
RETURNING id
|
||||
`
|
||||
|
||||
type UpsertDownloadWantParams struct {
|
||||
Mbid string
|
||||
Entity string
|
||||
LibraryID int64
|
||||
Artist string
|
||||
Title string
|
||||
Scope string
|
||||
Secondary int64
|
||||
ParentID sql.NullInt64
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Wants
|
||||
// ---------------------------------------------------------------------
|
||||
// Adding something already wanted is not an error and must not reset
|
||||
// the retry clock, so the conflict path only refreshes display text and
|
||||
// un-pauses nothing. scope and secondary are updated because asking
|
||||
// again with a wider scope is a real change of intent.
|
||||
func (q *Queries) UpsertDownloadWant(ctx context.Context, arg UpsertDownloadWantParams) (int64, error) {
|
||||
row := q.db.QueryRowContext(ctx, upsertDownloadWant,
|
||||
arg.Mbid,
|
||||
arg.Entity,
|
||||
arg.LibraryID,
|
||||
arg.Artist,
|
||||
arg.Title,
|
||||
arg.Scope,
|
||||
arg.Secondary,
|
||||
arg.ParentID,
|
||||
)
|
||||
var id int64
|
||||
err := row.Scan(&id)
|
||||
return id, err
|
||||
}
|
||||
@@ -26,6 +26,20 @@ type ArtistCreditArtist struct {
|
||||
CreditID int64
|
||||
}
|
||||
|
||||
type ArtistImage struct {
|
||||
ID int64
|
||||
ArtistMbid string
|
||||
Source string
|
||||
SourceUrl string
|
||||
FilePath string
|
||||
IsPrimary int64
|
||||
SortOrder int64
|
||||
Width sql.NullInt64
|
||||
Height sql.NullInt64
|
||||
FileSize sql.NullInt64
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type ArtistMetadatum struct {
|
||||
Mbid string
|
||||
Source string
|
||||
@@ -50,6 +64,7 @@ type AudioFile struct {
|
||||
LastPlayed sql.NullTime
|
||||
TagStatus string
|
||||
GroupKey string
|
||||
ModifiedAt int64
|
||||
}
|
||||
|
||||
type CoverArt struct {
|
||||
@@ -59,6 +74,116 @@ type CoverArt struct {
|
||||
MimeType string
|
||||
}
|
||||
|
||||
type DownloadItem struct {
|
||||
ID string
|
||||
RequestID string
|
||||
ProviderID int64
|
||||
TransportID sql.NullInt64
|
||||
ExternalID string
|
||||
Candidate string
|
||||
State string
|
||||
StagingDir string
|
||||
BytesDone int64
|
||||
BytesTotal int64
|
||||
ImportedPaths string
|
||||
Error string
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
type DownloadProvider struct {
|
||||
ID int64
|
||||
Kind string
|
||||
Name string
|
||||
Enabled int64
|
||||
Priority int64
|
||||
Settings string
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type DownloadRequest struct {
|
||||
ID string
|
||||
LibraryID int64
|
||||
Source string
|
||||
WantID sql.NullInt64
|
||||
ReleaseMbid sql.NullString
|
||||
ReleaseGroupMbid sql.NullString
|
||||
RecordingMbid sql.NullString
|
||||
Artist string
|
||||
Album string
|
||||
Query string
|
||||
Expected string
|
||||
State string
|
||||
Error string
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
type DownloadWant struct {
|
||||
ID int64
|
||||
Mbid string
|
||||
Entity string
|
||||
LibraryID int64
|
||||
Artist string
|
||||
Title string
|
||||
Scope string
|
||||
Secondary int64
|
||||
State string
|
||||
ParentID sql.NullInt64
|
||||
Attempts int64
|
||||
LastError string
|
||||
LastTriedAt sql.NullTime
|
||||
NextTryAt sql.NullTime
|
||||
ExternalIds string
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
type ExploreChampionFt struct {
|
||||
Title string
|
||||
ArtistName string
|
||||
Aliases string
|
||||
}
|
||||
|
||||
type ExploreIndex struct {
|
||||
ID int64
|
||||
EntityType string
|
||||
Mbid string
|
||||
Title string
|
||||
ArtistName string
|
||||
ArtistMbid string
|
||||
Aliases string
|
||||
Popularity int64
|
||||
ListenerCount int64
|
||||
Duration int64
|
||||
CaaReleaseMbid string
|
||||
ReleaseName string
|
||||
PrimaryType string
|
||||
SecondaryTypes string
|
||||
ReleaseDate string
|
||||
ArtistType string
|
||||
Country string
|
||||
Disambiguation string
|
||||
SortName string
|
||||
InLibrary int64
|
||||
IsSimilar int64
|
||||
LocalArtistID sql.NullInt64
|
||||
LocalReleaseGroupID sql.NullInt64
|
||||
LocalRecordingID sql.NullInt64
|
||||
DiscogFetched int64
|
||||
}
|
||||
|
||||
type ExploreIndexFt struct {
|
||||
Title string
|
||||
ArtistName string
|
||||
Aliases string
|
||||
}
|
||||
|
||||
type ExploreIndexMetum struct {
|
||||
Key string
|
||||
Value string
|
||||
}
|
||||
|
||||
type FileType struct {
|
||||
ID int64
|
||||
Extension string
|
||||
@@ -176,10 +301,10 @@ type ReleaseGroup struct {
|
||||
CoverArtID sql.NullInt64
|
||||
AlbumArtistCreditID sql.NullInt64
|
||||
Year sql.NullInt64
|
||||
OriginalYear sql.NullInt64
|
||||
TotalTracks sql.NullInt64
|
||||
TotalDiscs sql.NullInt64
|
||||
Mbid sql.NullString
|
||||
OriginalYear sql.NullInt64
|
||||
}
|
||||
|
||||
type ReleaseGroupRecording struct {
|
||||
@@ -190,6 +315,19 @@ type ReleaseGroupRecording struct {
|
||||
DiscNumber sql.NullInt64
|
||||
}
|
||||
|
||||
type ReleaseToRg struct {
|
||||
ReleaseMbid string
|
||||
RgMbid string
|
||||
}
|
||||
|
||||
type SearchClick struct {
|
||||
Query string
|
||||
EntityMbid string
|
||||
EntityType string
|
||||
ClickCount int64
|
||||
LastClicked time.Time
|
||||
}
|
||||
|
||||
type SearchIndex struct {
|
||||
FilePath string
|
||||
Title string
|
||||
@@ -197,6 +335,13 @@ type SearchIndex struct {
|
||||
Album string
|
||||
}
|
||||
|
||||
type SimilarArtistMap struct {
|
||||
SourceArtistMbid string
|
||||
SimilarArtistMbid string
|
||||
SimilarArtistName string
|
||||
Score int64
|
||||
}
|
||||
|
||||
type TaggingCandidate struct {
|
||||
GroupKey string
|
||||
Candidates string
|
||||
|
||||
@@ -23,7 +23,7 @@ func (q *Queries) CountReleaseGroupRecordings(ctx context.Context, releaseGroupI
|
||||
|
||||
const createReleaseGroup = `-- name: CreateReleaseGroup :one
|
||||
INSERT INTO release_groups (name) VALUES (?)
|
||||
RETURNING id, name, cover_art_id, album_artist_credit_id, year, original_year, total_tracks, total_discs, mbid
|
||||
RETURNING id, name, cover_art_id, album_artist_credit_id, year, total_tracks, total_discs, mbid, original_year
|
||||
`
|
||||
|
||||
func (q *Queries) CreateReleaseGroup(ctx context.Context, name string) (ReleaseGroup, error) {
|
||||
@@ -35,10 +35,10 @@ func (q *Queries) CreateReleaseGroup(ctx context.Context, name string) (ReleaseG
|
||||
&i.CoverArtID,
|
||||
&i.AlbumArtistCreditID,
|
||||
&i.Year,
|
||||
&i.OriginalYear,
|
||||
&i.TotalTracks,
|
||||
&i.TotalDiscs,
|
||||
&i.Mbid,
|
||||
&i.OriginalYear,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@@ -47,7 +47,7 @@ const createReleaseGroupFull = `-- name: CreateReleaseGroupFull :one
|
||||
INSERT INTO release_groups (
|
||||
name, cover_art_id, album_artist_credit_id, year, total_tracks, total_discs
|
||||
) VALUES (?, ?, ?, ?, ?, ?)
|
||||
RETURNING id, name, cover_art_id, album_artist_credit_id, year, original_year, total_tracks, total_discs, mbid
|
||||
RETURNING id, name, cover_art_id, album_artist_credit_id, year, total_tracks, total_discs, mbid, original_year
|
||||
`
|
||||
|
||||
type CreateReleaseGroupFullParams struct {
|
||||
@@ -75,10 +75,10 @@ func (q *Queries) CreateReleaseGroupFull(ctx context.Context, arg CreateReleaseG
|
||||
&i.CoverArtID,
|
||||
&i.AlbumArtistCreditID,
|
||||
&i.Year,
|
||||
&i.OriginalYear,
|
||||
&i.TotalTracks,
|
||||
&i.TotalDiscs,
|
||||
&i.Mbid,
|
||||
&i.OriginalYear,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@@ -432,7 +432,7 @@ func (q *Queries) GetAllAlbumsWithDetailsByLibrary(ctx context.Context, libraryI
|
||||
}
|
||||
|
||||
const getAllReleaseGroups = `-- name: GetAllReleaseGroups :many
|
||||
SELECT id, name, cover_art_id, album_artist_credit_id, year, original_year, total_tracks, total_discs, mbid FROM release_groups
|
||||
SELECT id, name, cover_art_id, album_artist_credit_id, year, total_tracks, total_discs, mbid, original_year FROM release_groups
|
||||
ORDER BY name
|
||||
`
|
||||
|
||||
@@ -451,10 +451,10 @@ func (q *Queries) GetAllReleaseGroups(ctx context.Context) ([]ReleaseGroup, erro
|
||||
&i.CoverArtID,
|
||||
&i.AlbumArtistCreditID,
|
||||
&i.Year,
|
||||
&i.OriginalYear,
|
||||
&i.TotalTracks,
|
||||
&i.TotalDiscs,
|
||||
&i.Mbid,
|
||||
&i.OriginalYear,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -470,7 +470,7 @@ func (q *Queries) GetAllReleaseGroups(ctx context.Context) ([]ReleaseGroup, erro
|
||||
}
|
||||
|
||||
const getReleaseGroup = `-- name: GetReleaseGroup :one
|
||||
SELECT id, name, cover_art_id, album_artist_credit_id, year, original_year, total_tracks, total_discs, mbid FROM release_groups
|
||||
SELECT id, name, cover_art_id, album_artist_credit_id, year, total_tracks, total_discs, mbid, original_year FROM release_groups
|
||||
WHERE id = ? LIMIT 1
|
||||
`
|
||||
|
||||
@@ -483,16 +483,16 @@ func (q *Queries) GetReleaseGroup(ctx context.Context, id int64) (ReleaseGroup,
|
||||
&i.CoverArtID,
|
||||
&i.AlbumArtistCreditID,
|
||||
&i.Year,
|
||||
&i.OriginalYear,
|
||||
&i.TotalTracks,
|
||||
&i.TotalDiscs,
|
||||
&i.Mbid,
|
||||
&i.OriginalYear,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getReleaseGroupByNameAndArtist = `-- name: GetReleaseGroupByNameAndArtist :one
|
||||
SELECT id, name, cover_art_id, album_artist_credit_id, year, original_year, total_tracks, total_discs, mbid FROM release_groups
|
||||
SELECT id, name, cover_art_id, album_artist_credit_id, year, total_tracks, total_discs, mbid, original_year FROM release_groups
|
||||
WHERE name = ? AND album_artist_credit_id = ? LIMIT 1
|
||||
`
|
||||
|
||||
@@ -510,10 +510,10 @@ func (q *Queries) GetReleaseGroupByNameAndArtist(ctx context.Context, arg GetRel
|
||||
&i.CoverArtID,
|
||||
&i.AlbumArtistCreditID,
|
||||
&i.Year,
|
||||
&i.OriginalYear,
|
||||
&i.TotalTracks,
|
||||
&i.TotalDiscs,
|
||||
&i.Mbid,
|
||||
&i.OriginalYear,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@@ -574,7 +574,7 @@ VALUES (?, ?, ?)
|
||||
ON CONFLICT(name, album_artist_credit_id) DO UPDATE SET
|
||||
album_artist_credit_id = COALESCE(excluded.album_artist_credit_id, release_groups.album_artist_credit_id),
|
||||
year = COALESCE(excluded.year, release_groups.year)
|
||||
RETURNING id, name, cover_art_id, album_artist_credit_id, year, original_year, total_tracks, total_discs, mbid
|
||||
RETURNING id, name, cover_art_id, album_artist_credit_id, year, total_tracks, total_discs, mbid, original_year
|
||||
`
|
||||
|
||||
type UpsertReleaseGroupParams struct {
|
||||
@@ -592,10 +592,10 @@ func (q *Queries) UpsertReleaseGroup(ctx context.Context, arg UpsertReleaseGroup
|
||||
&i.CoverArtID,
|
||||
&i.AlbumArtistCreditID,
|
||||
&i.Year,
|
||||
&i.OriginalYear,
|
||||
&i.TotalTracks,
|
||||
&i.TotalDiscs,
|
||||
&i.Mbid,
|
||||
&i.OriginalYear,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user