package rpsrepo import ( "context" "database/sql" ) type Repo struct { db *sql.DB } func NewRepo(db *sql.DB) *Repo { return &Repo{db: db} } func (r *Repo) GetScore(ctx context.Context, guildID int64, userID int64) (int, bool, error) { var score int err := r.db.QueryRowContext(ctx, ` SELECT score FROM rps WHERE guild_id = $1 AND user_id = $2 `, guildID, userID).Scan(&score) if err == sql.ErrNoRows { return 0, false, nil } if err != nil { return 0, false, err } return score, true, nil } func (r *Repo) SetScore(ctx context.Context, guildID int64, userID int64, score int) error { _, err := r.db.ExecContext(ctx, ` INSERT INTO rps (guild_id, user_id, score) VALUES ($1, $2, $3) ON CONFLICT (guild_id, user_id) DO UPDATE SET score = EXCLUDED.score `, guildID, userID, score) return err } type ScoreEntry struct { UserID int64 Score int } func (r *Repo) TopScores(ctx context.Context, guildID int64, limit int) ([]ScoreEntry, error) { if limit <= 0 { limit = 10 } rows, err := r.db.QueryContext(ctx, ` SELECT user_id, score FROM rps WHERE guild_id = $1 ORDER BY score DESC, user_id ASC LIMIT $2 `, guildID, limit) if err != nil { return nil, err } defer rows.Close() out := make([]ScoreEntry, 0, limit) for rows.Next() { var e ScoreEntry if err := rows.Scan(&e.UserID, &e.Score); err != nil { return nil, err } out = append(out, e) } if err := rows.Err(); err != nil { return nil, err } return out, nil }