package storage import ( "context" "errors" "strings" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgconn" "github.com/jackc/pgx/v5/pgxpool" "github.com/alchemistkay/guestguard/internal/domain" ) type UserRepo struct { pool *pgxpool.Pool } func NewUserRepo(db *DB) *UserRepo { return &UserRepo{pool: db.Pool} } func (r *UserRepo) Create(ctx context.Context, email, name string) (*domain.User, error) { const q = ` INSERT INTO users (email, name) VALUES ($1, $2) RETURNING id, email, name, created_at, updated_at ` row := r.pool.QueryRow(ctx, q, strings.ToLower(strings.TrimSpace(email)), strings.TrimSpace(name)) u, err := scanUser(row) if err != nil { var pgErr *pgconn.PgError if errors.As(err, &pgErr) && pgErr.Code == "23505" { return nil, domain.ErrEmailTaken } return nil, err } return u, nil } func (r *UserRepo) GetByEmail(ctx context.Context, email string) (*domain.User, error) { const q = `SELECT id, email, name, created_at, updated_at FROM users WHERE email = $1` u, err := scanUser(r.pool.QueryRow(ctx, q, strings.ToLower(strings.TrimSpace(email)))) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return nil, domain.ErrUserNotFound } return nil, err } return u, nil } func scanUser(s rowScanner) (*domain.User, error) { var u domain.User if err := s.Scan(&u.ID, &u.Email, &u.Name, &u.CreatedAt, &u.UpdatedAt); err != nil { return nil, err } return &u, nil }