feat: leveling system
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user