package users_repo import ( "context" "errors" "evening_detective_server/internal/repos" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" ) var ( ErrUserNotFound = errors.New("Пользователь не найден") ) type UsersRepo struct { pool *pgxpool.Pool } func NewUserRepo(pool *pgxpool.Pool) *UsersRepo { return &UsersRepo{ pool: pool, } } func (s *UsersRepo) AddUser( ctx context.Context, username string, email string, passwordHash string, roles []string, ) error { tag, err := s.pool.Exec( ctx, `INSERT INTO users (username, email, password_hash, roles) SELECT $1, $2, $3, $4 WHERE NOT EXISTS ( SELECT 1 FROM users WHERE username = $5 OR email = $6 )`, username, email, passwordHash, roles, username, email, ) if err != nil { return err } if tag.RowsAffected() == 0 { return errors.New("username или email уже используется") } return nil } func (s *UsersRepo) UpdateUserPassword( ctx context.Context, email string, passwordHash string, ) error { tag, err := s.pool.Exec( ctx, `UPDATE users SET password_hash = $1 WHERE email = $2`, passwordHash, email, ) if err != nil { return err } if tag.RowsAffected() == 0 { return ErrUserNotFound } return nil } func (s *UsersRepo) GetUserByEmail( ctx context.Context, email string, ) (*repos.User, error) { user := &repos.User{} row := s.pool.QueryRow( ctx, `SELECT id, username, email, password_hash, roles, is_active FROM users WHERE email = $1`, email, ) err := row.Scan( &user.ID, &user.Username, &user.Email, &user.PasswordHash, &user.Roles, &user.IsActive, ) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return nil, ErrUserNotFound } return nil, err } return user, nil } func (s *UsersRepo) GetUserByID( ctx context.Context, id int, ) (*repos.User, error) { user := &repos.User{} row := s.pool.QueryRow( ctx, `SELECT id, username, email, password_hash, roles, is_active FROM users WHERE id = $1`, id, ) err := row.Scan( &user.ID, &user.Username, &user.Email, &user.PasswordHash, &user.Roles, &user.IsActive, ) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return nil, ErrUserNotFound } return nil, err } return user, nil } func (s *UsersRepo) GetUsers( ctx context.Context, ) ([]*repos.User, error) { rows, err := s.pool.Query( ctx, `SELECT id, username, email, roles, is_active, created_at FROM users ORDER BY created_at DESC`, ) if err != nil { return nil, err } defer rows.Close() var users []*repos.User for rows.Next() { user := &repos.User{} err := rows.Scan( &user.ID, &user.Username, &user.Email, &user.Roles, &user.IsActive, &user.CreatedAt, ) if err != nil { return nil, err } users = append(users, user) } if err := rows.Err(); err != nil { return nil, err } return users, nil }