Files
YaeMikoBot/database/psql/users.go
2026-01-28 21:50:58 +03:00

174 lines
4.2 KiB
Go

package psql
import (
"context"
"database/sql"
"errors"
"math"
"time"
"git.nix13.pw/scuroneko/laniakea"
"github.com/shopspring/decimal"
"github.com/vinovest/sqlx"
)
type User struct {
ID int
Balance decimal.Decimal
Name string
GroupID int `db:"group_id"`
Level int
Exp int
WorkID int `db:"work_id"`
WorkTime time.Time `db:"work_time"`
AutoID sql.NullInt32 `db:"auto_id"`
BusinessID sql.NullInt32 `db:"business_id"`
MaidID sql.NullInt32 `db:"maid_id"`
MinerID sql.NullInt32 `db:"miner_id"`
IncomeTime time.Time `db:"income_time"`
BTC decimal.Decimal
Invested decimal.Decimal
PairID sql.NullInt64 `db:"pair_id"`
Greeting string
Donat int
FractionID sql.NullInt32 `db:"fraction_id"`
MoneyIncome decimal.Decimal `db:"money_income"`
ExpIncome int `db:"exp_income"`
BtcIncome decimal.Decimal `db:"btc_income"`
WaifuSearchTime time.Time `db:"waifu_search_time"`
Group *Group
Work *Work
Auto *ShopAuto
Business *ShopBusiness
Maid *ShopMaid
Miner *ShopMiner
Pair *User
Fraction *Fraction
}
type UserRepository struct {
db *sqlx.DB
}
func NewUserRepository(db *laniakea.DatabaseContext) *UserRepository {
return &UserRepository{db: db.PostgresSQL}
}
func (rep *UserRepository) GetOrCreate(tgId int, name string) (*User, error) {
user, err := rep.GetById(tgId)
if errors.Is(err, sql.ErrNoRows) {
user, err = rep.Create(tgId, name)
}
return user, err
}
func (rep *UserRepository) Create(id int, name string) (*User, error) {
user := new(User)
err := rep.db.Get(user, "INSERT INTO users (id, name) VALUES ($1, $2) RETURNING *;", id, name)
return user, err
}
func (rep *UserRepository) GetById(telegramId int) (*User, error) {
user := new(User)
err := sqlx.Transact(rep.db, func(ctx context.Context, db sqlx.Queryable) error {
err := rep.db.Get(user, "SELECT * FROM users WHERE id=$1;", telegramId)
if err != nil {
return err
}
user.Group = new(Group)
err = rep.db.Get(user.Group, "SELECT * FROM groups WHERE id=$1;", user.GroupID)
if err != nil {
return err
}
user.Work = new(Work)
err = rep.db.Get(user.Work, "SELECT * FROM works WHERE id=$1;", user.WorkID)
if err != nil {
return err
}
shopRep := NewShopRepository(rep.db)
if user.AutoID.Valid {
user.Auto, err = shopRep.GetAuto(user.AutoID.Int32)
if err != nil {
return err
}
}
if user.BusinessID.Valid {
user.Business, err = shopRep.GetBusiness(user.BusinessID.Int32)
if err != nil {
return err
}
}
if user.MaidID.Valid {
user.Maid, err = shopRep.GetMaid(user.MaidID.Int32)
if err != nil {
return err
}
}
if user.MinerID.Valid {
user.Miner, err = shopRep.GetMiner(user.MinerID.Int32)
if err != nil {
return err
}
}
if user.PairID.Valid {
user.Pair, err = rep.GetById(int(user.PairID.Int64))
if err != nil {
return err
}
}
if user.FractionID.Valid {
fractionRep := NewFractionRepository(rep.db)
user.Fraction, err = fractionRep.GetById(user.FractionID.Int32)
if err != nil {
return err
}
}
return nil
})
return user, err
}
func (rep *UserRepository) Update(user *User) (*User, error) {
_, err := rep.db.NamedExec(
`UPDATE users SET balance=:balance, name=:name, group_id=:group_id, level=:level, exp=:exp,
work_id=:work_id, work_time=:work_time, auto_id=:auto_id, business_id=:business_id,
maid_id=:maid_id, miner_id=:miner_id, income_time=:income_time, btc=:btc, invested=:invested,
pair_id=:pair_id, greeting=:greeting, donat=:donat, fraction_id=:fraction_id,
money_income=:money_income, exp_income=:exp_income, btc_income=:btc_income,
waifu_search_time=:waifu_search_time
WHERE id=:id;`,
user,
)
if err != nil {
return nil, err
}
return rep.GetById(user.ID)
}
func (rep *UserRepository) GetAll() ([]*User, error) {
users := make([]*User, 0)
return users, nil
}
func CountLevel(userXp int) (int, int) {
xp := 0
nextLevel := 2
for {
xp = int(math.Pow(float64(nextLevel), 3)) * (nextLevel * 3)
if xp > userXp {
break
}
if nextLevel == 200 {
break
}
nextLevel++
}
return nextLevel - 1, xp
}