Rewrites the internal/db/queries comments to rule 32 and regenerates dbq, whose doc comments and embedded SQL carry them. The bugs behind the tiered mixes, the md5 order seed, the score bands and the round-robin arms are restated as the constraint each one enforces; counts from one library and stale cross-references are gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
681 lines
18 KiB
Go
681 lines
18 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.31.1
|
|
// source: search.sql
|
|
|
|
package dbq
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
const blockRelease = `-- name: BlockRelease :exec
|
|
INSERT INTO release_blocks (info_hash, name, reason, detail, want_id, blocked_by, expires_at)
|
|
VALUES ($1, $2, $3, $4,
|
|
$5, $6, $7)
|
|
ON CONFLICT (info_hash) DO UPDATE
|
|
SET reason = EXCLUDED.reason, detail = EXCLUDED.detail, blocked_at = now(),
|
|
expires_at = EXCLUDED.expires_at, blocked_by = EXCLUDED.blocked_by
|
|
WHERE release_blocks.expires_at IS NOT NULL OR EXCLUDED.expires_at IS NULL
|
|
`
|
|
|
|
type BlockReleaseParams struct {
|
|
InfoHash string
|
|
Name string
|
|
Reason string
|
|
Detail string
|
|
WantID pgtype.UUID
|
|
BlockedBy pgtype.UUID
|
|
ExpiresAt pgtype.Timestamptz
|
|
}
|
|
|
|
// A release set aside. expires_at NULL is for good. A block for good is never
|
|
// shortened by a timed one: only a timed block, or another for good, is
|
|
// replaced.
|
|
func (q *Queries) BlockRelease(ctx context.Context, arg BlockReleaseParams) error {
|
|
_, err := q.db.Exec(ctx, blockRelease,
|
|
arg.InfoHash,
|
|
arg.Name,
|
|
arg.Reason,
|
|
arg.Detail,
|
|
arg.WantID,
|
|
arg.BlockedBy,
|
|
arg.ExpiresAt,
|
|
)
|
|
return err
|
|
}
|
|
|
|
const deleteWantCandidates = `-- name: DeleteWantCandidates :exec
|
|
DELETE FROM want_candidates WHERE want_id = $1
|
|
`
|
|
|
|
func (q *Queries) DeleteWantCandidates(ctx context.Context, wantID pgtype.UUID) error {
|
|
_, err := q.db.Exec(ctx, deleteWantCandidates, wantID)
|
|
return err
|
|
}
|
|
|
|
const editionTrackSpan = `-- name: EditionTrackSpan :one
|
|
SELECT COALESCE(MIN(track_count) FILTER (WHERE status = 'Official'), MIN(track_count), 0)::int AS min_tracks,
|
|
COALESCE(MAX(track_count), 0)::int AS max_tracks
|
|
FROM mb_releases
|
|
WHERE release_group_mbid = $1 AND track_count > 0
|
|
`
|
|
|
|
type EditionTrackSpanRow struct {
|
|
MinTracks int32
|
|
MaxTracks int32
|
|
}
|
|
|
|
// The fewest tracks an official edition of the group has (any edition when
|
|
// none is official), and the most any has. Zero when none is catalogued.
|
|
func (q *Queries) EditionTrackSpan(ctx context.Context, releaseGroupMbid string) (EditionTrackSpanRow, error) {
|
|
row := q.db.QueryRow(ctx, editionTrackSpan, releaseGroupMbid)
|
|
var i EditionTrackSpanRow
|
|
err := row.Scan(&i.MinTracks, &i.MaxTracks)
|
|
return i, err
|
|
}
|
|
|
|
const endGrab = `-- name: EndGrab :exec
|
|
UPDATE grabs
|
|
SET ended_at = now(), end_reason = $1, end_detail = $2
|
|
WHERE id = $3 AND ended_at IS NULL
|
|
`
|
|
|
|
type EndGrabParams struct {
|
|
EndReason string
|
|
EndDetail string
|
|
ID pgtype.UUID
|
|
}
|
|
|
|
func (q *Queries) EndGrab(ctx context.Context, arg EndGrabParams) error {
|
|
_, err := q.db.Exec(ctx, endGrab, arg.EndReason, arg.EndDetail, arg.ID)
|
|
return err
|
|
}
|
|
|
|
const getAcquisitionSettings = `-- name: GetAcquisitionSettings :one
|
|
|
|
SELECT id, auto_grab, search_interval_hours, allowed_qualities, last_pass_at, last_pass, updated_at, import_root, seed_ratio, seed_days, stall_hours, library_listing_started_at, library_listed_at, library_unlisted, upgrade_until FROM acquisition_settings WHERE id = true
|
|
`
|
|
|
|
// Searching for wants and grabbing releases.
|
|
func (q *Queries) GetAcquisitionSettings(ctx context.Context) (AcquisitionSetting, error) {
|
|
row := q.db.QueryRow(ctx, getAcquisitionSettings)
|
|
var i AcquisitionSetting
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.AutoGrab,
|
|
&i.SearchIntervalHours,
|
|
&i.AllowedQualities,
|
|
&i.LastPassAt,
|
|
&i.LastPass,
|
|
&i.UpdatedAt,
|
|
&i.ImportRoot,
|
|
&i.SeedRatio,
|
|
&i.SeedDays,
|
|
&i.StallHours,
|
|
&i.LibraryListingStartedAt,
|
|
&i.LibraryListedAt,
|
|
&i.LibraryUnlisted,
|
|
&i.UpgradeUntil,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getLiveGrab = `-- name: GetLiveGrab :one
|
|
SELECT id, want_id, info_hash, name, key, indexer, source, client, save_path, quality, origin, forced, grabbed_by, grabbed_at, ended_at, end_reason, end_detail, progress, import_state, import_reason, import_detail, import_forced, import_attempts, import_updated_at, imported_at, imported_files, destination, seeding, ratio, seed_released_at FROM grabs WHERE want_id = $1 AND ended_at IS NULL
|
|
`
|
|
|
|
func (q *Queries) GetLiveGrab(ctx context.Context, wantID pgtype.UUID) (Grab, error) {
|
|
row := q.db.QueryRow(ctx, getLiveGrab, wantID)
|
|
var i Grab
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.WantID,
|
|
&i.InfoHash,
|
|
&i.Name,
|
|
&i.Key,
|
|
&i.Indexer,
|
|
&i.Source,
|
|
&i.Client,
|
|
&i.SavePath,
|
|
&i.Quality,
|
|
&i.Origin,
|
|
&i.Forced,
|
|
&i.GrabbedBy,
|
|
&i.GrabbedAt,
|
|
&i.EndedAt,
|
|
&i.EndReason,
|
|
&i.EndDetail,
|
|
&i.Progress,
|
|
&i.ImportState,
|
|
&i.ImportReason,
|
|
&i.ImportDetail,
|
|
&i.ImportForced,
|
|
&i.ImportAttempts,
|
|
&i.ImportUpdatedAt,
|
|
&i.ImportedAt,
|
|
&i.ImportedFiles,
|
|
&i.Destination,
|
|
&i.Seeding,
|
|
&i.Ratio,
|
|
&i.SeedReleasedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getWantCandidate = `-- name: GetWantCandidate :one
|
|
SELECT want_id, key, name, info_hash, indexer, source, size_bytes, seeders, files_count, format, quality, year, verdict, reason, reasons, folded_from, rank, searched_at FROM want_candidates WHERE want_id = $1 AND key = $2
|
|
`
|
|
|
|
type GetWantCandidateParams struct {
|
|
WantID pgtype.UUID
|
|
Key string
|
|
}
|
|
|
|
func (q *Queries) GetWantCandidate(ctx context.Context, arg GetWantCandidateParams) (WantCandidate, error) {
|
|
row := q.db.QueryRow(ctx, getWantCandidate, arg.WantID, arg.Key)
|
|
var i WantCandidate
|
|
err := row.Scan(
|
|
&i.WantID,
|
|
&i.Key,
|
|
&i.Name,
|
|
&i.InfoHash,
|
|
&i.Indexer,
|
|
&i.Source,
|
|
&i.SizeBytes,
|
|
&i.Seeders,
|
|
&i.FilesCount,
|
|
&i.Format,
|
|
&i.Quality,
|
|
&i.Year,
|
|
&i.Verdict,
|
|
&i.Reason,
|
|
&i.Reasons,
|
|
&i.FoldedFrom,
|
|
&i.Rank,
|
|
&i.SearchedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getWantForSearch = `-- name: GetWantForSearch :one
|
|
SELECT w.id, w.release_group_mbid, w.artist_mbid, w.artist_name, w.title, w.reason, w.fulfilled_at,
|
|
w.upgrade, w.held_tier, w.held_quality, w.album_id,
|
|
COALESCE(NULLIF(w.primary_type, ''), g.primary_type, '')::text AS primary_type,
|
|
COALESCE(g.secondary_types, '{}')::text[] AS secondary_types,
|
|
COALESCE(NULLIF(w.first_release_date, ''), g.first_release_date, '')::text AS first_release_date
|
|
FROM wants w
|
|
LEFT JOIN mb_release_groups g ON g.mbid = w.release_group_mbid
|
|
WHERE w.id = $1
|
|
`
|
|
|
|
type GetWantForSearchRow struct {
|
|
ID pgtype.UUID
|
|
ReleaseGroupMbid string
|
|
ArtistMbid string
|
|
ArtistName string
|
|
Title string
|
|
Reason string
|
|
FulfilledAt pgtype.Timestamptz
|
|
Upgrade string
|
|
HeldTier string
|
|
HeldQuality string
|
|
AlbumID pgtype.UUID
|
|
PrimaryType string
|
|
SecondaryTypes []string
|
|
FirstReleaseDate string
|
|
}
|
|
|
|
func (q *Queries) GetWantForSearch(ctx context.Context, id pgtype.UUID) (GetWantForSearchRow, error) {
|
|
row := q.db.QueryRow(ctx, getWantForSearch, id)
|
|
var i GetWantForSearchRow
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.ReleaseGroupMbid,
|
|
&i.ArtistMbid,
|
|
&i.ArtistName,
|
|
&i.Title,
|
|
&i.Reason,
|
|
&i.FulfilledAt,
|
|
&i.Upgrade,
|
|
&i.HeldTier,
|
|
&i.HeldQuality,
|
|
&i.AlbumID,
|
|
&i.PrimaryType,
|
|
&i.SecondaryTypes,
|
|
&i.FirstReleaseDate,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const insertGrab = `-- name: InsertGrab :one
|
|
INSERT INTO grabs (want_id, info_hash, name, key, indexer, source, client, save_path, quality,
|
|
origin, forced, grabbed_by)
|
|
VALUES ($1, $2, $3, $4, $5,
|
|
$6, $7, $8, $9,
|
|
$10, $11, $12)
|
|
RETURNING id, want_id, info_hash, name, key, indexer, source, client, save_path, quality, origin, forced, grabbed_by, grabbed_at, ended_at, end_reason, end_detail, progress, import_state, import_reason, import_detail, import_forced, import_attempts, import_updated_at, imported_at, imported_files, destination, seeding, ratio, seed_released_at
|
|
`
|
|
|
|
type InsertGrabParams struct {
|
|
WantID pgtype.UUID
|
|
InfoHash string
|
|
Name string
|
|
Key string
|
|
Indexer string
|
|
Source string
|
|
Client string
|
|
SavePath string
|
|
Quality string
|
|
Origin string
|
|
Forced bool
|
|
GrabbedBy pgtype.UUID
|
|
}
|
|
|
|
func (q *Queries) InsertGrab(ctx context.Context, arg InsertGrabParams) (Grab, error) {
|
|
row := q.db.QueryRow(ctx, insertGrab,
|
|
arg.WantID,
|
|
arg.InfoHash,
|
|
arg.Name,
|
|
arg.Key,
|
|
arg.Indexer,
|
|
arg.Source,
|
|
arg.Client,
|
|
arg.SavePath,
|
|
arg.Quality,
|
|
arg.Origin,
|
|
arg.Forced,
|
|
arg.GrabbedBy,
|
|
)
|
|
var i Grab
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.WantID,
|
|
&i.InfoHash,
|
|
&i.Name,
|
|
&i.Key,
|
|
&i.Indexer,
|
|
&i.Source,
|
|
&i.Client,
|
|
&i.SavePath,
|
|
&i.Quality,
|
|
&i.Origin,
|
|
&i.Forced,
|
|
&i.GrabbedBy,
|
|
&i.GrabbedAt,
|
|
&i.EndedAt,
|
|
&i.EndReason,
|
|
&i.EndDetail,
|
|
&i.Progress,
|
|
&i.ImportState,
|
|
&i.ImportReason,
|
|
&i.ImportDetail,
|
|
&i.ImportForced,
|
|
&i.ImportAttempts,
|
|
&i.ImportUpdatedAt,
|
|
&i.ImportedAt,
|
|
&i.ImportedFiles,
|
|
&i.Destination,
|
|
&i.Seeding,
|
|
&i.Ratio,
|
|
&i.SeedReleasedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const insertWantCandidate = `-- name: InsertWantCandidate :exec
|
|
INSERT INTO want_candidates (want_id, key, name, info_hash, indexer, source, size_bytes, seeders,
|
|
files_count, format, quality, year, verdict, reason, reasons, folded_from, rank)
|
|
VALUES ($1, $2, $3, $4, $5,
|
|
$6, $7, $8, $9, $10,
|
|
$11, $12, $13, $14, $15,
|
|
$16, $17)
|
|
ON CONFLICT (want_id, key) DO NOTHING
|
|
`
|
|
|
|
type InsertWantCandidateParams struct {
|
|
WantID pgtype.UUID
|
|
Key string
|
|
Name string
|
|
InfoHash string
|
|
Indexer string
|
|
Source string
|
|
SizeBytes int64
|
|
Seeders int32
|
|
FilesCount int32
|
|
Format string
|
|
Quality string
|
|
Year int32
|
|
Verdict string
|
|
Reason string
|
|
Reasons []byte
|
|
FoldedFrom []string
|
|
Rank int32
|
|
}
|
|
|
|
func (q *Queries) InsertWantCandidate(ctx context.Context, arg InsertWantCandidateParams) error {
|
|
_, err := q.db.Exec(ctx, insertWantCandidate,
|
|
arg.WantID,
|
|
arg.Key,
|
|
arg.Name,
|
|
arg.InfoHash,
|
|
arg.Indexer,
|
|
arg.Source,
|
|
arg.SizeBytes,
|
|
arg.Seeders,
|
|
arg.FilesCount,
|
|
arg.Format,
|
|
arg.Quality,
|
|
arg.Year,
|
|
arg.Verdict,
|
|
arg.Reason,
|
|
arg.Reasons,
|
|
arg.FoldedFrom,
|
|
arg.Rank,
|
|
)
|
|
return err
|
|
}
|
|
|
|
const listReleaseBlocks = `-- name: ListReleaseBlocks :many
|
|
SELECT info_hash, name, reason, detail, want_id, blocked_by, blocked_at, expires_at FROM release_blocks
|
|
WHERE expires_at IS NULL OR expires_at > now()
|
|
ORDER BY blocked_at DESC
|
|
`
|
|
|
|
// Every release set aside and still held back: a stalled one lifts by itself
|
|
// at expires_at.
|
|
func (q *Queries) ListReleaseBlocks(ctx context.Context) ([]ReleaseBlock, error) {
|
|
rows, err := q.db.Query(ctx, listReleaseBlocks)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ReleaseBlock
|
|
for rows.Next() {
|
|
var i ReleaseBlock
|
|
if err := rows.Scan(
|
|
&i.InfoHash,
|
|
&i.Name,
|
|
&i.Reason,
|
|
&i.Detail,
|
|
&i.WantID,
|
|
&i.BlockedBy,
|
|
&i.BlockedAt,
|
|
&i.ExpiresAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listWantCandidates = `-- name: ListWantCandidates :many
|
|
SELECT want_id, key, name, info_hash, indexer, source, size_bytes, seeders, files_count, format, quality, year, verdict, reason, reasons, folded_from, rank, searched_at FROM want_candidates WHERE want_id = $1 ORDER BY rank, key
|
|
`
|
|
|
|
func (q *Queries) ListWantCandidates(ctx context.Context, wantID pgtype.UUID) ([]WantCandidate, error) {
|
|
rows, err := q.db.Query(ctx, listWantCandidates, wantID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []WantCandidate
|
|
for rows.Next() {
|
|
var i WantCandidate
|
|
if err := rows.Scan(
|
|
&i.WantID,
|
|
&i.Key,
|
|
&i.Name,
|
|
&i.InfoHash,
|
|
&i.Indexer,
|
|
&i.Source,
|
|
&i.SizeBytes,
|
|
&i.Seeders,
|
|
&i.FilesCount,
|
|
&i.Format,
|
|
&i.Quality,
|
|
&i.Year,
|
|
&i.Verdict,
|
|
&i.Reason,
|
|
&i.Reasons,
|
|
&i.FoldedFrom,
|
|
&i.Rank,
|
|
&i.SearchedAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listWantsDueForSearch = `-- name: ListWantsDueForSearch :many
|
|
SELECT w.id, w.release_group_mbid, w.artist_name, w.title, w.reason, w.upgrade, w.held_tier, w.held_quality,
|
|
COALESCE(NULLIF(w.primary_type, ''), g.primary_type, '')::text AS primary_type,
|
|
COALESCE(g.secondary_types, '{}')::text[] AS secondary_types,
|
|
COALESCE(NULLIF(w.first_release_date, ''), g.first_release_date, '')::text AS first_release_date
|
|
FROM wants w
|
|
LEFT JOIN mb_release_groups g ON g.mbid = w.release_group_mbid
|
|
WHERE (w.fulfilled_at IS NULL OR w.upgrade <> '')
|
|
AND NOT EXISTS (SELECT 1 FROM grabs gr WHERE gr.want_id = w.id AND gr.ended_at IS NULL)
|
|
AND (w.searched_at IS NULL
|
|
OR w.searched_at < now() - make_interval(hours => CASE WHEN w.fulfilled_at IS NULL
|
|
THEN $1::int
|
|
ELSE GREATEST($1::int, 168) END))
|
|
ORDER BY w.fulfilled_at IS NOT NULL,
|
|
w.searched_at IS NOT NULL,
|
|
CASE w.reason WHEN 'request' THEN 0 WHEN 'missing' THEN 1 ELSE 2 END,
|
|
w.searched_at NULLS FIRST, w.wanted_at, w.id
|
|
LIMIT $2
|
|
`
|
|
|
|
type ListWantsDueForSearchParams struct {
|
|
Hours int32
|
|
MaxRows int32
|
|
}
|
|
|
|
type ListWantsDueForSearchRow struct {
|
|
ID pgtype.UUID
|
|
ReleaseGroupMbid string
|
|
ArtistName string
|
|
Title string
|
|
Reason string
|
|
Upgrade string
|
|
HeldTier string
|
|
HeldQuality string
|
|
PrimaryType string
|
|
SecondaryTypes []string
|
|
FirstReleaseDate string
|
|
}
|
|
|
|
// Wants with no download running that were never searched or not since
|
|
// @hours ago: open wants first (never-searched, then requests, then missing
|
|
// files, then followed artists' releases), then held albums wanted for an
|
|
// upgrade, which are searched at most weekly.
|
|
func (q *Queries) ListWantsDueForSearch(ctx context.Context, arg ListWantsDueForSearchParams) ([]ListWantsDueForSearchRow, error) {
|
|
rows, err := q.db.Query(ctx, listWantsDueForSearch, arg.Hours, arg.MaxRows)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ListWantsDueForSearchRow
|
|
for rows.Next() {
|
|
var i ListWantsDueForSearchRow
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.ReleaseGroupMbid,
|
|
&i.ArtistName,
|
|
&i.Title,
|
|
&i.Reason,
|
|
&i.Upgrade,
|
|
&i.HeldTier,
|
|
&i.HeldQuality,
|
|
&i.PrimaryType,
|
|
&i.SecondaryTypes,
|
|
&i.FirstReleaseDate,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const markCandidatesBlocked = `-- name: MarkCandidatesBlocked :exec
|
|
UPDATE want_candidates
|
|
SET verdict = 'blocked', reason = $1,
|
|
reasons = jsonb_build_array(jsonb_build_object('kind', 'hard', 'code', 'blocked', 'text', $1::text))
|
|
WHERE info_hash = $2
|
|
`
|
|
|
|
type MarkCandidatesBlockedParams struct {
|
|
Reason string
|
|
InfoHash string
|
|
}
|
|
|
|
func (q *Queries) MarkCandidatesBlocked(ctx context.Context, arg MarkCandidatesBlockedParams) error {
|
|
_, err := q.db.Exec(ctx, markCandidatesBlocked, arg.Reason, arg.InfoHash)
|
|
return err
|
|
}
|
|
|
|
const markCandidatesUnblocked = `-- name: MarkCandidatesUnblocked :exec
|
|
UPDATE want_candidates
|
|
SET verdict = 'review', reason = $1,
|
|
reasons = jsonb_build_array(jsonb_build_object('kind', 'soft', 'code', 'unblocked', 'text', $1::text))
|
|
WHERE info_hash = $2 AND verdict = 'blocked'
|
|
`
|
|
|
|
type MarkCandidatesUnblockedParams struct {
|
|
Reason string
|
|
InfoHash string
|
|
}
|
|
|
|
func (q *Queries) MarkCandidatesUnblocked(ctx context.Context, arg MarkCandidatesUnblockedParams) error {
|
|
_, err := q.db.Exec(ctx, markCandidatesUnblocked, arg.Reason, arg.InfoHash)
|
|
return err
|
|
}
|
|
|
|
const recordSearchPass = `-- name: RecordSearchPass :exec
|
|
UPDATE acquisition_settings SET last_pass_at = now(), last_pass = $1 WHERE id = true
|
|
`
|
|
|
|
func (q *Queries) RecordSearchPass(ctx context.Context, report []byte) error {
|
|
_, err := q.db.Exec(ctx, recordSearchPass, report)
|
|
return err
|
|
}
|
|
|
|
const recordWantSearch = `-- name: RecordWantSearch :exec
|
|
UPDATE wants
|
|
SET searched_at = now(),
|
|
search_outcome = $1,
|
|
search_considered = $2,
|
|
best_release = $3,
|
|
best_verdict = $4,
|
|
search_error = $5,
|
|
updated_at = now()
|
|
WHERE id = $6
|
|
`
|
|
|
|
type RecordWantSearchParams struct {
|
|
Outcome string
|
|
Considered int32
|
|
BestRelease string
|
|
BestVerdict string
|
|
SearchError string
|
|
ID pgtype.UUID
|
|
}
|
|
|
|
func (q *Queries) RecordWantSearch(ctx context.Context, arg RecordWantSearchParams) error {
|
|
_, err := q.db.Exec(ctx, recordWantSearch,
|
|
arg.Outcome,
|
|
arg.Considered,
|
|
arg.BestRelease,
|
|
arg.BestVerdict,
|
|
arg.SearchError,
|
|
arg.ID,
|
|
)
|
|
return err
|
|
}
|
|
|
|
const unblockRelease = `-- name: UnblockRelease :execrows
|
|
DELETE FROM release_blocks WHERE info_hash = $1
|
|
`
|
|
|
|
func (q *Queries) UnblockRelease(ctx context.Context, infoHash string) (int64, error) {
|
|
result, err := q.db.Exec(ctx, unblockRelease, infoHash)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return result.RowsAffected(), nil
|
|
}
|
|
|
|
const updateAcquisitionSettings = `-- name: UpdateAcquisitionSettings :one
|
|
UPDATE acquisition_settings
|
|
SET auto_grab = $1,
|
|
search_interval_hours = $2,
|
|
allowed_qualities = $3,
|
|
import_root = $4,
|
|
seed_ratio = $5,
|
|
seed_days = $6,
|
|
stall_hours = $7,
|
|
upgrade_until = $8,
|
|
updated_at = now()
|
|
WHERE id = true
|
|
RETURNING id, auto_grab, search_interval_hours, allowed_qualities, last_pass_at, last_pass, updated_at, import_root, seed_ratio, seed_days, stall_hours, library_listing_started_at, library_listed_at, library_unlisted, upgrade_until
|
|
`
|
|
|
|
type UpdateAcquisitionSettingsParams struct {
|
|
AutoGrab bool
|
|
SearchIntervalHours int32
|
|
AllowedQualities []string
|
|
ImportRoot string
|
|
SeedRatio float32
|
|
SeedDays int32
|
|
StallHours int32
|
|
UpgradeUntil string
|
|
}
|
|
|
|
func (q *Queries) UpdateAcquisitionSettings(ctx context.Context, arg UpdateAcquisitionSettingsParams) (AcquisitionSetting, error) {
|
|
row := q.db.QueryRow(ctx, updateAcquisitionSettings,
|
|
arg.AutoGrab,
|
|
arg.SearchIntervalHours,
|
|
arg.AllowedQualities,
|
|
arg.ImportRoot,
|
|
arg.SeedRatio,
|
|
arg.SeedDays,
|
|
arg.StallHours,
|
|
arg.UpgradeUntil,
|
|
)
|
|
var i AcquisitionSetting
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.AutoGrab,
|
|
&i.SearchIntervalHours,
|
|
&i.AllowedQualities,
|
|
&i.LastPassAt,
|
|
&i.LastPass,
|
|
&i.UpdatedAt,
|
|
&i.ImportRoot,
|
|
&i.SeedRatio,
|
|
&i.SeedDays,
|
|
&i.StallHours,
|
|
&i.LibraryListingStartedAt,
|
|
&i.LibraryListedAt,
|
|
&i.LibraryUnlisted,
|
|
&i.UpgradeUntil,
|
|
)
|
|
return i, err
|
|
}
|