users.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package repository
  2. import (
  3. "context"
  4. "fmt"
  5. "time"
  6. "github.com/jackc/pgx/v5"
  7. "github.com/jackc/pgx/v5/pgxpool"
  8. "github.com/photoplaces/backend/internal/models"
  9. )
  10. type UserRepo struct {
  11. pool *pgxpool.Pool
  12. }
  13. func NewUserRepo(pool *pgxpool.Pool) *UserRepo {
  14. return &UserRepo{pool: pool}
  15. }
  16. func (r *UserRepo) Create(ctx context.Context, u *models.User) error {
  17. return r.pool.QueryRow(ctx,
  18. `INSERT INTO users (email, password_hash, role, name)
  19. VALUES ($1, $2, $3, $4)
  20. RETURNING id, created_at, updated_at`,
  21. u.Email, u.PasswordHash, u.Role, u.Name,
  22. ).Scan(&u.ID, &u.CreatedAt, &u.UpdatedAt)
  23. }
  24. func (r *UserRepo) GetByID(ctx context.Context, id string) (*models.User, error) {
  25. row := r.pool.QueryRow(ctx,
  26. `SELECT id, email, password_hash, role, status, name, avatar_url, phone, bio, country,
  27. created_at, updated_at, deleted_at
  28. FROM users WHERE id = $1 AND deleted_at IS NULL`, id)
  29. return scanUser(row)
  30. }
  31. func (r *UserRepo) GetByEmail(ctx context.Context, email string) (*models.User, error) {
  32. row := r.pool.QueryRow(ctx,
  33. `SELECT id, email, password_hash, role, status, name, avatar_url, phone, bio, country,
  34. created_at, updated_at, deleted_at
  35. FROM users WHERE email = $1 AND deleted_at IS NULL`, email)
  36. return scanUser(row)
  37. }
  38. func (r *UserRepo) Update(ctx context.Context, u *models.User) error {
  39. u.UpdatedAt = time.Now()
  40. _, err := r.pool.Exec(ctx,
  41. `UPDATE users SET name=$1, phone=$2, bio=$3, avatar_url=$4, country=$5, updated_at=$6
  42. WHERE id=$7 AND deleted_at IS NULL`,
  43. u.Name, u.Phone, u.Bio, u.AvatarURL, u.Country, u.UpdatedAt, u.ID)
  44. return err
  45. }
  46. func (r *UserRepo) UpdateRole(ctx context.Context, id, role string) error {
  47. _, err := r.pool.Exec(ctx,
  48. `UPDATE users SET role=$1, updated_at=now() WHERE id=$2 AND deleted_at IS NULL`, role, id)
  49. return err
  50. }
  51. func (r *UserRepo) UpdateStatus(ctx context.Context, id, status string) error {
  52. _, err := r.pool.Exec(ctx,
  53. `UPDATE users SET status=$1, updated_at=now() WHERE id=$2 AND deleted_at IS NULL`, status, id)
  54. return err
  55. }
  56. func (r *UserRepo) List(ctx context.Context, filter models.UserFilter) ([]*models.User, error) {
  57. query := `SELECT id, email, password_hash, role, status, name, avatar_url, phone, bio, country,
  58. created_at, updated_at, deleted_at
  59. FROM users WHERE deleted_at IS NULL`
  60. args := pgx.NamedArgs{}
  61. if filter.Role != "" {
  62. query += ` AND role = @role`
  63. args["role"] = filter.Role
  64. }
  65. if filter.Status != "" {
  66. query += ` AND status = @status`
  67. args["status"] = filter.Status
  68. }
  69. query += ` ORDER BY created_at DESC LIMIT @lim`
  70. args["lim"] = filter.Limit()
  71. rows, err := r.pool.Query(ctx, query, args)
  72. if err != nil {
  73. return nil, fmt.Errorf("list users: %w", err)
  74. }
  75. defer rows.Close()
  76. var users []*models.User
  77. for rows.Next() {
  78. u, err := scanUser(rows)
  79. if err != nil {
  80. return nil, err
  81. }
  82. users = append(users, u)
  83. }
  84. return users, nil
  85. }
  86. func scanUser(row interface{ Scan(dest ...any) error }) (*models.User, error) {
  87. var u models.User
  88. err := row.Scan(
  89. &u.ID, &u.Email, &u.PasswordHash, &u.Role, &u.Status,
  90. &u.Name, &u.AvatarURL, &u.Phone, &u.Bio, &u.Country,
  91. &u.CreatedAt, &u.UpdatedAt, &u.DeletedAt,
  92. )
  93. if err != nil {
  94. if err == pgx.ErrNoRows {
  95. return nil, nil
  96. }
  97. return nil, err
  98. }
  99. return &u, nil
  100. }