package bundb import ( "context" "database/sql" "errors" "fmt" "gitea.dwysokinski.me/twhelp/sessions/internal/bundb/internal/model" "gitea.dwysokinski.me/twhelp/sessions/internal/domain" "github.com/jackc/pgerrcode" "github.com/uptrace/bun" "github.com/uptrace/bun/driver/pgdriver" ) type User struct { db *bun.DB } func NewUser(db *bun.DB) *User { return &User{db: db} } func (u *User) Create(ctx context.Context, params domain.CreateUserParams) (domain.User, error) { user := model.NewUser(params) if _, err := u.db.NewInsert(). Model(&user). Returning("*"). Exec(ctx); err != nil { return domain.User{}, fmt.Errorf( "something went wrong while inserting user into the db: %w", mapCreateUserError(err, params), ) } return user.ToDomain(), nil } func (u *User) Get(ctx context.Context, id int64) (domain.User, error) { var user model.User if err := u.db.NewSelect(). Model(&user). Where("id = ?", id). Scan(ctx); err != nil { if errors.Is(err, sql.ErrNoRows) { return domain.User{}, domain.UserNotFoundError{ID: id} } return domain.User{}, fmt.Errorf( "something went wrong while selecting user (id=%d) from the db: %w", id, err, ) } return user.ToDomain(), nil } func mapCreateUserError(err error, params domain.CreateUserParams) error { var pgError pgdriver.Error if !errors.As(err, &pgError) { return err } code := pgError.Field('C') constraint := pgError.Field('n') switch { case code == pgerrcode.UniqueViolation && constraint == "users_name_lower_key": return domain.UsernameAlreadyTakenError{ Name: params.Name(), } default: return err } }