package db import ( "fmt" "log/slog" "slices" "strings" "time" ) type User struct { db *DB log *slog.Logger ID int TguID int Subs []string Created time.Time Edited time.Time Deleted time.Time } type Inst struct { db *DB log *slog.Logger List []string } func NewUser(db *DB, log *slog.Logger) User { return User{ log: log, db: db, } } // GetAll // Get all users in db func (u *User) GetAll(name string) (users []User, err error) { stmt, err := u.db.Prepare("SELECT users.id, users.tgu_id, users.subs FROM users WHERE users.subs LIKE ?") if err != nil { u.log.Error("[user-GetAll]", "error", err) return nil, err } rows, err := stmt.Query("%" + name + "%") if err != nil { u.log.Error("[user-GetAll-stmt]", "error", err) return nil, err } defer rows.Close() users = []User{} for rows.Next() { user := User{} subs := "" if err = rows.Scan(&user.ID, &user.TguID, &subs); err != nil { u.log.Error("[user-GetAll-scanning]", "error", err) return users, err } if subs == "" { u.log.Info("[user-GetAll-scanning] returning subs empty") continue } user.Subs = strings.Split(subs, ",") u.log.Info("user", "no", user) users = append(users, user) } if err := rows.Err(); err != nil { u.log.Error("[user-GetAll-returning]", "error", err) return users, err } return users, nil } // Get // Get an specific user func (u *User) Get(telegramID int64) (user User, err error) { stmt, err := u.db.Prepare("SELECT users.id, users.tgu_id, users.subs FROM users WHERE tgu_id=?") if err != nil { u.log.Error("[user-Get]", "error", err) return user, err } subs := "" err = stmt.QueryRow(telegramID).Scan(&user.ID, &user.TguID, &subs) if err != nil { u.log.Error("[user-Get-stmt]", "error", err) return user, err } if subs != "" { user.Subs = strings.Split(subs, ",") } else { user.Subs = []string{} } u.ID, u.TguID, u.Subs = user.ID, user.TguID, user.Subs return user, nil } // Add // Add user to database func (u *User) Add(telegramID int64) (bool, error) { stmt, err := u.db.Prepare("INSERT INTO users ('tgu_id', 'subs', 'created', 'edited') VALUES(?,?,datetime(),datetime())") if err != nil { u.log.Error("[user-Add-stmt]", "error", err) return false, err } _, err = stmt.Exec(telegramID, "") if err != nil { u.log.Error("[user-Add-exec]", "error", err) return false, err } return true, nil } // Edit // edit user info in database func (u *User) Subscribe(name string) (err error) { if u.TguID == 0 || u.ID == 0 { err = fmt.Errorf("user needs to have a telegram id or reference on db") u.log.Error("[user-Subscribe-check]", "error", err) return err } idx := slices.Index[[]string](u.Subs, name) if idx >= 0 { return fmt.Errorf("user alredy subscribed to inst") } u.Subs = append(u.Subs, name) stmt, err := u.db.Prepare("UPDATE users SET subs=? WHERE tgu_id=?") if err != nil { u.log.Error("[user-Subscribe-stmt]", "error", err) return err } strSubs := strings.Join(u.Subs, ",") _, err = stmt.Exec(strSubs, u.TguID) if err != nil { u.log.Error("[user-Subscribe-exec]", "error", err) return err } return nil } // Delete // Delete user from database func (u *User) Unsubscribe(name string) (err error) { if u.TguID == 0 || u.ID == 0 { err = fmt.Errorf("user needs to have a telegram id or reference on db") u.log.Error("[user-UnSubscribe-check]", "error", err) return err } if len(u.Subs) <= 0 { err = fmt.Errorf("user needs to have a subscription to unsubcribe") u.log.Error("[user-UnSubscribe-check]", "error", err) return err } idx := slices.Index[[]string](u.Subs, name) if idx >= 0 { u.Subs = slices.Delete[[]string](u.Subs, idx, idx+1) } else { err = fmt.Errorf("user is not subscribed to %s", name) u.log.Error("[user-UnSubscribe-check]", "error", err) return err } stmt, err := u.db.Prepare("UPDATE users SET subs=? WHERE tgu_id=?") if err != nil { u.log.Error("[user-UnSubscribe-stmt]", "error", err) return err } strSubs := strings.Join(u.Subs, ",") _, err = stmt.Exec(strSubs, u.TguID) if err != nil { u.log.Error("[user-UnSubscribe-exec]", "error", err) return err } return nil } // Reset // Clean user subscriptions on system func (u *User) Reset() (err error) { if u.TguID == 0 || u.ID == 0 { err = fmt.Errorf("user needs to have a telegram id or reference on db") u.log.Error("[user-Subscribe-check]", "error", err) return err } stmt, err := u.db.Prepare("UPDATE users SET subs=? WHERE tgu_id=?") if err != nil { u.log.Error("[user-Subscribe-stmt]", "error", err) return err } _, err = stmt.Exec("", u.TguID) if err != nil { u.log.Error("[user-Subscribe-exec]", "error", err) return err } return nil } func NewInst(dbx *DB, log *slog.Logger) Inst { return Inst{ log: log, db: dbx, } } func (i *Inst) GetAll() ([]string, error) { stmt, err := i.db.Prepare("SELECT DISTINCT dolars.name FROM dolars WHERE name LIKE '%ban%' OR name LIKE '%scoti%' OR name LIKE '%asociacion%'") if err != nil { i.log.Error("[inst-GetAll]", "error", err) return nil, err } rows, err := stmt.Query() if err != nil { i.log.Error("[inst-GetAll-stmt]", "error", err) return nil, err } defer rows.Close() insts := []string{} for rows.Next() { inst := "" if err = rows.Scan(&inst); err != nil { return nil, err } if inst == "" { continue } insts = append(insts, inst) } if err := rows.Err(); err != nil { return insts, err } return insts, nil } func (i *Inst) GetBancos() ([]string, error) { stmt, err := i.db.Prepare("SELECT DISTINCT dolars.name FROM dolars WHERE name LIKE '%ban%' OR name LIKE '%scoti%'") if err != nil { i.log.Error("[inst-GetAll]", "error", err) return nil, err } rows, err := stmt.Query() if err != nil { i.log.Error("[inst-GetAll-stmt]", "error", err) return nil, err } defer rows.Close() insts := []string{} for rows.Next() { inst := "" if err = rows.Scan(&inst); err != nil { return nil, err } if inst == "" { continue } insts = append(insts, inst) } if err := rows.Err(); err != nil { return insts, err } return insts, nil } func (i *Inst) GetCajas() ([]string, error) { stmt, err := i.db.Prepare("SELECT DISTINCT dolars.name FROM dolars WHERE name LIKE '%asociacion%'") if err != nil { i.log.Error("[inst-GetAll]", "error", err) return nil, err } rows, err := stmt.Query() if err != nil { i.log.Error("[inst-GetAll-stmt]", "error", err) return nil, err } defer rows.Close() insts := []string{} for rows.Next() { inst := "" if err = rows.Scan(&inst); err != nil { return nil, err } if inst == "" { continue } insts = append(insts, inst) } if err := rows.Err(); err != nil { return insts, err } return insts, nil } func (i *Inst) GetAgentes() ([]string, error) { stmt, err := i.db.Prepare("SELECT DISTINCT dolars.name FROM dolars WHERE name NOT LIKE '%ban%' AND name NOT LIKE '%scoti%' AND name NOT LIKE '%asociacion%'") if err != nil { i.log.Error("[inst-GetAll]", "error", err) return nil, err } rows, err := stmt.Query() if err != nil { i.log.Error("[inst-GetAll-stmt]", "error", err) return nil, err } defer rows.Close() insts := []string{} for rows.Next() { inst := "" if err = rows.Scan(&inst); err != nil { return nil, err } if inst == "" { continue } insts = append(insts, inst) } if err := rows.Err(); err != nil { return insts, err } return insts, nil }