mirror of
https://github.com/gabehf/Koito.git
synced 2026-04-22 12:01:52 -07:00
chore: initial public commit
This commit is contained in:
commit
fc9054b78c
250 changed files with 32809 additions and 0 deletions
65
db/queries/alias.sql
Normal file
65
db/queries/alias.sql
Normal 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
112
db/queries/artist.sql
Normal 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
9
db/queries/etc.sql
Normal 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
222
db/queries/listen.sql
Normal 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
118
db/queries/release.sql
Normal 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
161
db/queries/search.sql
Normal 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
19
db/queries/sessions.sql
Normal 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
139
db/queries/track.sql
Normal 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
45
db/queries/users.sql
Normal 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;
|
||||
Loading…
Add table
Add a link
Reference in a new issue