chore: initial public commit

This commit is contained in:
Gabe Farrell 2025-06-11 19:45:39 -04:00
commit fc9054b78c
250 changed files with 32809 additions and 0 deletions

65
db/queries/alias.sql Normal file
View file

@ -0,0 +1,65 @@
-- name: InsertArtistAlias :exec
INSERT INTO artist_aliases (artist_id, alias, source, is_primary)
VALUES ($1, $2, $3, $4)
ON CONFLICT DO NOTHING;
-- name: GetAllArtistAliases :many
SELECT * FROM artist_aliases
WHERE artist_id = $1 ORDER BY is_primary DESC;
-- name: GetArtistAlias :one
SELECT * FROM artist_aliases
WHERE alias = $1 LIMIT 1;
-- name: SetArtistAliasPrimaryStatus :exec
UPDATE artist_aliases SET is_primary = $1 WHERE artist_id = $2 AND alias = $3;
-- name: DeleteArtistAlias :exec
DELETE FROM artist_aliases
WHERE artist_id = $1
AND alias = $2
AND is_primary = false;
-- name: InsertReleaseAlias :exec
INSERT INTO release_aliases (release_id, alias, source, is_primary)
VALUES ($1, $2, $3, $4)
ON CONFLICT DO NOTHING;
-- name: GetAllReleaseAliases :many
SELECT * FROM release_aliases
WHERE release_id = $1 ORDER BY is_primary DESC;
-- name: GetReleaseAlias :one
SELECT * FROM release_aliases
WHERE alias = $1 LIMIT 1;
-- name: SetReleaseAliasPrimaryStatus :exec
UPDATE release_aliases SET is_primary = $1 WHERE release_id = $2 AND alias = $3;
-- name: DeleteReleaseAlias :exec
DELETE FROM release_aliases
WHERE release_id = $1
AND alias = $2
AND is_primary = false;
-- name: InsertTrackAlias :exec
INSERT INTO track_aliases (track_id, alias, source, is_primary)
VALUES ($1, $2, $3, $4)
ON CONFLICT DO NOTHING;
-- name: GetAllTrackAliases :many
SELECT * FROM track_aliases
WHERE track_id = $1 ORDER BY is_primary DESC;
-- name: GetTrackAlias :one
SELECT * FROM track_aliases
WHERE alias = $1 LIMIT 1;
-- name: SetTrackAliasPrimaryStatus :exec
UPDATE track_aliases SET is_primary = $1 WHERE track_id = $2 AND alias = $3;
-- name: DeleteTrackAlias :exec
DELETE FROM track_aliases
WHERE track_id = $1
AND alias = $2
AND is_primary = false;

112
db/queries/artist.sql Normal file
View file

@ -0,0 +1,112 @@
-- name: InsertArtist :one
INSERT INTO artists (musicbrainz_id, image, image_source)
VALUES ($1, $2, $3)
RETURNING *;
-- name: GetArtist :one
SELECT
a.*,
array_agg(aa.alias)::text[] AS aliases
FROM artists_with_name a
LEFT JOIN artist_aliases aa ON a.id = aa.artist_id
WHERE a.id = $1
GROUP BY a.id, a.musicbrainz_id, a.image, a.image_source, a.name;
-- name: GetTrackArtists :many
SELECT
a.*
FROM artists_with_name a
LEFT JOIN artist_tracks at ON a.id = at.artist_id
WHERE at.track_id = $1
GROUP BY a.id, a.musicbrainz_id, a.image, a.image_source, a.name;
-- name: GetArtistByImage :one
SELECT * FROM artists WHERE image = $1 LIMIT 1;
-- name: GetReleaseArtists :many
SELECT
a.*
FROM artists_with_name a
LEFT JOIN artist_releases ar ON a.id = ar.artist_id
WHERE ar.release_id = $1
GROUP BY a.id, a.musicbrainz_id, a.image, a.image_source, a.name;
-- name: GetArtistByName :one
WITH artist_with_aliases AS (
SELECT
a.*,
COALESCE(array_agg(aa.alias), '{}')::text[] AS aliases
FROM artists_with_name a
LEFT JOIN artist_aliases aa ON a.id = aa.artist_id
WHERE a.id IN (
SELECT aa2.artist_id FROM artist_aliases aa2 WHERE aa2.alias = $1
)
GROUP BY a.id, a.musicbrainz_id, a.image, a.image_source, a.name
)
SELECT * FROM artist_with_aliases;
-- name: GetArtistByMbzID :one
SELECT
a.*,
array_agg(aa.alias)::text[] AS aliases
FROM artists_with_name a
LEFT JOIN artist_aliases aa ON a.id = aa.artist_id
WHERE a.musicbrainz_id = $1
GROUP BY a.id, a.musicbrainz_id, a.image, a.image_source, a.name;
-- name: GetTopArtistsPaginated :many
SELECT
a.id,
a.name,
a.musicbrainz_id,
a.image,
COUNT(*) AS listen_count
FROM listens l
JOIN tracks t ON l.track_id = t.id
JOIN artist_tracks at ON at.track_id = t.id
JOIN artists_with_name a ON a.id = at.artist_id
WHERE l.listened_at BETWEEN $1 AND $2
GROUP BY a.id, a.name, a.musicbrainz_id, a.image, a.image_source, a.name
ORDER BY listen_count DESC
LIMIT $3 OFFSET $4;
-- name: CountTopArtists :one
SELECT COUNT(DISTINCT at.artist_id) AS total_count
FROM listens l
JOIN artist_tracks at ON l.track_id = at.track_id
WHERE l.listened_at BETWEEN $1 AND $2;
-- name: UpdateArtistMbzID :exec
UPDATE artists SET musicbrainz_id = $2
WHERE id = $1;
-- name: UpdateArtistImage :exec
UPDATE artists SET image = $2, image_source = $3
WHERE id = $1;
-- name: DeleteConflictingArtistTracks :exec
DELETE FROM artist_tracks at
WHERE at.artist_id = $1
AND track_id IN (
SELECT at.track_id FROM artist_tracks at WHERE at.artist_id = $2
);
-- name: UpdateArtistTracks :exec
UPDATE artist_tracks
SET artist_id = $2
WHERE artist_id = $1;
-- name: DeleteConflictingArtistReleases :exec
DELETE FROM artist_releases ar
WHERE ar.artist_id = $1
AND release_id IN (
SELECT ar.release_id FROM artist_releases ar WHERE ar.artist_id = $2
);
-- name: UpdateArtistReleases :exec
UPDATE artist_releases
SET artist_id = $2
WHERE artist_id = $1;
-- name: DeleteArtist :exec
DELETE FROM artists WHERE id = $1;

9
db/queries/etc.sql Normal file
View file

@ -0,0 +1,9 @@
-- name: CleanOrphanedEntries :exec
DO $$
BEGIN
DELETE FROM tracks WHERE id NOT IN (SELECT l.track_id FROM listens l);
DELETE FROM releases WHERE id NOT IN (SELECT t.release_id FROM tracks t);
-- DELETE FROM releases WHERE release_group_id NOT IN (SELECT t.release_group_id FROM tracks t);
-- DELETE FROM releases WHERE release_group_id NOT IN (SELECT rg.id FROM release_groups rg);
DELETE FROM artists WHERE id NOT IN (SELECT at.artist_id FROM artist_tracks at);
END $$;

222
db/queries/listen.sql Normal file
View file

@ -0,0 +1,222 @@
-- name: InsertListen :exec
INSERT INTO listens (track_id, listened_at, user_id, client)
VALUES ($1, $2, $3, $4)
ON CONFLICT DO NOTHING;
-- name: GetLastListensPaginated :many
SELECT
l.*,
t.title AS track_title,
t.release_id AS release_id,
(
SELECT json_agg(json_build_object('id', a.id, 'name', a.name))
FROM artist_tracks at
JOIN artists_with_name a ON a.id = at.artist_id
WHERE at.track_id = t.id
) AS artists
FROM listens l
JOIN tracks_with_title t ON l.track_id = t.id
WHERE l.listened_at BETWEEN $1 AND $2
ORDER BY l.listened_at DESC
LIMIT $3 OFFSET $4;
-- name: GetLastListensFromArtistPaginated :many
SELECT
l.*,
t.title AS track_title,
t.release_id AS release_id,
(
SELECT json_agg(json_build_object('id', a.id, 'name', a.name))
FROM artist_tracks at
JOIN artists_with_name a ON a.id = at.artist_id
WHERE at.track_id = t.id
) AS artists
FROM listens l
JOIN tracks_with_title t ON l.track_id = t.id
JOIN artist_tracks at ON t.id = at.track_id
WHERE at.artist_id = $5
AND l.listened_at BETWEEN $1 AND $2
ORDER BY l.listened_at DESC
LIMIT $3 OFFSET $4;
-- name: GetLastListensFromReleasePaginated :many
SELECT
l.*,
t.title AS track_title,
t.release_id AS release_id,
(
SELECT json_agg(json_build_object('id', a.id, 'name', a.name))
FROM artist_tracks at
JOIN artists_with_name a ON a.id = at.artist_id
WHERE at.track_id = t.id
) AS artists
FROM listens l
JOIN tracks_with_title t ON l.track_id = t.id
WHERE l.listened_at BETWEEN $1 AND $2
AND t.release_id = $5
ORDER BY l.listened_at DESC
LIMIT $3 OFFSET $4;
-- name: GetLastListensFromTrackPaginated :many
SELECT
l.*,
t.title AS track_title,
t.release_id AS release_id,
(
SELECT json_agg(json_build_object('id', a.id, 'name', a.name))
FROM artist_tracks at
JOIN artists_with_name a ON a.id = at.artist_id
WHERE at.track_id = t.id
) AS artists
FROM listens l
JOIN tracks_with_title t ON l.track_id = t.id
WHERE l.listened_at BETWEEN $1 AND $2
AND t.id = $5
ORDER BY l.listened_at DESC
LIMIT $3 OFFSET $4;
-- name: CountListens :one
SELECT COUNT(*) AS total_count
FROM listens l
WHERE l.listened_at BETWEEN $1 AND $2;
-- name: CountListensFromTrack :one
SELECT COUNT(*) AS total_count
FROM listens l
WHERE l.listened_at BETWEEN $1 AND $2
AND l.track_id = $3;
-- name: CountListensFromArtist :one
SELECT COUNT(*) AS total_count
FROM listens l
JOIN artist_tracks at ON l.track_id = at.track_id
WHERE l.listened_at BETWEEN $1 AND $2
AND at.artist_id = $3;
-- name: CountListensFromRelease :one
SELECT COUNT(*) AS total_count
FROM listens l
JOIN tracks t ON l.track_id = t.id
WHERE l.listened_at BETWEEN $1 AND $2
AND t.release_id = $3;
-- name: CountTimeListened :one
SELECT COALESCE(SUM(t.duration), 0)::BIGINT AS seconds_listened
FROM listens l
JOIN tracks t ON l.track_id = t.id
WHERE l.listened_at BETWEEN $1 AND $2;
-- name: CountTimeListenedToArtist :one
SELECT COALESCE(SUM(t.duration), 0)::BIGINT AS seconds_listened
FROM listens l
JOIN tracks t ON l.track_id = t.id
JOIN artist_tracks at ON t.id = at.track_id
WHERE l.listened_at BETWEEN $1 AND $2
AND at.artist_id = $3;
-- name: CountTimeListenedToRelease :one
SELECT COALESCE(SUM(t.duration), 0)::BIGINT AS seconds_listened
FROM listens l
JOIN tracks t ON l.track_id = t.id
WHERE l.listened_at BETWEEN $1 AND $2
AND t.release_id = $3;
-- name: CountTimeListenedToTrack :one
SELECT COALESCE(SUM(t.duration), 0)::BIGINT AS seconds_listened
FROM listens l
JOIN tracks t ON l.track_id = t.id
WHERE l.listened_at BETWEEN $1 AND $2
AND t.id = $3;
-- name: ListenActivity :many
WITH buckets AS (
SELECT generate_series($1::timestamptz, $2::timestamptz, $3::interval) AS bucket_start
),
bucketed_listens AS (
SELECT
b.bucket_start,
COUNT(l.listened_at) AS listen_count
FROM buckets b
LEFT JOIN listens l
ON l.listened_at >= b.bucket_start
AND l.listened_at < b.bucket_start + $3::interval
GROUP BY b.bucket_start
ORDER BY b.bucket_start
)
SELECT * FROM bucketed_listens;
-- name: ListenActivityForArtist :many
WITH buckets AS (
SELECT generate_series($1::timestamptz, $2::timestamptz, $3::interval) AS bucket_start
),
filtered_listens AS (
SELECT l.*
FROM listens l
JOIN artist_tracks t ON l.track_id = t.track_id
WHERE t.artist_id = $4
),
bucketed_listens AS (
SELECT
b.bucket_start,
COUNT(l.listened_at) AS listen_count
FROM buckets b
LEFT JOIN filtered_listens l
ON l.listened_at >= b.bucket_start
AND l.listened_at < b.bucket_start + $3::interval
GROUP BY b.bucket_start
ORDER BY b.bucket_start
)
SELECT * FROM bucketed_listens;
-- name: ListenActivityForRelease :many
WITH buckets AS (
SELECT generate_series($1::timestamptz, $2::timestamptz, $3::interval) AS bucket_start
),
filtered_listens AS (
SELECT l.*
FROM listens l
JOIN tracks t ON l.track_id = t.id
WHERE t.release_id = $4
),
bucketed_listens AS (
SELECT
b.bucket_start,
COUNT(l.listened_at) AS listen_count
FROM buckets b
LEFT JOIN filtered_listens l
ON l.listened_at >= b.bucket_start
AND l.listened_at < b.bucket_start + $3::interval
GROUP BY b.bucket_start
ORDER BY b.bucket_start
)
SELECT * FROM bucketed_listens;
-- name: ListenActivityForTrack :many
WITH buckets AS (
SELECT generate_series($1::timestamptz, $2::timestamptz, $3::interval) AS bucket_start
),
filtered_listens AS (
SELECT l.*
FROM listens l
JOIN tracks t ON l.track_id = t.id
WHERE t.id = $4
),
bucketed_listens AS (
SELECT
b.bucket_start,
COUNT(l.listened_at) AS listen_count
FROM buckets b
LEFT JOIN filtered_listens l
ON l.listened_at >= b.bucket_start
AND l.listened_at < b.bucket_start + $3::interval
GROUP BY b.bucket_start
ORDER BY b.bucket_start
)
SELECT * FROM bucketed_listens;
-- name: UpdateTrackIdForListens :exec
UPDATE listens SET track_id = $2
WHERE track_id = $1;
-- name: DeleteListen :exec
DELETE FROM listens WHERE track_id = $1 AND listened_at = $2;

118
db/queries/release.sql Normal file
View file

@ -0,0 +1,118 @@
-- name: InsertRelease :one
INSERT INTO releases (musicbrainz_id, various_artists, image, image_source)
VALUES ($1, $2, $3, $4)
RETURNING *;
-- name: GetRelease :one
SELECT * FROM releases_with_title
WHERE id = $1 LIMIT 1;
-- name: GetReleaseByMbzID :one
SELECT * FROM releases_with_title
WHERE musicbrainz_id = $1 LIMIT 1;
-- name: GetReleaseByImageID :one
SELECT * FROM releases
WHERE image = $1 LIMIT 1;
-- name: GetReleaseByArtistAndTitle :one
SELECT r.*
FROM releases_with_title r
JOIN artist_releases ar ON r.id = ar.release_id
WHERE r.title = $1 AND ar.artist_id = $2
LIMIT 1;
-- name: GetReleaseByArtistAndTitles :one
SELECT r.*
FROM releases_with_title r
JOIN artist_releases ar ON r.id = ar.release_id
WHERE r.title = ANY ($1::TEXT[]) AND ar.artist_id = $2
LIMIT 1;
-- name: GetTopReleasesFromArtist :many
SELECT
r.*,
COUNT(*) AS listen_count,
(
SELECT json_agg(DISTINCT jsonb_build_object('id', a.id, 'name', a.name))
FROM artists_with_name a
JOIN artist_releases ar ON ar.artist_id = a.id
WHERE ar.release_id = r.id
) AS artists
FROM listens l
JOIN tracks t ON l.track_id = t.id
JOIN releases_with_title r ON t.release_id = r.id
JOIN artist_releases ar ON r.id = ar.release_id
WHERE ar.artist_id = $5
AND l.listened_at BETWEEN $1 AND $2
GROUP BY r.id, r.title, r.musicbrainz_id, r.various_artists, r.image, r.image_source
ORDER BY listen_count DESC
LIMIT $3 OFFSET $4;
-- name: GetTopReleasesPaginated :many
SELECT
r.*,
COUNT(*) AS listen_count,
(
SELECT json_agg(DISTINCT jsonb_build_object('id', a.id, 'name', a.name))
FROM artists_with_name a
JOIN artist_releases ar ON ar.artist_id = a.id
WHERE ar.release_id = r.id
) AS artists
FROM listens l
JOIN tracks t ON l.track_id = t.id
JOIN releases_with_title r ON t.release_id = r.id
WHERE l.listened_at BETWEEN $1 AND $2
GROUP BY r.id, r.title, r.musicbrainz_id, r.various_artists, r.image, r.image_source
ORDER BY listen_count DESC
LIMIT $3 OFFSET $4;
-- name: CountTopReleases :one
SELECT COUNT(DISTINCT r.id) AS total_count
FROM listens l
JOIN tracks t ON l.track_id = t.id
JOIN releases r ON t.release_id = r.id
WHERE l.listened_at BETWEEN $1 AND $2;
-- name: CountReleasesFromArtist :one
SELECT COUNT(*)
FROM releases r
JOIN artist_releases ar ON r.id = ar.release_id
WHERE ar.artist_id = $1;
-- name: AssociateArtistToRelease :exec
INSERT INTO artist_releases (artist_id, release_id)
VALUES ($1, $2)
ON CONFLICT DO NOTHING;
-- name: GetReleasesWithoutImages :many
SELECT
r.*,
(
SELECT json_agg(DISTINCT jsonb_build_object('id', a.id, 'name', a.name))
FROM artists_with_name a
JOIN artist_releases ar ON a.id = ar.artist_id
WHERE ar.release_id = r.id
) AS artists
FROM releases_with_title r
WHERE r.image IS NULL
AND r.id > $2
ORDER BY r.id ASC
LIMIT $1;
-- name: UpdateReleaseMbzID :exec
UPDATE releases SET musicbrainz_id = $2
WHERE id = $1;
-- name: UpdateReleaseImage :exec
UPDATE releases SET image = $2, image_source = $3
WHERE id = $1;
-- name: DeleteRelease :exec
DELETE FROM releases WHERE id = $1;
-- name: DeleteReleasesFromArtist :exec
DELETE FROM releases r
USING artist_releases ar
WHERE ar.release_id = r.id
AND ar.artist_id = $1;

161
db/queries/search.sql Normal file
View file

@ -0,0 +1,161 @@
-- name: SearchArtists :many
SELECT id, name, musicbrainz_id, image, score
FROM (
SELECT
a.id,
a.name,
a.musicbrainz_id,
a.image,
similarity(aa.alias, $1) AS score,
ROW_NUMBER() OVER (PARTITION BY a.id ORDER BY similarity(aa.alias, $1) DESC) AS rn
FROM artist_aliases aa
JOIN artists_with_name a ON aa.artist_id = a.id
WHERE similarity(aa.alias, $1) > 0.28
) ranked
WHERE rn = 1
ORDER BY score DESC
LIMIT $2;
-- name: SearchArtistsBySubstring :many
SELECT id, name, musicbrainz_id, image, score
FROM (
SELECT
a.id,
a.name,
a.musicbrainz_id,
a.image,
1.0 AS score, -- why
ROW_NUMBER() OVER (PARTITION BY a.id ORDER BY aa.alias) AS rn
FROM artist_aliases aa
JOIN artists_with_name a ON aa.artist_id = a.id
WHERE aa.alias ILIKE $1 || '%'
) ranked
WHERE rn = 1
ORDER BY score DESC
LIMIT $2;
-- name: SearchTracks :many
SELECT
ranked.id,
ranked.title,
ranked.musicbrainz_id,
ranked.release_id,
ranked.image,
ranked.score,
(
SELECT json_agg(json_build_object('id', a.id, 'name', a.name))
FROM artist_tracks at
JOIN artists_with_name a ON a.id = at.artist_id
WHERE at.track_id = ranked.id
) AS artists
FROM (
SELECT
t.id,
t.title,
t.musicbrainz_id,
t.release_id,
r.image,
similarity(ta.alias, $1) AS score,
ROW_NUMBER() OVER (PARTITION BY t.id ORDER BY similarity(ta.alias, $1) DESC) AS rn
FROM track_aliases ta
JOIN tracks_with_title t ON ta.track_id = t.id
JOIN releases r ON t.release_id = r.id
WHERE similarity(ta.alias, $1) > 0.28
) ranked
WHERE rn = 1
ORDER BY score DESC, title
LIMIT $2;
-- name: SearchTracksBySubstring :many
SELECT
ranked.id,
ranked.title,
ranked.musicbrainz_id,
ranked.release_id,
ranked.image,
ranked.score,
(
SELECT json_agg(json_build_object('id', a.id, 'name', a.name))
FROM artist_tracks at
JOIN artists_with_name a ON a.id = at.artist_id
WHERE at.track_id = ranked.id
) AS artists
FROM (
SELECT
t.id,
t.title,
t.musicbrainz_id,
t.release_id,
r.image,
1.0 AS score,
ROW_NUMBER() OVER (PARTITION BY t.id ORDER BY ta.alias) AS rn
FROM track_aliases ta
JOIN tracks_with_title t ON ta.track_id = t.id
JOIN releases r ON t.release_id = r.id
WHERE ta.alias ILIKE $1 || '%'
) ranked
WHERE rn = 1
ORDER BY score DESC, title
LIMIT $2;
-- name: SearchReleases :many
SELECT
ranked.id,
ranked.title,
ranked.musicbrainz_id,
ranked.image,
ranked.various_artists,
ranked.score,
(
SELECT json_agg(DISTINCT jsonb_build_object('id', a.id, 'name', a.name))
FROM artists_with_name a
JOIN artist_releases ar ON ar.artist_id = a.id
WHERE ar.release_id = ranked.id
) AS artists
FROM (
SELECT
r.id,
r.title,
r.musicbrainz_id,
r.image,
r.various_artists,
similarity(ra.alias, $1) AS score,
ROW_NUMBER() OVER (PARTITION BY r.id ORDER BY similarity(ra.alias, $1) DESC) AS rn
FROM release_aliases ra
JOIN releases_with_title r ON ra.release_id = r.id
WHERE similarity(ra.alias, $1) > 0.28
) ranked
WHERE rn = 1
ORDER BY score DESC, title
LIMIT $2;
-- name: SearchReleasesBySubstring :many
SELECT
ranked.id,
ranked.title,
ranked.musicbrainz_id,
ranked.image,
ranked.various_artists,
ranked.score,
(
SELECT json_agg(DISTINCT jsonb_build_object('id', a.id, 'name', a.name))
FROM artists_with_name a
JOIN artist_releases ar ON ar.artist_id = a.id
WHERE ar.release_id = ranked.id
) AS artists
FROM (
SELECT
r.id,
r.title,
r.musicbrainz_id,
r.image,
r.various_artists,
1.0 AS score, -- idk why
ROW_NUMBER() OVER (PARTITION BY r.id ORDER BY ra.alias) AS rn
FROM release_aliases ra
JOIN releases_with_title r ON ra.release_id = r.id
WHERE ra.alias ILIKE $1 || '%'
) ranked
WHERE rn = 1
ORDER BY score DESC, title
LIMIT $2;

19
db/queries/sessions.sql Normal file
View file

@ -0,0 +1,19 @@
-- name: InsertSession :one
INSERT INTO sessions (id, user_id, expires_at, persistent)
VALUES ($1, $2, $3, $4)
RETURNING *;
-- name: GetSession :one
SELECT * FROM sessions WHERE id = $1 AND expires_at > NOW();
-- name: UpdateSessionExpiry :exec
UPDATE sessions SET expires_at = $2 WHERE id = $1;
-- name: DeleteSession :exec
DELETE FROM sessions WHERE id = $1;
-- name: GetUserBySession :one
SELECT *
FROM users u
JOIN sessions s ON u.id = s.user_id
WHERE s.id = $1;

139
db/queries/track.sql Normal file
View file

@ -0,0 +1,139 @@
-- name: InsertTrack :one
INSERT INTO tracks (musicbrainz_id, release_id, duration)
VALUES ($1, $2, $3)
RETURNING *;
-- name: AssociateArtistToTrack :exec
INSERT INTO artist_tracks (artist_id, track_id)
VALUES ($1, $2)
ON CONFLICT DO NOTHING;
-- name: GetTrack :one
SELECT
t.*,
r.image
FROM tracks_with_title t
JOIN releases r ON t.release_id = r.id
WHERE t.id = $1 LIMIT 1;
-- name: GetTrackByMbzID :one
SELECT * FROM tracks_with_title
WHERE musicbrainz_id = $1 LIMIT 1;
-- name: GetAllTracksFromArtist :many
SELECT t.*
FROM tracks_with_title t
JOIN artist_tracks at ON t.id = at.track_id
WHERE at.artist_id = $1;
-- name: GetTrackByTitleAndArtists :one
SELECT t.*
FROM tracks_with_title t
JOIN artist_tracks at ON at.track_id = t.id
WHERE t.title = $1
AND at.artist_id = ANY($2::int[])
GROUP BY t.id, t.title, t.musicbrainz_id, t.duration, t.release_id
HAVING COUNT(DISTINCT at.artist_id) = cardinality($2::int[]);
-- name: GetTopTracksPaginated :many
SELECT
t.id,
t.title,
t.musicbrainz_id,
t.release_id,
r.image,
COUNT(*) AS listen_count,
(
SELECT json_agg(json_build_object('id', a.id, 'name', a.name))
FROM artist_tracks at
JOIN artists_with_name a ON a.id = at.artist_id
WHERE at.track_id = t.id
) AS artists
FROM listens l
JOIN tracks_with_title t ON l.track_id = t.id
JOIN releases r ON t.release_id = r.id
WHERE l.listened_at BETWEEN $1 AND $2
GROUP BY t.id, t.title, t.musicbrainz_id, t.release_id, r.image
ORDER BY listen_count DESC
LIMIT $3 OFFSET $4;
-- name: GetTopTracksByArtistPaginated :many
SELECT
t.id,
t.title,
t.musicbrainz_id,
t.release_id,
r.image,
COUNT(*) AS listen_count,
(
SELECT json_agg(json_build_object('id', a.id, 'name', a.name))
FROM artist_tracks at2
JOIN artists_with_name a ON a.id = at2.artist_id
WHERE at2.track_id = t.id
) AS artists
FROM listens l
JOIN tracks_with_title t ON l.track_id = t.id
JOIN releases r ON t.release_id = r.id
JOIN artist_tracks at ON at.track_id = t.id
WHERE l.listened_at BETWEEN $1 AND $2
AND at.artist_id = $5
GROUP BY t.id, t.title, t.musicbrainz_id, t.release_id, r.image
ORDER BY listen_count DESC
LIMIT $3 OFFSET $4;
-- name: GetTopTracksInReleasePaginated :many
SELECT
t.id,
t.title,
t.musicbrainz_id,
t.release_id,
r.image,
COUNT(*) AS listen_count,
(
SELECT json_agg(json_build_object('id', a.id, 'name', a.name))
FROM artist_tracks at2
JOIN artists_with_name a ON a.id = at2.artist_id
WHERE at2.track_id = t.id
) AS artists
FROM listens l
JOIN tracks_with_title t ON l.track_id = t.id
JOIN releases r ON t.release_id = r.id
WHERE l.listened_at BETWEEN $1 AND $2
AND t.release_id = $5
GROUP BY t.id, t.title, t.musicbrainz_id, t.release_id, r.image
ORDER BY listen_count DESC
LIMIT $3 OFFSET $4;
-- name: CountTopTracks :one
SELECT COUNT(DISTINCT l.track_id) AS total_count
FROM listens l
WHERE l.listened_at BETWEEN $1 AND $2;
-- name: CountTopTracksByArtist :one
SELECT COUNT(DISTINCT l.track_id) AS total_count
FROM listens l
JOIN artist_tracks at ON l.track_id = at.track_id
WHERE l.listened_at BETWEEN $1 AND $2
AND at.artist_id = $3;
-- name: CountTopTracksByRelease :one
SELECT COUNT(DISTINCT l.track_id) AS total_count
FROM listens l
JOIN tracks t ON l.track_id = t.id
WHERE l.listened_at BETWEEN $1 AND $2
AND t.release_id = $3;
-- name: UpdateTrackMbzID :exec
UPDATE tracks SET musicbrainz_id = $2
WHERE id = $1;
-- name: UpdateTrackDuration :exec
UPDATE tracks SET duration = $2
WHERE id = $1;
-- name: UpdateReleaseForAll :exec
UPDATE tracks SET release_id = $2
WHERE release_id = $1;
-- name: DeleteTrack :exec
DELETE FROM tracks WHERE id = $1;

45
db/queries/users.sql Normal file
View file

@ -0,0 +1,45 @@
-- name: InsertUser :one
INSERT INTO users (username, password, role)
VALUES ($1, $2, $3)
RETURNING *;
-- name: DeleteUser :exec
DELETE FROM users WHERE id = $1;
-- name: GetUserByUsername :one
SELECT * FROM users WHERE username = $1;
-- name: CountUsers :one
SELECT COUNT(*) FROM users;
-- name: InsertApiKey :one
INSERT INTO api_keys (user_id, key, label)
VALUES ($1, $2, $3)
RETURNING *;
-- name: DeleteApiKey :exec
DELETE FROM api_keys WHERE id = $1;
-- name: CountApiKeys :one
SELECT COUNT(*) FROM api_keys WHERE user_id = $1;
-- name: GetUserByApiKey :one
SELECT u.*
FROM users u
JOIN api_keys ak ON u.id = ak.user_id
WHERE ak.key = $1;
-- name: GetAllApiKeysByUserID :many
SELECT ak.*
FROM api_keys ak
JOIN users u ON ak.user_id = u.id
WHERE u.id = $1;
-- name: UpdateUserUsername :exec
UPDATE users SET username = $2 WHERE id = $1;
-- name: UpdateUserPassword :exec
UPDATE users SET password = $2 WHERE id = $1;
-- name: UpdateApiKeyLabel :exec
UPDATE api_keys SET label = $3 WHERE id = $1 AND user_id = $2;