package psql import ( "context" "database/sql" "errors" "kurumibot/laniakea" "math" "time" "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 GetAllUsers() ([]*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 }