package db import ( "context" "database/sql" "fmt" "log/slog" "strings" "git.maximotejeda.com/maximo/tgb-user/internal/application/core/domain" ) type User struct { db *sql.DB log *slog.Logger ID int64 `json:"id"` Tgb_ID int64 `json:"tgb_id"` Username string `json:"username"` FirstName string `json:"first_name"` LastName string `json:"last_name"` Created int64 `json:"created"` Edited int64 `json:"edited"` Deleted int64 `json:"deleted"` } func NewUser(db *sql.DB, log *slog.Logger) *User { log = log.With("obj", "User") return &User{ db: db, log: log, } } func (u User) Get(ctx context.Context, tgb_id int64) (*domain.User, error) { stmt, err := u.db.PrepareContext(ctx, ` SELECT u.id, u.tgb_id, u.username, u.first_name, u.last_name, u.created, u.edited FROM users AS u WHERE u.tgb_id = ? AND deleted IS NULL; `) if err != nil { u.log.Error("prepare stmt get", "error", err) return nil, err } defer stmt.Close() us := &domain.User{} if err := stmt.QueryRowContext(ctx, tgb_id).Scan(&us.ID, &us.TGB_ID, &us.Username, &us.FirstName, &us.LastName, &us.Created, &us.Edited); err != nil { u.log.Error("query row context get", "error", err) return nil, err } bu := NewBotUser(u.db, u.log) bul, err := bu.GetBots(ctx, us.TGB_ID) if err != nil { u.log.Error("getting bots", "error", err) } for _, i := range bul { us.TGBOT = us.TGBOT + "," + i.BotName } us.TGBOT, _ = strings.CutPrefix(us.TGBOT, ",") return us, nil } func (u User) Create(ctx context.Context, user *domain.User) (bool, error) { stmt, err := u.db.PrepareContext(ctx, ` INSERT INTO users (tgb_id, username, first_name, last_name, created, edited) VALUES(?,?,?,?,strftime('%s', 'now'),strftime('%s', 'now')); `) if err != nil { u.log.Error("prepare stmt create", "error", err) return false, err } defer stmt.Close() _, err = stmt.ExecContext(ctx, user.TGB_ID, user.Username, user.FirstName, user.LastName) if err != nil { u.log.Error("exec context create", "error", err) return false, err } return true, nil } func (u User) Edit(ctx context.Context, user domain.User) (bool, error) { stmt, err := u.db.PrepareContext(ctx, ` UPDATE users SET username = ?, first_name = ?, last_name = ?, edited = strftime('%s', 'now') WHERE tgb_id = ? AND deleted IS NULL; `) if err != nil { u.log.Error("prepare stmt edit", "error", err) return false, err } defer stmt.Close() row, err := stmt.ExecContext(ctx, user.Username, user.FirstName, user.LastName, user.TGB_ID) if err != nil { u.log.Error("exec context edit", "error", err) return false, nil } num, _ := row.RowsAffected() if num < 1 { return false, fmt.Errorf("no rows affected with tgb_id: %d", user.TGB_ID) } return true, nil } func (u User) Delete(ctx context.Context, tgb_id int64) (bool, error) { stmt, err := u.db.PrepareContext(ctx, ` UPDATE users SET deleted = strftime('%s', 'now'), edited = strftime('%s', 'now') WHERE tgb_id = ?; `) if err != nil { u.log.Error("prepare stmt delete", "error", err) return false, err } defer stmt.Close() _, err = stmt.ExecContext(ctx, tgb_id) if err != nil { u.log.Error("exec context delete", "error", err) return false, err } return true, nil } func (u User) HardDelete(ctx context.Context, tgb_id int64) (bool, error) { stmt, err := u.db.PrepareContext(ctx, ` DELETE FROM users WHERE tgb_id = ?; `) if err != nil { u.log.Error("prepare stmt hard delete", "error", err) return false, err } defer stmt.Close() _, err = stmt.ExecContext(ctx, tgb_id) if err != nil { u.log.Error("exec context hard delete", "error", err) return false, err } return true, nil } func (u User) AddBot(ctx context.Context, tgb_id int64, bot_name string) (bool, error) { bu := BotUser{db: u.db} ok, err := bu.Add(ctx, tgb_id, bot_name) return ok, err } func (u User) DeleteBot(ctx context.Context, tgb_id int64, bot_name string) (bool, error) { bu := BotUser{db: u.db} ok, err := bu.Delete(ctx, tgb_id, bot_name) return ok, err }