package users import ( "context" "errors" "time" "github.com/google/uuid" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" ) type User struct { ID uuid.UUID Email string Phone string Name string Birthdate *time.Time Gender string City string Bio string PhotoURL string IsVerified bool IsBlocked bool CreatedAt time.Time UpdatedAt time.Time LastSeenAt *time.Time } type Repo struct { pool *pgxpool.Pool } func NewRepo(pool *pgxpool.Pool) *Repo { return &Repo{pool: pool} } func (r *Repo) CreateWithPassword(ctx context.Context, u *User, passwordHash string) error { return r.pool.QueryRow(ctx, ` INSERT INTO users (email, phone, password_hash, name, birthdate, gender, city) VALUES (NULLIF($1, ''), NULLIF($2, ''), $3, $4, $5, NULLIF($6, ''), NULLIF($7, '')) RETURNING id, created_at, updated_at`, u.Email, u.Phone, passwordHash, u.Name, u.Birthdate, u.Gender, u.City, ).Scan(&u.ID, &u.CreatedAt, &u.UpdatedAt) } func (r *Repo) UpdateRaw(ctx context.Context, sql string, args ...interface{}) (int64, error) { tag, err := r.pool.Exec(ctx, sql, args...) if err != nil { return 0, err } return tag.RowsAffected(), nil } func (r *Repo) GetByID(ctx context.Context, id uuid.UUID) (*User, error) { u := &User{} var email, phone, gender, city, bio, photo *string var birth *time.Time err := r.pool.QueryRow(ctx, ` SELECT id, email, phone, name, birthdate, gender, city, bio, photo_url, is_verified, is_blocked, created_at, updated_at, last_seen_at FROM users WHERE id=$1`, id, ).Scan(&u.ID, &email, &phone, &u.Name, &birth, &gender, &city, &bio, &photo, &u.IsVerified, &u.IsBlocked, &u.CreatedAt, &u.UpdatedAt, &u.LastSeenAt) if errors.Is(err, pgx.ErrNoRows) { return nil, nil } if err != nil { return nil, err } if email != nil { u.Email = *email } if phone != nil { u.Phone = *phone } if gender != nil { u.Gender = *gender } if city != nil { u.City = *city } if bio != nil { u.Bio = *bio } if photo != nil { u.PhotoURL = *photo } if birth != nil { u.Birthdate = birth } return u, nil } func (r *Repo) GetByEmail(ctx context.Context, email string) (*User, string, error) { u := &User{} var hash string var em *string var birth *time.Time var gender, city, bio, photo *string err := r.pool.QueryRow(ctx, ` SELECT id, email, password_hash, name, birthdate, gender, city, bio, photo_url, is_verified, is_blocked, created_at, updated_at, last_seen_at FROM users WHERE email=$1`, email, ).Scan(&u.ID, &em, &hash, &u.Name, &birth, &gender, &city, &bio, &photo, &u.IsVerified, &u.IsBlocked, &u.CreatedAt, &u.UpdatedAt, &u.LastSeenAt) if errors.Is(err, pgx.ErrNoRows) { return nil, "", nil } if err != nil { return nil, "", err } if em != nil { u.Email = *em } if gender != nil { u.Gender = *gender } if city != nil { u.City = *city } if bio != nil { u.Bio = *bio } if photo != nil { u.PhotoURL = *photo } if birth != nil { u.Birthdate = birth } return u, hash, nil }