package db import ( "context" "fmt" "time" "git.haelnorr.com/h/golib/hwsauth" "github.com/bwmarrin/discordgo" "github.com/pkg/errors" "github.com/uptrace/bun" ) var CurrentUser hwsauth.ContextLoader[*User] type User struct { bun.BaseModel `bun:"table:users,alias:u"` ID int `bun:"id,pk,autoincrement"` // Integer ID (index primary key) Username string `bun:"username,unique"` // Username (unique) CreatedAt int64 `bun:"created_at"` // Epoch timestamp when the user was added to the database DiscordID string `bun:"discord_id,unique"` } func (user *User) GetID() int { return user.ID } // CreateUser creates a new user with the given username and password func CreateUser(ctx context.Context, tx bun.Tx, username string, discorduser *discordgo.User) (*User, error) { if discorduser == nil { return nil, errors.New("user cannot be nil") } user := &User{ Username: username, CreatedAt: time.Now().Unix(), DiscordID: discorduser.ID, } _, err := tx.NewInsert(). Model(user). Exec(ctx) if err != nil { return nil, errors.Wrap(err, "tx.NewInsert") } return user, nil } // GetUserByID queries the database for a user matching the given ID // Returns nil, nil if no user is found func GetUserByID(ctx context.Context, tx bun.Tx, id int) (*User, error) { fmt.Printf("user id requested: %v", id) user := new(User) err := tx.NewSelect(). Model(user). Where("id = ?", id). Limit(1). Scan(ctx) if err != nil { if err.Error() == "sql: no rows in result set" { return nil, nil } return nil, errors.Wrap(err, "tx.NewSelect") } return user, nil } // GetUserByUsername queries the database for a user matching the given username // Returns nil, nil if no user is found func GetUserByUsername(ctx context.Context, tx bun.Tx, username string) (*User, error) { user := new(User) err := tx.NewSelect(). Model(user). Where("username = ?", username). Limit(1). Scan(ctx) if err != nil { if err.Error() == "sql: no rows in result set" { return nil, nil } return nil, errors.Wrap(err, "tx.Select") } return user, nil } // GetUserByDiscordID queries the database for a user matching the given discord id // Returns nil, nil if no user is found func GetUserByDiscordID(ctx context.Context, tx bun.Tx, discordID string) (*User, error) { user := new(User) err := tx.NewSelect(). Model(user). Where("discord_id = ?", discordID). Limit(1). Scan(ctx) if err != nil { if err.Error() == "sql: no rows in result set" { return nil, nil } return nil, errors.Wrap(err, "tx.NewSelect") } return user, nil } // IsUsernameUnique checks if the given username is unique (not already taken) // Returns true if the username is available, false if it's taken func IsUsernameUnique(ctx context.Context, tx bun.Tx, username string) (bool, error) { count, err := tx.NewSelect(). Model((*User)(nil)). Where("username = ?", username). Count(ctx) if err != nil { return false, errors.Wrap(err, "tx.NewSelect") } return count == 0, nil }