// Package repository package repository import ( "context" "fmt" "time" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" "gogs.fxtmmsk.ru/foxtime/photoplaces/backend/internal/models" ) type UserRepo struct { pool *pgxpool.Pool } func NewUserRepo(pool *pgxpool.Pool) *UserRepo { return &UserRepo{pool: pool} } func (r *UserRepo) Create(ctx context.Context, u *models.User) error { return r.pool.QueryRow(ctx, `INSERT INTO users (email, password_hash, role, name) VALUES ($1, $2, $3, $4) RETURNING id, created_at, updated_at`, u.Email, u.PasswordHash, u.Role, u.Name, ).Scan(&u.ID, &u.CreatedAt, &u.UpdatedAt) } func (r *UserRepo) GetByID(ctx context.Context, id string) (*models.User, error) { row := r.pool.QueryRow(ctx, `SELECT id, email, password_hash, role, status, name, avatar_url, phone, bio, country, created_at, updated_at, deleted_at FROM users WHERE id = $1 AND deleted_at IS NULL`, id) return scanUser(row) } func (r *UserRepo) GetByEmail(ctx context.Context, email string) (*models.User, error) { row := r.pool.QueryRow(ctx, `SELECT id, email, password_hash, role, status, name, avatar_url, phone, bio, country, created_at, updated_at, deleted_at FROM users WHERE email = $1 AND deleted_at IS NULL`, email) return scanUser(row) } func (r *UserRepo) Update(ctx context.Context, u *models.User) error { u.UpdatedAt = time.Now() _, err := r.pool.Exec(ctx, `UPDATE users SET name=$1, phone=$2, bio=$3, avatar_url=$4, country=$5, updated_at=$6 WHERE id=$7 AND deleted_at IS NULL`, u.Name, u.Phone, u.Bio, u.AvatarURL, u.Country, u.UpdatedAt, u.ID) return err } func (r *UserRepo) UpdateRole(ctx context.Context, id, role string) error { _, err := r.pool.Exec(ctx, `UPDATE users SET role=$1, updated_at=now() WHERE id=$2 AND deleted_at IS NULL`, role, id) return err } func (r *UserRepo) UpdateStatus(ctx context.Context, id, status string) error { _, err := r.pool.Exec(ctx, `UPDATE users SET status=$1, updated_at=now() WHERE id=$2 AND deleted_at IS NULL`, status, id) return err } func (r *UserRepo) List(ctx context.Context, filter models.UserFilter) ([]*models.User, error) { query := `SELECT id, email, password_hash, role, status, name, avatar_url, phone, bio, country, created_at, updated_at, deleted_at FROM users WHERE deleted_at IS NULL` args := pgx.NamedArgs{} if filter.Role != "" { query += ` AND role = @role` args["role"] = filter.Role } if filter.Status != "" { query += ` AND status = @status` args["status"] = filter.Status } query += ` ORDER BY created_at DESC LIMIT @lim` args["lim"] = filter.Limit() rows, err := r.pool.Query(ctx, query, args) if err != nil { return nil, fmt.Errorf("list users: %w", err) } defer rows.Close() var users []*models.User for rows.Next() { u, err := scanUser(rows) if err != nil { return nil, err } users = append(users, u) } return users, nil } func scanUser(row interface{ Scan(dest ...any) error }) (*models.User, error) { var u models.User err := row.Scan( &u.ID, &u.Email, &u.PasswordHash, &u.Role, &u.Status, &u.Name, &u.AvatarURL, &u.Phone, &u.Bio, &u.Country, &u.CreatedAt, &u.UpdatedAt, &u.DeletedAt, ) if err != nil { if err == pgx.ErrNoRows { return nil, nil } return nil, err } return &u, nil }