Handle empty database when checking for duplicate users (#419)

This commit is contained in:
shenlan 2025-10-06 13:28:08 +08:00 committed by GitHub
parent 4d1139e2b9
commit 953a2acf76

View File

@ -109,18 +109,24 @@ func (s *postgresStore) CreateUser(ctx context.Context, user *User) error {
}
if normalizedEmail != "" {
if _, err := s.GetUserByEmail(ctx, normalizedEmail); err == nil {
return ErrEmailExists
} else if !errors.Is(err, ErrUserNotFound) {
const emailExistsQuery = "SELECT EXISTS(SELECT 1 FROM users WHERE lower(email) = $1)"
emailExists, err := s.userExists(ctx, emailExistsQuery, normalizedEmail)
if err != nil {
return err
}
if emailExists {
return ErrEmailExists
}
}
if _, err := s.GetUserByName(ctx, normalizedName); err == nil {
return ErrNameExists
} else if !errors.Is(err, ErrUserNotFound) {
const nameExistsQuery = "SELECT EXISTS(SELECT 1 FROM users WHERE lower(username) = lower($1))"
nameExists, err := s.userExists(ctx, nameExistsQuery, normalizedName)
if err != nil {
return err
}
if nameExists {
return ErrNameExists
}
query := `INSERT INTO users (username, password, email, email_verified_at)
VALUES ($1, $2, $3, $4)
@ -163,6 +169,31 @@ func (s *postgresStore) CreateUser(ctx context.Context, user *User) error {
return nil
}
func (s *postgresStore) userExists(ctx context.Context, query string, arg any) (bool, error) {
var exists bool
err := s.db.QueryRowContext(ctx, query, arg).Scan(&exists)
if err != nil {
if isDatabaseEmptyError(err) {
return false, nil
}
return false, err
}
return exists, nil
}
func isDatabaseEmptyError(err error) bool {
if errors.Is(err, sql.ErrNoRows) {
return true
}
var pgErr *pgconn.PgError
if errors.As(err, &pgErr) {
if pgErr.Code == "42P01" { // undefined_table
return true
}
}
return false
}
func (s *postgresStore) GetUserByEmail(ctx context.Context, email string) (*User, error) {
normalized := strings.ToLower(strings.TrimSpace(email))
if normalized == "" {