// Code generated by sqlc. DO NOT EDIT. // versions: // sqlc v1.31.1 // source: you_might_like.sql package dbq import ( "context" "github.com/jackc/pgx/v5/pgtype" ) const countListeningSignalForUser = `-- name: CountListeningSignalForUser :one SELECT count(DISTINCT pe.track_id)::bigint AS distinct_tracks, count(DISTINCT t.artist_id)::bigint AS distinct_artists FROM play_events pe JOIN tracks t ON t.id = pe.track_id WHERE pe.user_id = $1 AND pe.was_skipped = false ` type CountListeningSignalForUserRow struct { DistinctTracks int64 DistinctArtists int64 } // "You might like" Home rows (#790). The daily build computes ranked // album/artist IDs in Go (similarity roll-up + cold-start gate) and // atomic-replaces them here; /api/home reads them back hydrated. // Cold-start gate. Returns the breadth of the user's real listening: // distinct unskipped tracks played and distinct artists played. The // build skips You-might-like entirely below a threshold (a thin history // yields near-random roll-ups). was_skipped=false so a user spamming // next can't inflate the signal. func (q *Queries) CountListeningSignalForUser(ctx context.Context, userID pgtype.UUID) (CountListeningSignalForUserRow, error) { row := q.db.QueryRow(ctx, countListeningSignalForUser, userID) var i CountListeningSignalForUserRow err := row.Scan(&i.DistinctTracks, &i.DistinctArtists) return i, err } const deleteYouMightLikeAlbumsForUser = `-- name: DeleteYouMightLikeAlbumsForUser :exec DELETE FROM you_might_like_albums WHERE user_id = $1 ` func (q *Queries) DeleteYouMightLikeAlbumsForUser(ctx context.Context, userID pgtype.UUID) error { _, err := q.db.Exec(ctx, deleteYouMightLikeAlbumsForUser, userID) return err } const deleteYouMightLikeArtistsForUser = `-- name: DeleteYouMightLikeArtistsForUser :exec DELETE FROM you_might_like_artists WHERE user_id = $1 ` func (q *Queries) DeleteYouMightLikeArtistsForUser(ctx context.Context, userID pgtype.UUID) error { _, err := q.db.Exec(ctx, deleteYouMightLikeArtistsForUser, userID) return err } const insertYouMightLikeAlbum = `-- name: InsertYouMightLikeAlbum :exec INSERT INTO you_might_like_albums (user_id, album_id, rank) VALUES ($1, $2, $3) ` type InsertYouMightLikeAlbumParams struct { UserID pgtype.UUID AlbumID pgtype.UUID Rank int32 } func (q *Queries) InsertYouMightLikeAlbum(ctx context.Context, arg InsertYouMightLikeAlbumParams) error { _, err := q.db.Exec(ctx, insertYouMightLikeAlbum, arg.UserID, arg.AlbumID, arg.Rank) return err } const insertYouMightLikeArtist = `-- name: InsertYouMightLikeArtist :exec INSERT INTO you_might_like_artists (user_id, artist_id, rank) VALUES ($1, $2, $3) ` type InsertYouMightLikeArtistParams struct { UserID pgtype.UUID ArtistID pgtype.UUID Rank int32 } func (q *Queries) InsertYouMightLikeArtist(ctx context.Context, arg InsertYouMightLikeArtistParams) error { _, err := q.db.Exec(ctx, insertYouMightLikeArtist, arg.UserID, arg.ArtistID, arg.Rank) return err } const listYouMightLikeAlbumFallbackForUser = `-- name: ListYouMightLikeAlbumFallbackForUser :many WITH liked_album_ids AS ( SELECT likb.album_id AS album_id FROM general_likes_albums likb WHERE likb.user_id = $1 UNION SELECT trk.album_id AS album_id FROM general_likes likt JOIN tracks trk ON trk.id = likt.track_id WHERE likt.user_id = $1 ) SELECT albums.id, albums.title, albums.sort_title, albums.artist_id, albums.release_date, albums.mbid, albums.cover_art_path, albums.created_at, albums.updated_at, albums.cover_art_source, albums.cover_art_sources_version, artists.name AS artist_name FROM liked_album_ids lai JOIN albums ON albums.id = lai.album_id JOIN artists ON artists.id = albums.artist_id ORDER BY md5(albums.id::text || current_date::text) LIMIT $2 ` type ListYouMightLikeAlbumFallbackForUserParams struct { UserID pgtype.UUID Limit int32 } type ListYouMightLikeAlbumFallbackForUserRow struct { Album Album ArtistName string } // Broad "albums you've shown affinity for" pool: explicitly liked albums PLUS // the albums of liked tracks. Same projection as ListYouMightLikeAlbumsForUser. func (q *Queries) ListYouMightLikeAlbumFallbackForUser(ctx context.Context, arg ListYouMightLikeAlbumFallbackForUserParams) ([]ListYouMightLikeAlbumFallbackForUserRow, error) { rows, err := q.db.Query(ctx, listYouMightLikeAlbumFallbackForUser, arg.UserID, arg.Limit) if err != nil { return nil, err } defer rows.Close() var items []ListYouMightLikeAlbumFallbackForUserRow for rows.Next() { var i ListYouMightLikeAlbumFallbackForUserRow if err := rows.Scan( &i.Album.ID, &i.Album.Title, &i.Album.SortTitle, &i.Album.ArtistID, &i.Album.ReleaseDate, &i.Album.Mbid, &i.Album.CoverArtPath, &i.Album.CreatedAt, &i.Album.UpdatedAt, &i.Album.CoverArtSource, &i.Album.CoverArtSourcesVersion, &i.ArtistName, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listYouMightLikeAlbumsForUser = `-- name: ListYouMightLikeAlbumsForUser :many SELECT albums.id, albums.title, albums.sort_title, albums.artist_id, albums.release_date, albums.mbid, albums.cover_art_path, albums.created_at, albums.updated_at, albums.cover_art_source, albums.cover_art_sources_version, artists.name AS artist_name FROM you_might_like_albums yml JOIN albums ON albums.id = yml.album_id JOIN artists ON artists.id = albums.artist_id WHERE yml.user_id = $1 ORDER BY yml.rank LIMIT $2 ` type ListYouMightLikeAlbumsForUserParams struct { UserID pgtype.UUID Limit int32 } type ListYouMightLikeAlbumsForUserRow struct { Album Album ArtistName string } // Read path. Same projection as ListRediscoverAlbumsForUser so the API // layer reuses albumRefFrom(row.Album, row.ArtistName, …). Ordered by // the rank persisted at build time. Final cross-section dedup (vs Most // Played / Rediscover) and the output cap land in the Go layer // (internal/recommendation/home.go). func (q *Queries) ListYouMightLikeAlbumsForUser(ctx context.Context, arg ListYouMightLikeAlbumsForUserParams) ([]ListYouMightLikeAlbumsForUserRow, error) { rows, err := q.db.Query(ctx, listYouMightLikeAlbumsForUser, arg.UserID, arg.Limit) if err != nil { return nil, err } defer rows.Close() var items []ListYouMightLikeAlbumsForUserRow for rows.Next() { var i ListYouMightLikeAlbumsForUserRow if err := rows.Scan( &i.Album.ID, &i.Album.Title, &i.Album.SortTitle, &i.Album.ArtistID, &i.Album.ReleaseDate, &i.Album.Mbid, &i.Album.CoverArtPath, &i.Album.CreatedAt, &i.Album.UpdatedAt, &i.Album.CoverArtSource, &i.Album.CoverArtSourcesVersion, &i.ArtistName, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listYouMightLikeArtistFallbackForUser = `-- name: ListYouMightLikeArtistFallbackForUser :many WITH liked_artist_ids AS ( SELECT lika.artist_id AS artist_id FROM general_likes_artists lika WHERE lika.user_id = $1 UNION SELECT alb.artist_id AS artist_id FROM general_likes_albums likb JOIN albums alb ON alb.id = likb.album_id WHERE likb.user_id = $1 UNION SELECT trk.artist_id AS artist_id FROM general_likes likt JOIN tracks trk ON trk.id = likt.track_id WHERE likt.user_id = $1 ) SELECT artists.id, artists.name, artists.sort_name, artists.mbid, artists.created_at, artists.updated_at, artists.artist_thumb_path, artists.artist_fanart_path, artists.artist_art_source, artists.artist_art_sources_version, cov.id AS cover_album_id, cnt.album_count::bigint AS album_count FROM liked_artist_ids lai JOIN artists ON artists.id = lai.artist_id LEFT JOIN LATERAL ( SELECT id FROM albums WHERE artist_id = artists.id AND cover_art_path IS NOT NULL ORDER BY created_at DESC LIMIT 1 ) cov ON true LEFT JOIN LATERAL ( SELECT count(*) AS album_count FROM albums WHERE artist_id = artists.id ) cnt ON true ORDER BY md5(artists.id::text || current_date::text) LIMIT $2 ` type ListYouMightLikeArtistFallbackForUserParams struct { UserID pgtype.UUID Limit int32 } type ListYouMightLikeArtistFallbackForUserRow struct { Artist Artist CoverAlbumID pgtype.UUID AlbumCount int64 } // Broad "artists you've shown affinity for" pool to fill a thin // You-might-like artists row: explicitly liked artists PLUS the artists of // liked albums and liked tracks. Most users like albums/tracks far more than // they like artists explicitly, so the union is much deeper than // general_likes_artists alone. Daily-stable order; same projection as // ListYouMightLikeArtistsForUser so the Go layer reuses it directly. func (q *Queries) ListYouMightLikeArtistFallbackForUser(ctx context.Context, arg ListYouMightLikeArtistFallbackForUserParams) ([]ListYouMightLikeArtistFallbackForUserRow, error) { rows, err := q.db.Query(ctx, listYouMightLikeArtistFallbackForUser, arg.UserID, arg.Limit) if err != nil { return nil, err } defer rows.Close() var items []ListYouMightLikeArtistFallbackForUserRow for rows.Next() { var i ListYouMightLikeArtistFallbackForUserRow if err := rows.Scan( &i.Artist.ID, &i.Artist.Name, &i.Artist.SortName, &i.Artist.Mbid, &i.Artist.CreatedAt, &i.Artist.UpdatedAt, &i.Artist.ArtistThumbPath, &i.Artist.ArtistFanartPath, &i.Artist.ArtistArtSource, &i.Artist.ArtistArtSourcesVersion, &i.CoverAlbumID, &i.AlbumCount, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listYouMightLikeArtistsForUser = `-- name: ListYouMightLikeArtistsForUser :many SELECT artists.id, artists.name, artists.sort_name, artists.mbid, artists.created_at, artists.updated_at, artists.artist_thumb_path, artists.artist_fanart_path, artists.artist_art_source, artists.artist_art_sources_version, cov.id AS cover_album_id, cnt.album_count::bigint AS album_count FROM you_might_like_artists yml JOIN artists ON artists.id = yml.artist_id LEFT JOIN LATERAL ( SELECT id FROM albums WHERE artist_id = artists.id AND cover_art_path IS NOT NULL ORDER BY created_at DESC LIMIT 1 ) cov ON true LEFT JOIN LATERAL ( SELECT count(*) AS album_count FROM albums WHERE artist_id = artists.id ) cnt ON true WHERE yml.user_id = $1 ORDER BY yml.rank LIMIT $2 ` type ListYouMightLikeArtistsForUserParams struct { UserID pgtype.UUID Limit int32 } type ListYouMightLikeArtistsForUserRow struct { Artist Artist CoverAlbumID pgtype.UUID AlbumCount int64 } // Read path. Same projection as ListRediscoverArtistsForUser (embeds the // artist + a representative cover_album_id + album_count) so the API // layer reuses artistRefFromCovered. Ordered by persisted rank. func (q *Queries) ListYouMightLikeArtistsForUser(ctx context.Context, arg ListYouMightLikeArtistsForUserParams) ([]ListYouMightLikeArtistsForUserRow, error) { rows, err := q.db.Query(ctx, listYouMightLikeArtistsForUser, arg.UserID, arg.Limit) if err != nil { return nil, err } defer rows.Close() var items []ListYouMightLikeArtistsForUserRow for rows.Next() { var i ListYouMightLikeArtistsForUserRow if err := rows.Scan( &i.Artist.ID, &i.Artist.Name, &i.Artist.SortName, &i.Artist.Mbid, &i.Artist.CreatedAt, &i.Artist.UpdatedAt, &i.Artist.ArtistThumbPath, &i.Artist.ArtistFanartPath, &i.Artist.ArtistArtSource, &i.Artist.ArtistArtSourcesVersion, &i.CoverAlbumID, &i.AlbumCount, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil }