DeleteByID deletes the given user and all their resources. It returns ErrUserOwnRepos when the user still has repository ownership, or returns ErrUserHasOrgs when the user still has organization membership. It is more performant to skip rewriting the "authorized_keys" file for individual deletion in
(ctx context.Context, userID int64, skipRewriteAuthorizedKeys bool)
| 393 | // performant to skip rewriting the "authorized_keys" file for individual |
| 394 | // deletion in a batch operation. |
| 395 | func (s *UsersStore) DeleteByID(ctx context.Context, userID int64, skipRewriteAuthorizedKeys bool) error { |
| 396 | user, err := s.GetByID(ctx, userID) |
| 397 | if err != nil { |
| 398 | if IsErrUserNotExist(err) { |
| 399 | return nil |
| 400 | } |
| 401 | return errors.Wrap(err, "get user") |
| 402 | } |
| 403 | |
| 404 | // Double-check the user is not a direct owner of any repository and not a |
| 405 | // member of any organization. |
| 406 | var count int64 |
| 407 | err = s.db.WithContext(ctx).Model(&Repository{}).Where("owner_id = ?", userID).Count(&count).Error |
| 408 | if err != nil { |
| 409 | return errors.Wrap(err, "count repositories") |
| 410 | } else if count > 0 { |
| 411 | return ErrUserOwnRepos{args: errutil.Args{"userID": userID}} |
| 412 | } |
| 413 | |
| 414 | err = s.db.WithContext(ctx).Model(&OrgUser{}).Where("uid = ?", userID).Count(&count).Error |
| 415 | if err != nil { |
| 416 | return errors.Wrap(err, "count organization membership") |
| 417 | } else if count > 0 { |
| 418 | return ErrUserHasOrgs{args: errutil.Args{"userID": userID}} |
| 419 | } |
| 420 | |
| 421 | needsRewriteAuthorizedKeys := false |
| 422 | err = s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { |
| 423 | /* |
| 424 | Equivalent SQL for PostgreSQL: |
| 425 | |
| 426 | UPDATE repository |
| 427 | SET num_watches = num_watches - 1 |
| 428 | WHERE id IN ( |
| 429 | SELECT repo_id FROM watch WHERE user_id = @userID |
| 430 | ) |
| 431 | */ |
| 432 | err = tx.Table("repository"). |
| 433 | Where("id IN (?)", tx. |
| 434 | Select("repo_id"). |
| 435 | Table("watch"). |
| 436 | Where("user_id = ?", userID), |
| 437 | ). |
| 438 | UpdateColumn("num_watches", gorm.Expr("num_watches - 1")). |
| 439 | Error |
| 440 | if err != nil { |
| 441 | return errors.Wrap(err, `decrease "repository.num_watches"`) |
| 442 | } |
| 443 | |
| 444 | /* |
| 445 | Equivalent SQL for PostgreSQL: |
| 446 | |
| 447 | UPDATE repository |
| 448 | SET num_stars = num_stars - 1 |
| 449 | WHERE id IN ( |
| 450 | SELECT repo_id FROM star WHERE uid = @userID |
| 451 | ) |
| 452 | */ |