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
960 lines
23 KiB
Go
960 lines
23 KiB
Go
// 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
|
|
}
|