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