gitea源码

star.go 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // Copyright 2016 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package repo
  4. import (
  5. "context"
  6. "code.gitea.io/gitea/models/db"
  7. user_model "code.gitea.io/gitea/models/user"
  8. "code.gitea.io/gitea/modules/timeutil"
  9. )
  10. // Star represents a starred repo by an user.
  11. type Star struct {
  12. ID int64 `xorm:"pk autoincr"`
  13. UID int64 `xorm:"UNIQUE(s)"`
  14. RepoID int64 `xorm:"UNIQUE(s)"`
  15. CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
  16. }
  17. func init() {
  18. db.RegisterModel(new(Star))
  19. }
  20. // StarRepo or unstar repository.
  21. func StarRepo(ctx context.Context, doer *user_model.User, repo *Repository, star bool) error {
  22. return db.WithTx(ctx, func(ctx context.Context) error {
  23. staring := IsStaring(ctx, doer.ID, repo.ID)
  24. if star {
  25. if user_model.IsUserBlockedBy(ctx, doer, repo.OwnerID) {
  26. return user_model.ErrBlockedUser
  27. }
  28. if staring {
  29. return nil
  30. }
  31. if err := db.Insert(ctx, &Star{UID: doer.ID, RepoID: repo.ID}); err != nil {
  32. return err
  33. }
  34. if _, err := db.Exec(ctx, "UPDATE `repository` SET num_stars = num_stars + 1 WHERE id = ?", repo.ID); err != nil {
  35. return err
  36. }
  37. if _, err := db.Exec(ctx, "UPDATE `user` SET num_stars = num_stars + 1 WHERE id = ?", doer.ID); err != nil {
  38. return err
  39. }
  40. } else {
  41. if !staring {
  42. return nil
  43. }
  44. if _, err := db.DeleteByBean(ctx, &Star{UID: doer.ID, RepoID: repo.ID}); err != nil {
  45. return err
  46. }
  47. if _, err := db.Exec(ctx, "UPDATE `repository` SET num_stars = num_stars - 1 WHERE id = ?", repo.ID); err != nil {
  48. return err
  49. }
  50. if _, err := db.Exec(ctx, "UPDATE `user` SET num_stars = num_stars - 1 WHERE id = ?", doer.ID); err != nil {
  51. return err
  52. }
  53. }
  54. return nil
  55. })
  56. }
  57. // IsStaring checks if user has starred given repository.
  58. func IsStaring(ctx context.Context, userID, repoID int64) bool {
  59. has, _ := db.GetEngine(ctx).Get(&Star{UID: userID, RepoID: repoID})
  60. return has
  61. }
  62. // GetStargazers returns the users that starred the repo.
  63. func GetStargazers(ctx context.Context, repo *Repository, opts db.ListOptions) ([]*user_model.User, error) {
  64. sess := db.GetEngine(ctx).Where("star.repo_id = ?", repo.ID).
  65. Join("LEFT", "star", "`user`.id = star.uid")
  66. if opts.Page > 0 {
  67. sess = db.SetSessionPagination(sess, &opts)
  68. users := make([]*user_model.User, 0, opts.PageSize)
  69. return users, sess.Find(&users)
  70. }
  71. users := make([]*user_model.User, 0, 8)
  72. return users, sess.Find(&users)
  73. }
  74. // ClearRepoStars clears all stars for a repository and from the user that starred it.
  75. // Used when a repository is set to private.
  76. func ClearRepoStars(ctx context.Context, repoID int64) error {
  77. if _, err := db.Exec(ctx, "UPDATE `user` SET num_stars=num_stars-1 WHERE id IN (SELECT `uid` FROM `star` WHERE repo_id = ?)", repoID); err != nil {
  78. return err
  79. }
  80. if _, err := db.Exec(ctx, "UPDATE `repository` SET num_stars = 0 WHERE id = ?", repoID); err != nil {
  81. return err
  82. }
  83. return db.DeleteBeans(ctx, Star{RepoID: repoID})
  84. }