tailly_back_v2/internal/repository/user_repository.go
madipo2611 0d4b8b203e v0.0.2
2025-05-01 12:17:42 +03:00

184 lines
3.8 KiB
Go

package repository
import (
"context"
"database/sql"
"errors"
"tailly_back_v2/internal/domain"
"time"
)
var (
ErrUserNotFound = errors.New("user not found")
)
type UserRepository interface {
Create(ctx context.Context, user *domain.User) error
GetByID(ctx context.Context, id int) (*domain.User, error)
GetByEmail(ctx context.Context, email string) (*domain.User, error)
GetByConfirmationToken(ctx context.Context, token string) (*domain.User, error)
Update(ctx context.Context, user *domain.User) error
Delete(ctx context.Context, id int) error
}
type userRepository struct {
db *sql.DB
}
func NewUserRepository(db *sql.DB) UserRepository {
return &userRepository{db: db}
}
func (r *userRepository) Create(ctx context.Context, user *domain.User) error {
query := `
INSERT INTO users (username, email, password, email_confirmation_token, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING id
`
err := r.db.QueryRowContext(ctx, query,
user.Username,
user.Email,
user.Password,
user.EmailConfirmationToken,
user.CreatedAt,
user.UpdatedAt,
).Scan(&user.ID)
return err
}
func (r *userRepository) GetByID(ctx context.Context, id int) (*domain.User, error) {
query := `
SELECT id, username, email, password, email_confirmation_token, email_confirmed_at, created_at, updated_at
FROM users
WHERE id = $1
`
user := &domain.User{}
var confirmedAt sql.NullTime
err := r.db.QueryRowContext(ctx, query, id).Scan(
&user.ID,
&user.Username,
&user.Email,
&user.Password,
&user.EmailConfirmationToken,
&confirmedAt,
&user.CreatedAt,
&user.UpdatedAt,
)
if err == sql.ErrNoRows {
return nil, ErrUserNotFound
}
if confirmedAt.Valid {
user.EmailConfirmedAt = &confirmedAt.Time
}
return user, err
}
func (r *userRepository) GetByEmail(ctx context.Context, email string) (*domain.User, error) {
query := `
SELECT id, username, email, password, email_confirmation_token, email_confirmed_at, created_at, updated_at
FROM users
WHERE email = $1
`
user := &domain.User{}
var confirmedAt sql.NullTime
err := r.db.QueryRowContext(ctx, query, email).Scan(
&user.ID,
&user.Username,
&user.Email,
&user.Password,
&user.EmailConfirmationToken,
&confirmedAt,
&user.CreatedAt,
&user.UpdatedAt,
)
if err == sql.ErrNoRows {
return nil, ErrUserNotFound
}
if confirmedAt.Valid {
user.EmailConfirmedAt = &confirmedAt.Time
}
return user, err
}
func (r *userRepository) GetByConfirmationToken(ctx context.Context, token string) (*domain.User, error) {
query := `
SELECT id, username, email, password, email_confirmation_token, email_confirmed_at, created_at, updated_at
FROM users
WHERE email_confirmation_token = $1
`
user := &domain.User{}
var confirmedAt sql.NullTime
err := r.db.QueryRowContext(ctx, query, token).Scan(
&user.ID,
&user.Username,
&user.Email,
&user.Password,
&user.EmailConfirmationToken,
&confirmedAt,
&user.CreatedAt,
&user.UpdatedAt,
)
if err == sql.ErrNoRows {
return nil, ErrUserNotFound
}
if confirmedAt.Valid {
user.EmailConfirmedAt = &confirmedAt.Time
}
return user, err
}
func (r *userRepository) Update(ctx context.Context, user *domain.User) error {
query := `
UPDATE users
SET username = $1,
email = $2,
password = $3,
email_confirmation_token = $4,
email_confirmed_at = $5,
updated_at = $6
WHERE id = $7
`
var confirmedAt interface{}
if user.EmailConfirmedAt != nil {
confirmedAt = *user.EmailConfirmedAt
} else {
confirmedAt = nil
}
_, err := r.db.ExecContext(ctx, query,
user.Username,
user.Email,
user.Password,
user.EmailConfirmationToken,
confirmedAt,
time.Now(), // Обновляем updated_at
user.ID,
)
return err
}
func (r *userRepository) Delete(ctx context.Context, id int) error {
query := `DELETE FROM users WHERE id = $1`
_, err := r.db.ExecContext(ctx, query, id)
return err
}