mirror of
https://github.com/Sosokker/go-chi-oapi-codegen-todolist.git
synced 2025-12-19 14:04:07 +01:00
157 lines
3.6 KiB
Go
157 lines
3.6 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/Sosokker/todolist-backend/internal/domain"
|
|
db "github.com/Sosokker/todolist-backend/internal/repository/sqlc/generated"
|
|
"github.com/google/uuid"
|
|
"github.com/jackc/pgx/v5"
|
|
"github.com/jackc/pgx/v5/pgconn"
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
type pgxUserRepository struct {
|
|
q *db.Queries
|
|
}
|
|
|
|
func NewPgxUserRepository(queries *db.Queries) UserRepository {
|
|
return &pgxUserRepository{q: queries}
|
|
}
|
|
|
|
// mapDbUserToDomain converts a generated User → domain.User
|
|
func mapDbUserToDomain(u db.User) *domain.User {
|
|
var googleID *string
|
|
if u.GoogleID.Valid {
|
|
googleID = &u.GoogleID.String
|
|
}
|
|
return &domain.User{
|
|
ID: u.ID,
|
|
Username: u.Username,
|
|
Email: u.Email,
|
|
PasswordHash: u.PasswordHash,
|
|
EmailVerified: u.EmailVerified,
|
|
GoogleID: googleID,
|
|
CreatedAt: u.CreatedAt,
|
|
UpdatedAt: u.UpdatedAt,
|
|
}
|
|
}
|
|
|
|
func (r *pgxUserRepository) Create(
|
|
ctx context.Context,
|
|
user *domain.User,
|
|
) (*domain.User, error) {
|
|
var pgGoogleID pgtype.Text
|
|
if user.GoogleID != nil {
|
|
pgGoogleID = pgtype.Text{String: *user.GoogleID, Valid: true}
|
|
}
|
|
|
|
dbUser, err := r.q.CreateUser(ctx, db.CreateUserParams{
|
|
Username: user.Username,
|
|
Email: user.Email,
|
|
PasswordHash: user.PasswordHash,
|
|
EmailVerified: user.EmailVerified,
|
|
GoogleID: pgGoogleID,
|
|
})
|
|
if err != nil {
|
|
var pgErr *pgconn.PgError
|
|
if errors.As(err, &pgErr) && pgErr.Code == "23505" {
|
|
return nil, domain.ErrConflict
|
|
}
|
|
return nil, err
|
|
}
|
|
return mapDbUserToDomain(dbUser), nil
|
|
}
|
|
|
|
func (r *pgxUserRepository) GetByID(
|
|
ctx context.Context,
|
|
id uuid.UUID,
|
|
) (*domain.User, error) {
|
|
dbUser, err := r.q.GetUserByID(ctx, id)
|
|
if err != nil {
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return nil, domain.ErrNotFound
|
|
}
|
|
return nil, err
|
|
}
|
|
return mapDbUserToDomain(dbUser), nil
|
|
}
|
|
|
|
func (r *pgxUserRepository) GetByEmail(
|
|
ctx context.Context,
|
|
email string,
|
|
) (*domain.User, error) {
|
|
dbUser, err := r.q.GetUserByEmail(ctx, email)
|
|
if err != nil {
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return nil, domain.ErrNotFound
|
|
}
|
|
return nil, err
|
|
}
|
|
return mapDbUserToDomain(dbUser), nil
|
|
}
|
|
|
|
func (r *pgxUserRepository) GetByGoogleID(
|
|
ctx context.Context,
|
|
googleID string,
|
|
) (*domain.User, error) {
|
|
pgGoogleID := pgtype.Text{String: googleID, Valid: true}
|
|
dbUser, err := r.q.GetUserByGoogleID(ctx, pgGoogleID)
|
|
if err != nil {
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return nil, domain.ErrNotFound
|
|
}
|
|
return nil, err
|
|
}
|
|
return mapDbUserToDomain(dbUser), nil
|
|
}
|
|
|
|
func (r *pgxUserRepository) Update(
|
|
ctx context.Context,
|
|
id uuid.UUID,
|
|
u *domain.User,
|
|
) (*domain.User, error) {
|
|
if _, err := r.GetByID(ctx, id); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var username pgtype.Text
|
|
if u.Username != "" {
|
|
username = pgtype.Text{String: u.Username, Valid: true}
|
|
}
|
|
var email pgtype.Text
|
|
if u.Email != "" {
|
|
email = pgtype.Text{String: u.Email, Valid: true}
|
|
}
|
|
emailVerified := pgtype.Bool{Bool: u.EmailVerified, Valid: true}
|
|
|
|
var pgGoogleID pgtype.Text
|
|
if u.GoogleID != nil {
|
|
pgGoogleID = pgtype.Text{String: *u.GoogleID, Valid: true}
|
|
}
|
|
|
|
dbUser, err := r.q.UpdateUser(ctx, db.UpdateUserParams{
|
|
ID: id,
|
|
Username: username,
|
|
Email: email,
|
|
EmailVerified: emailVerified,
|
|
GoogleID: pgGoogleID,
|
|
})
|
|
if err != nil {
|
|
var pgErr *pgconn.PgError
|
|
if errors.As(err, &pgErr) && pgErr.Code == "23505" {
|
|
return nil, domain.ErrConflict
|
|
}
|
|
return nil, err
|
|
}
|
|
return mapDbUserToDomain(dbUser), nil
|
|
}
|
|
|
|
func (r *pgxUserRepository) Delete(
|
|
ctx context.Context,
|
|
id uuid.UUID,
|
|
) error {
|
|
return r.q.DeleteUser(ctx, id)
|
|
}
|