You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

star.go 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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, userID, repoID int64, star bool) error {
  22. ctx, committer, err := db.TxContext(ctx)
  23. if err != nil {
  24. return err
  25. }
  26. defer committer.Close()
  27. staring := IsStaring(ctx, userID, repoID)
  28. if star {
  29. if staring {
  30. return nil
  31. }
  32. if err := db.Insert(ctx, &Star{UID: userID, RepoID: repoID}); err != nil {
  33. return err
  34. }
  35. if _, err := db.Exec(ctx, "UPDATE `repository` SET num_stars = num_stars + 1 WHERE id = ?", repoID); err != nil {
  36. return err
  37. }
  38. if _, err := db.Exec(ctx, "UPDATE `user` SET num_stars = num_stars + 1 WHERE id = ?", userID); err != nil {
  39. return err
  40. }
  41. } else {
  42. if !staring {
  43. return nil
  44. }
  45. if _, err := db.DeleteByBean(ctx, &Star{UID: userID, RepoID: repoID}); err != nil {
  46. return err
  47. }
  48. if _, err := db.Exec(ctx, "UPDATE `repository` SET num_stars = num_stars - 1 WHERE id = ?", repoID); err != nil {
  49. return err
  50. }
  51. if _, err := db.Exec(ctx, "UPDATE `user` SET num_stars = num_stars - 1 WHERE id = ?", userID); err != nil {
  52. return err
  53. }
  54. }
  55. return committer.Commit()
  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. }