// Code generated by sqlc. DO NOT EDIT. // versions: // sqlc v1.31.1 // source: taste_profile.sql package dbq import ( "context" "github.com/jackc/pgx/v5/pgtype" ) const deleteTasteProfileArtistsForUser = `-- name: DeleteTasteProfileArtistsForUser :exec DELETE FROM taste_profile_artists WHERE user_id = $1 ` func (q *Queries) DeleteTasteProfileArtistsForUser(ctx context.Context, userID pgtype.UUID) error { _, err := q.db.Exec(ctx, deleteTasteProfileArtistsForUser, userID) return err } const deleteTasteProfileTagsForUser = `-- name: DeleteTasteProfileTagsForUser :exec DELETE FROM taste_profile_tags WHERE user_id = $1 ` func (q *Queries) DeleteTasteProfileTagsForUser(ctx context.Context, userID pgtype.UUID) error { _, err := q.db.Exec(ctx, deleteTasteProfileTagsForUser, userID) return err } const insertTasteProfileArtist = `-- name: InsertTasteProfileArtist :exec INSERT INTO taste_profile_artists (user_id, artist_id, weight) VALUES ($1, $2, $3) ` type InsertTasteProfileArtistParams struct { UserID pgtype.UUID ArtistID pgtype.UUID Weight float64 } func (q *Queries) InsertTasteProfileArtist(ctx context.Context, arg InsertTasteProfileArtistParams) error { _, err := q.db.Exec(ctx, insertTasteProfileArtist, arg.UserID, arg.ArtistID, arg.Weight) return err } const insertTasteProfileTag = `-- name: InsertTasteProfileTag :exec INSERT INTO taste_profile_tags (user_id, tag, weight) VALUES ($1, $2, $3) ` type InsertTasteProfileTagParams struct { UserID pgtype.UUID Tag string Weight float64 } func (q *Queries) InsertTasteProfileTag(ctx context.Context, arg InsertTasteProfileTagParams) error { _, err := q.db.Exec(ctx, insertTasteProfileTag, arg.UserID, arg.Tag, arg.Weight) return err } const listLikedArtistIDsForUser = `-- name: ListLikedArtistIDsForUser :many SELECT artist_id FROM general_likes_artists WHERE user_id = $1 ` // Artists the user has explicitly liked; feeds the artist-like bonus. func (q *Queries) ListLikedArtistIDsForUser(ctx context.Context, userID pgtype.UUID) ([]pgtype.UUID, error) { rows, err := q.db.Query(ctx, listLikedArtistIDsForUser, userID) if err != nil { return nil, err } defer rows.Close() var items []pgtype.UUID for rows.Next() { var artist_id pgtype.UUID if err := rows.Scan(&artist_id); err != nil { return nil, err } items = append(items, artist_id) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listLikedTrackTasteInputsForUser = `-- name: ListLikedTrackTasteInputsForUser :many SELECT t.artist_id, t.genre FROM general_likes gl JOIN tracks t ON t.id = gl.track_id WHERE gl.user_id = $1 ` type ListLikedTrackTasteInputsForUserRow struct { ArtistID pgtype.UUID Genre *string } // (artist_id, genre) for each track the user has explicitly liked. Feeds the // track-like bonus into the liked track's artist and tags. func (q *Queries) ListLikedTrackTasteInputsForUser(ctx context.Context, userID pgtype.UUID) ([]ListLikedTrackTasteInputsForUserRow, error) { rows, err := q.db.Query(ctx, listLikedTrackTasteInputsForUser, userID) if err != nil { return nil, err } defer rows.Close() var items []ListLikedTrackTasteInputsForUserRow for rows.Next() { var i ListLikedTrackTasteInputsForUserRow if err := rows.Scan(&i.ArtistID, &i.Genre); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listPlayEngagementInputsForUser = `-- name: ListPlayEngagementInputsForUser :many SELECT t.artist_id, t.genre, LEAST(GREATEST( COALESCE(pe.completion_ratio, pe.duration_played_ms::float8 / NULLIF(t.duration_ms, 0), 0), 0), 1)::float8 AS completion, (EXTRACT(epoch FROM now() - pe.started_at) / 86400.0)::float8 AS age_days FROM play_events pe JOIN tracks t ON t.id = pe.track_id WHERE pe.user_id = $1 AND pe.started_at > now() - ($2::float8 * INTERVAL '1 day') AND NOT EXISTS ( SELECT 1 FROM lidarr_quarantine q WHERE q.user_id = $1 AND q.track_id = t.id ) ` type ListPlayEngagementInputsForUserParams struct { UserID pgtype.UUID Column2 float64 } type ListPlayEngagementInputsForUserRow struct { ArtistID pgtype.UUID Genre *string Completion float64 AgeDays float64 } // Taste profile (#796 phase 1). The daily build computes signed artist/tag // weights in Go (graded engagement + decay + like bonus) and atomic-replaces // them here. Read queries serve "top taste" lookups (used in phase 2). // One row per play in the decay-relevant window. completion is the play's // completion ratio (precomputed column when present, else duration_played / // track duration, clamped to [0,1]); age_days drives the time-decay. Genre // is split into tags in Go. Quarantined tracks are excluded. func (q *Queries) ListPlayEngagementInputsForUser(ctx context.Context, arg ListPlayEngagementInputsForUserParams) ([]ListPlayEngagementInputsForUserRow, error) { rows, err := q.db.Query(ctx, listPlayEngagementInputsForUser, arg.UserID, arg.Column2) if err != nil { return nil, err } defer rows.Close() var items []ListPlayEngagementInputsForUserRow for rows.Next() { var i ListPlayEngagementInputsForUserRow if err := rows.Scan( &i.ArtistID, &i.Genre, &i.Completion, &i.AgeDays, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listTasteProfileArtistsForUser = `-- name: ListTasteProfileArtistsForUser :many SELECT artist_id, weight FROM taste_profile_artists WHERE user_id = $1 ORDER BY weight DESC LIMIT $2 ` type ListTasteProfileArtistsForUserParams struct { UserID pgtype.UUID Limit int32 } type ListTasteProfileArtistsForUserRow struct { ArtistID pgtype.UUID Weight float64 } // Top-weighted taste artists (phase-2 consumption + tests). func (q *Queries) ListTasteProfileArtistsForUser(ctx context.Context, arg ListTasteProfileArtistsForUserParams) ([]ListTasteProfileArtistsForUserRow, error) { rows, err := q.db.Query(ctx, listTasteProfileArtistsForUser, arg.UserID, arg.Limit) if err != nil { return nil, err } defer rows.Close() var items []ListTasteProfileArtistsForUserRow for rows.Next() { var i ListTasteProfileArtistsForUserRow if err := rows.Scan(&i.ArtistID, &i.Weight); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listTasteProfileTagsForUser = `-- name: ListTasteProfileTagsForUser :many SELECT tag, weight FROM taste_profile_tags WHERE user_id = $1 ORDER BY weight DESC LIMIT $2 ` type ListTasteProfileTagsForUserParams struct { UserID pgtype.UUID Limit int32 } type ListTasteProfileTagsForUserRow struct { Tag string Weight float64 } func (q *Queries) ListTasteProfileTagsForUser(ctx context.Context, arg ListTasteProfileTagsForUserParams) ([]ListTasteProfileTagsForUserRow, error) { rows, err := q.db.Query(ctx, listTasteProfileTagsForUser, arg.UserID, arg.Limit) if err != nil { return nil, err } defer rows.Close() var items []ListTasteProfileTagsForUserRow for rows.Next() { var i ListTasteProfileTagsForUserRow if err := rows.Scan(&i.Tag, &i.Weight); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil }