95 lines
2.0 KiB
Go
95 lines
2.0 KiB
Go
package levelrepo
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
)
|
|
|
|
type Level struct {
|
|
GuildID int64
|
|
UserID int64
|
|
Level int
|
|
XP int64
|
|
}
|
|
|
|
type Repo struct {
|
|
db *sql.DB
|
|
}
|
|
|
|
func NewRepo(db *sql.DB) *Repo {
|
|
return &Repo{db: db}
|
|
}
|
|
|
|
func (r *Repo) GetLevel(ctx context.Context, guildID, userID int64) (*Level, error) {
|
|
const q = `
|
|
SELECT level, xp
|
|
FROM levels
|
|
WHERE guild = $1 AND user_id = $2
|
|
`
|
|
row := r.db.QueryRowContext(ctx, q, guildID, userID)
|
|
var lvl Level
|
|
lvl.GuildID = guildID
|
|
lvl.UserID = userID
|
|
switch err := row.Scan(&lvl.Level, &lvl.XP); err {
|
|
case sql.ErrNoRows:
|
|
// default new user
|
|
lvl.Level = 0
|
|
lvl.XP = 0
|
|
return &lvl, nil
|
|
case nil:
|
|
return &lvl, nil
|
|
default:
|
|
return nil, err
|
|
}
|
|
}
|
|
func (r *Repo) UpsertLevel(ctx context.Context, lvl *Level) error {
|
|
const q = `
|
|
INSERT INTO levels (guild, user_id, level, xp)
|
|
VALUES ($1, $2, $3, $4)
|
|
ON CONFLICT (guild, user_id)
|
|
DO UPDATE SET level = EXCLUDED.level, xp = EXCLUDED.xp
|
|
`
|
|
_, err := r.db.ExecContext(ctx, q, lvl.GuildID, lvl.UserID, lvl.Level, lvl.XP)
|
|
return err
|
|
}
|
|
|
|
func (r *Repo) SetLevel(ctx context.Context, guildID, userID int64, level int) error {
|
|
const q = `
|
|
INSERT INTO levels (guild, user_id, level, xp)
|
|
VALUES ($1, $2, $3, 99)
|
|
ON CONFLICT (guild, user_id)
|
|
DO UPDATE SET level = EXCLUDED.level, xp = 99
|
|
`
|
|
_, err := r.db.ExecContext(ctx, q, guildID, userID, level)
|
|
return err
|
|
}
|
|
|
|
func (r *Repo) TopLevels(ctx context.Context, guildID int64, limit int) ([]*Level, error) {
|
|
const q = `
|
|
SELECT user_id, level, xp
|
|
FROM levels
|
|
WHERE guild = $1
|
|
ORDER BY level DESC, xp DESC, user_id ASC
|
|
LIMIT $2
|
|
`
|
|
|
|
rows, err := r.db.QueryContext(ctx, q, guildID, limit)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
out := make([]*Level, 0, limit)
|
|
for rows.Next() {
|
|
lvl := &Level{GuildID: guildID}
|
|
if err := rows.Scan(&lvl.UserID, &lvl.Level, &lvl.XP); err != nil {
|
|
return nil, err
|
|
}
|
|
out = append(out, lvl)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return out, nil
|
|
}
|