feat(db): add user-context track query variants honoring quarantine
This commit is contained in:
@@ -34,6 +34,10 @@ WHERE t.id <> $2
|
|||||||
WHERE user_id = $1 AND track_id = t.id
|
WHERE user_id = $1 AND track_id = t.id
|
||||||
AND started_at > now() - $3 * interval '1 hour'
|
AND started_at > now() - $3 * interval '1 hour'
|
||||||
)
|
)
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1 FROM lidarr_quarantine q
|
||||||
|
WHERE q.user_id = $1 AND q.track_id = t.id
|
||||||
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
type LoadRadioCandidatesParams struct {
|
type LoadRadioCandidatesParams struct {
|
||||||
@@ -117,6 +121,10 @@ excluded_ids AS (
|
|||||||
SELECT pe.track_id AS id
|
SELECT pe.track_id AS id
|
||||||
FROM play_events pe
|
FROM play_events pe
|
||||||
WHERE pe.user_id = $1 AND pe.started_at > now() - $3 * interval '1 hour'
|
WHERE pe.user_id = $1 AND pe.started_at > now() - $3 * interval '1 hour'
|
||||||
|
UNION ALL
|
||||||
|
SELECT q.track_id AS id
|
||||||
|
FROM lidarr_quarantine q
|
||||||
|
WHERE q.user_id = $1
|
||||||
),
|
),
|
||||||
lb_similar AS (
|
lb_similar AS (
|
||||||
SELECT ts.track_b_id AS track_id, ts.score AS sim_score
|
SELECT ts.track_b_id AS track_id, ts.score AS sim_score
|
||||||
|
|||||||
@@ -33,6 +33,28 @@ func (q *Queries) CountTracksMatching(ctx context.Context, dollar_1 string) (int
|
|||||||
return count, err
|
return count, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const countTracksMatchingForUser = `-- name: CountTracksMatchingForUser :one
|
||||||
|
SELECT COUNT(*) FROM tracks
|
||||||
|
WHERE title ILIKE '%' || $1::text || '%'
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1 FROM lidarr_quarantine q
|
||||||
|
WHERE q.user_id = $2 AND q.track_id = tracks.id
|
||||||
|
)
|
||||||
|
`
|
||||||
|
|
||||||
|
type CountTracksMatchingForUserParams struct {
|
||||||
|
Column1 string
|
||||||
|
UserID pgtype.UUID
|
||||||
|
}
|
||||||
|
|
||||||
|
// $1 = title query, $2 = user_id.
|
||||||
|
func (q *Queries) CountTracksMatchingForUser(ctx context.Context, arg CountTracksMatchingForUserParams) (int64, error) {
|
||||||
|
row := q.db.QueryRow(ctx, countTracksMatchingForUser, arg.Column1, arg.UserID)
|
||||||
|
var count int64
|
||||||
|
err := row.Scan(&count)
|
||||||
|
return count, err
|
||||||
|
}
|
||||||
|
|
||||||
const getTrackByID = `-- name: GetTrackByID :one
|
const getTrackByID = `-- name: GetTrackByID :one
|
||||||
SELECT id, title, album_id, artist_id, track_number, disc_number, duration_ms, file_path, file_size, file_format, bitrate, mbid, genre, added_at, updated_at FROM tracks WHERE id = $1
|
SELECT id, title, album_id, artist_id, track_number, disc_number, duration_ms, file_path, file_size, file_format, bitrate, mbid, genre, added_at, updated_at FROM tracks WHERE id = $1
|
||||||
`
|
`
|
||||||
@@ -127,6 +149,59 @@ func (q *Queries) ListTracksByAlbum(ctx context.Context, albumID pgtype.UUID) ([
|
|||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const listTracksByAlbumForUser = `-- name: ListTracksByAlbumForUser :many
|
||||||
|
SELECT id, title, album_id, artist_id, track_number, disc_number, duration_ms, file_path, file_size, file_format, bitrate, mbid, genre, added_at, updated_at FROM tracks
|
||||||
|
WHERE album_id = $1
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1 FROM lidarr_quarantine q
|
||||||
|
WHERE q.user_id = $2 AND q.track_id = tracks.id
|
||||||
|
)
|
||||||
|
ORDER BY disc_number NULLS LAST, track_number NULLS LAST
|
||||||
|
`
|
||||||
|
|
||||||
|
type ListTracksByAlbumForUserParams struct {
|
||||||
|
AlbumID pgtype.UUID
|
||||||
|
UserID pgtype.UUID
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same as ListTracksByAlbum but excludes tracks the user has quarantined.
|
||||||
|
// $1 = album_id, $2 = user_id.
|
||||||
|
func (q *Queries) ListTracksByAlbumForUser(ctx context.Context, arg ListTracksByAlbumForUserParams) ([]Track, error) {
|
||||||
|
rows, err := q.db.Query(ctx, listTracksByAlbumForUser, arg.AlbumID, arg.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []Track
|
||||||
|
for rows.Next() {
|
||||||
|
var i Track
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.Title,
|
||||||
|
&i.AlbumID,
|
||||||
|
&i.ArtistID,
|
||||||
|
&i.TrackNumber,
|
||||||
|
&i.DiscNumber,
|
||||||
|
&i.DurationMs,
|
||||||
|
&i.FilePath,
|
||||||
|
&i.FileSize,
|
||||||
|
&i.FileFormat,
|
||||||
|
&i.Bitrate,
|
||||||
|
&i.Mbid,
|
||||||
|
&i.Genre,
|
||||||
|
&i.AddedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
const searchTracks = `-- name: SearchTracks :many
|
const searchTracks = `-- name: SearchTracks :many
|
||||||
SELECT id, title, album_id, artist_id, track_number, disc_number, duration_ms, file_path, file_size, file_format, bitrate, mbid, genre, added_at, updated_at FROM tracks
|
SELECT id, title, album_id, artist_id, track_number, disc_number, duration_ms, file_path, file_size, file_format, bitrate, mbid, genre, added_at, updated_at FROM tracks
|
||||||
WHERE title ILIKE '%' || $1 || '%'
|
WHERE title ILIKE '%' || $1 || '%'
|
||||||
@@ -176,6 +251,66 @@ func (q *Queries) SearchTracks(ctx context.Context, arg SearchTracksParams) ([]T
|
|||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const searchTracksForUser = `-- name: SearchTracksForUser :many
|
||||||
|
SELECT id, title, album_id, artist_id, track_number, disc_number, duration_ms, file_path, file_size, file_format, bitrate, mbid, genre, added_at, updated_at FROM tracks
|
||||||
|
WHERE title ILIKE '%' || $1 || '%'
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1 FROM lidarr_quarantine q
|
||||||
|
WHERE q.user_id = $2 AND q.track_id = tracks.id
|
||||||
|
)
|
||||||
|
ORDER BY title
|
||||||
|
LIMIT $3 OFFSET $4
|
||||||
|
`
|
||||||
|
|
||||||
|
type SearchTracksForUserParams struct {
|
||||||
|
Column1 *string
|
||||||
|
UserID pgtype.UUID
|
||||||
|
Limit int32
|
||||||
|
Offset int32
|
||||||
|
}
|
||||||
|
|
||||||
|
// $1 = title query, $2 = user_id, $3 = limit, $4 = offset.
|
||||||
|
func (q *Queries) SearchTracksForUser(ctx context.Context, arg SearchTracksForUserParams) ([]Track, error) {
|
||||||
|
rows, err := q.db.Query(ctx, searchTracksForUser,
|
||||||
|
arg.Column1,
|
||||||
|
arg.UserID,
|
||||||
|
arg.Limit,
|
||||||
|
arg.Offset,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []Track
|
||||||
|
for rows.Next() {
|
||||||
|
var i Track
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.Title,
|
||||||
|
&i.AlbumID,
|
||||||
|
&i.ArtistID,
|
||||||
|
&i.TrackNumber,
|
||||||
|
&i.DiscNumber,
|
||||||
|
&i.DurationMs,
|
||||||
|
&i.FilePath,
|
||||||
|
&i.FileSize,
|
||||||
|
&i.FileFormat,
|
||||||
|
&i.Bitrate,
|
||||||
|
&i.Mbid,
|
||||||
|
&i.Genre,
|
||||||
|
&i.AddedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
const upsertTrack = `-- name: UpsertTrack :one
|
const upsertTrack = `-- name: UpsertTrack :one
|
||||||
INSERT INTO tracks (
|
INSERT INTO tracks (
|
||||||
title, album_id, artist_id, track_number, disc_number,
|
title, album_id, artist_id, track_number, disc_number,
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ WHERE t.id <> $2
|
|||||||
SELECT 1 FROM play_events
|
SELECT 1 FROM play_events
|
||||||
WHERE user_id = $1 AND track_id = t.id
|
WHERE user_id = $1 AND track_id = t.id
|
||||||
AND started_at > now() - $3 * interval '1 hour'
|
AND started_at > now() - $3 * interval '1 hour'
|
||||||
|
)
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1 FROM lidarr_quarantine q
|
||||||
|
WHERE q.user_id = $1 AND q.track_id = t.id
|
||||||
);
|
);
|
||||||
|
|
||||||
-- name: LoadRadioCandidatesV2 :many
|
-- name: LoadRadioCandidatesV2 :many
|
||||||
@@ -53,6 +57,10 @@ excluded_ids AS (
|
|||||||
SELECT pe.track_id AS id
|
SELECT pe.track_id AS id
|
||||||
FROM play_events pe
|
FROM play_events pe
|
||||||
WHERE pe.user_id = $1 AND pe.started_at > now() - $3 * interval '1 hour'
|
WHERE pe.user_id = $1 AND pe.started_at > now() - $3 * interval '1 hour'
|
||||||
|
UNION ALL
|
||||||
|
SELECT q.track_id AS id
|
||||||
|
FROM lidarr_quarantine q
|
||||||
|
WHERE q.user_id = $1
|
||||||
),
|
),
|
||||||
lb_similar AS (
|
lb_similar AS (
|
||||||
SELECT ts.track_b_id AS track_id, ts.score AS sim_score
|
SELECT ts.track_b_id AS track_id, ts.score AS sim_score
|
||||||
|
|||||||
@@ -39,3 +39,34 @@ LIMIT $2 OFFSET $3;
|
|||||||
|
|
||||||
-- name: CountTracksMatching :one
|
-- name: CountTracksMatching :one
|
||||||
SELECT COUNT(*) FROM tracks WHERE title ILIKE '%' || $1::text || '%';
|
SELECT COUNT(*) FROM tracks WHERE title ILIKE '%' || $1::text || '%';
|
||||||
|
|
||||||
|
-- name: ListTracksByAlbumForUser :many
|
||||||
|
-- Same as ListTracksByAlbum but excludes tracks the user has quarantined.
|
||||||
|
-- $1 = album_id, $2 = user_id.
|
||||||
|
SELECT * FROM tracks
|
||||||
|
WHERE album_id = $1
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1 FROM lidarr_quarantine q
|
||||||
|
WHERE q.user_id = $2 AND q.track_id = tracks.id
|
||||||
|
)
|
||||||
|
ORDER BY disc_number NULLS LAST, track_number NULLS LAST;
|
||||||
|
|
||||||
|
-- name: SearchTracksForUser :many
|
||||||
|
-- $1 = title query, $2 = user_id, $3 = limit, $4 = offset.
|
||||||
|
SELECT * FROM tracks
|
||||||
|
WHERE title ILIKE '%' || $1 || '%'
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1 FROM lidarr_quarantine q
|
||||||
|
WHERE q.user_id = $2 AND q.track_id = tracks.id
|
||||||
|
)
|
||||||
|
ORDER BY title
|
||||||
|
LIMIT $3 OFFSET $4;
|
||||||
|
|
||||||
|
-- name: CountTracksMatchingForUser :one
|
||||||
|
-- $1 = title query, $2 = user_id.
|
||||||
|
SELECT COUNT(*) FROM tracks
|
||||||
|
WHERE title ILIKE '%' || $1::text || '%'
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1 FROM lidarr_quarantine q
|
||||||
|
WHERE q.user_id = $2 AND q.track_id = tracks.id
|
||||||
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user