vyvanse/internal/dao/users.go

123 lines
2.8 KiB
Go

package dao
import (
"context"
"database/sql"
"git.xeserv.us/xena/gorqlite"
"github.com/opentracing/opentracing-go"
splog "github.com/opentracing/opentracing-go/log"
)
type Users struct {
conn gorqlite.Connection
}
func NewUsers(conn gorqlite.Connection) *Users {
return &Users{conn: conn}
}
func (u *Users) Migrate(ctx context.Context) error {
sp, ctx := opentracing.StartSpanFromContext(ctx, "users.migrate")
defer sp.Finish()
migrationDDL := []string{
`CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY, discord_id TEXT UNIQUE, score INTEGER)`,
}
res, err := u.conn.Write(migrationDDL)
if err != nil {
sp.LogFields(splog.Error(err))
}
for i, re := range res {
if re.Err != nil {
sp.LogFields(splog.Error(err))
return err
}
sp.LogFields(splog.Int("migration.step", i), splog.Float64("timing", re.Timing), splog.Int64("rows.affected", re.RowsAffected))
}
return nil
}
func (u *Users) Insert(ctx context.Context, discordID string) (int64, error) {
sp, ctx := opentracing.StartSpanFromContext(ctx, "users.insert")
defer sp.Finish()
sp.LogFields(splog.String("discord.id", discordID))
re, err := u.conn.WriteOne(gorqlite.NewPreparedStatement("INSERT INTO users (discord_id, score) VALUES (%s, 0)").Bind(discordID))
if err != nil {
sp.LogFields(splog.Error(err))
sp.LogFields(splog.Error(re.Err))
return -1, err
}
if re.Err != nil {
sp.LogFields(splog.Error(re.Err))
return -1, err
}
return re.LastInsertID, nil
}
func (u *Users) IncScore(ctx context.Context, discordID string) error {
sp, ctx := opentracing.StartSpanFromContext(ctx, "users.inc.score")
defer sp.Finish()
sp.LogFields(splog.String("discord.id", discordID))
re, err := u.conn.WriteOne(gorqlite.NewPreparedStatement("UPDATE users SET score = score + 1 WHERE discord_id=%s").Bind(discordID))
if err != nil {
sp.LogFields(splog.Error(err))
}
if re.Err != nil {
sp.LogFields(splog.Error(re.Err))
return re.Err
}
return nil
}
type User struct {
ID int64 `json:"id"`
DiscordID string `json:"discord_id"`
Score int64 `json:"score"`
}
func (u *Users) Top10(ctx context.Context) ([]User, error) {
sp, ctx := opentracing.StartSpanFromContext(ctx, "users.top10")
defer sp.Finish()
qr, err := u.conn.QueryOne("SELECT id, discord_id, score FROM users WHERE score > 0 ORDER BY score DESC LIMIT 10")
if err != nil {
sp.LogFields(splog.Error(err))
}
if qr.Err != nil {
sp.LogFields(splog.Error(qr.Err))
return nil, qr.Err
}
var result []User
if qr.NumRows() == 0 {
sp.LogFields(splog.Error(sql.ErrNoRows))
return nil, sql.ErrNoRows
}
for qr.Next() {
var u User
err = qr.Scan(&u.ID, &u.DiscordID, &u.Score)
if err != nil {
sp.LogFields(splog.Error(err))
return nil, err
}
result = append(result, u)
}
return result, nil
}