feat(db): add session-vector capture queries; LikeTrack returns row count
ListRecentSessionTracks + UpdatePlayEventVector for the vector capture path inside RecordPlayStarted. LikeTrack switches to :execrows so the contextual-likes capture can detect insert vs already-exists. Existing callers updated to ignore the count for now; later tasks consume it.
This commit is contained in:
@@ -188,6 +188,60 @@ func (q *Queries) InsertSkipEvent(ctx context.Context, arg InsertSkipEventParams
|
||||
return i, err
|
||||
}
|
||||
|
||||
const listRecentSessionTracks = `-- name: ListRecentSessionTracks :many
|
||||
SELECT t.id, t.title, t.album_id, t.artist_id, t.track_number, t.disc_number, t.duration_ms, t.file_path, t.file_size, t.file_format, t.bitrate, t.mbid, t.genre, t.added_at, t.updated_at FROM tracks t
|
||||
JOIN play_events pe ON pe.track_id = t.id
|
||||
WHERE pe.session_id = $1
|
||||
AND pe.started_at < $2
|
||||
ORDER BY pe.started_at DESC
|
||||
LIMIT $3
|
||||
`
|
||||
|
||||
type ListRecentSessionTracksParams struct {
|
||||
SessionID pgtype.UUID
|
||||
StartedAt pgtype.Timestamptz
|
||||
Limit int32
|
||||
}
|
||||
|
||||
// Returns up to $3 tracks in session $1 whose play_event started before
|
||||
// $2, ordered newest-first. Used by playevents.RecordPlayStarted to
|
||||
// build the session_vector for the just-inserted play_event.
|
||||
func (q *Queries) ListRecentSessionTracks(ctx context.Context, arg ListRecentSessionTracksParams) ([]Track, error) {
|
||||
rows, err := q.db.Query(ctx, listRecentSessionTracks, arg.SessionID, arg.StartedAt, arg.Limit)
|
||||
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 touchPlaySessionLastEvent = `-- name: TouchPlaySessionLastEvent :exec
|
||||
UPDATE play_sessions
|
||||
SET last_event_at = $2,
|
||||
@@ -251,3 +305,21 @@ func (q *Queries) UpdatePlayEventEnded(ctx context.Context, arg UpdatePlayEventE
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const updatePlayEventVector = `-- name: UpdatePlayEventVector :exec
|
||||
UPDATE play_events
|
||||
SET session_vector_at_play = $2
|
||||
WHERE id = $1
|
||||
`
|
||||
|
||||
type UpdatePlayEventVectorParams struct {
|
||||
ID pgtype.UUID
|
||||
SessionVectorAtPlay []byte
|
||||
}
|
||||
|
||||
// Used right after InsertPlayEvent to populate session_vector_at_play
|
||||
// once the vector has been computed.
|
||||
func (q *Queries) UpdatePlayEventVector(ctx context.Context, arg UpdatePlayEventVectorParams) error {
|
||||
_, err := q.db.Exec(ctx, updatePlayEventVector, arg.ID, arg.SessionVectorAtPlay)
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user