2016-12-29 12:58:24 -02:00
// Copyright 2016 The Gitea Authors. All rights reserved.
2022-11-27 13:20:29 -05:00
// SPDX-License-Identifier: MIT
2016-12-29 12:58:24 -02:00
2021-12-12 23:48:20 +08:00
package repo
2016-12-29 12:58:24 -02:00
2020-10-13 02:01:57 +02:00
import (
2022-05-20 22:08:52 +08:00
"context"
2021-09-19 19:49:59 +08:00
"code.gitea.io/gitea/models/db"
2021-11-24 17:49:20 +08:00
user_model "code.gitea.io/gitea/models/user"
2020-10-13 02:01:57 +02:00
"code.gitea.io/gitea/modules/timeutil"
)
2016-12-29 12:58:24 -02:00
// Star represents a starred repo by an user.
type Star struct {
2020-10-13 02:01:57 +02:00
ID int64 ` xorm:"pk autoincr" `
UID int64 ` xorm:"UNIQUE(s)" `
RepoID int64 ` xorm:"UNIQUE(s)" `
CreatedUnix timeutil . TimeStamp ` xorm:"INDEX created" `
2016-12-29 12:58:24 -02:00
}
2021-09-19 19:49:59 +08:00
func init ( ) {
db . RegisterModel ( new ( Star ) )
}
2016-12-29 12:58:24 -02:00
// StarRepo or unstar repository.
2023-09-15 08:13:19 +02:00
func StarRepo ( ctx context . Context , userID , repoID int64 , star bool ) error {
ctx , committer , err := db . TxContext ( ctx )
2021-11-21 23:41:00 +08:00
if err != nil {
2016-12-29 12:58:24 -02:00
return err
}
2021-11-21 23:41:00 +08:00
defer committer . Close ( )
2022-05-20 22:08:52 +08:00
staring := IsStaring ( ctx , userID , repoID )
2016-12-29 12:58:24 -02:00
if star {
2021-11-21 23:41:00 +08:00
if staring {
2016-12-29 12:58:24 -02:00
return nil
}
2021-11-21 23:41:00 +08:00
if err := db . Insert ( ctx , & Star { UID : userID , RepoID : repoID } ) ; err != nil {
2016-12-29 12:58:24 -02:00
return err
}
2021-11-21 23:41:00 +08:00
if _ , err := db . Exec ( ctx , "UPDATE `repository` SET num_stars = num_stars + 1 WHERE id = ?" , repoID ) ; err != nil {
2016-12-29 12:58:24 -02:00
return err
}
2021-11-21 23:41:00 +08:00
if _ , err := db . Exec ( ctx , "UPDATE `user` SET num_stars = num_stars + 1 WHERE id = ?" , userID ) ; err != nil {
2016-12-29 12:58:24 -02:00
return err
}
} else {
2021-11-21 23:41:00 +08:00
if ! staring {
2016-12-29 12:58:24 -02:00
return nil
}
2021-11-21 23:41:00 +08:00
if _ , err := db . DeleteByBean ( ctx , & Star { UID : userID , RepoID : repoID } ) ; err != nil {
2016-12-29 12:58:24 -02:00
return err
}
2021-11-21 23:41:00 +08:00
if _ , err := db . Exec ( ctx , "UPDATE `repository` SET num_stars = num_stars - 1 WHERE id = ?" , repoID ) ; err != nil {
2016-12-29 12:58:24 -02:00
return err
}
2021-11-21 23:41:00 +08:00
if _ , err := db . Exec ( ctx , "UPDATE `user` SET num_stars = num_stars - 1 WHERE id = ?" , userID ) ; err != nil {
2016-12-29 12:58:24 -02:00
return err
}
}
2021-11-21 23:41:00 +08:00
return committer . Commit ( )
2016-12-29 12:58:24 -02:00
}
// IsStaring checks if user has starred given repository.
2022-05-20 22:08:52 +08:00
func IsStaring ( ctx context . Context , userID , repoID int64 ) bool {
has , _ := db . GetEngine ( ctx ) . Get ( & Star { UID : userID , RepoID : repoID } )
2016-12-29 12:58:24 -02:00
return has
}
// GetStargazers returns the users that starred the repo.
2023-09-15 08:13:19 +02:00
func GetStargazers ( ctx context . Context , repo * Repository , opts db . ListOptions ) ( [ ] * user_model . User , error ) {
sess := db . GetEngine ( ctx ) . Where ( "star.repo_id = ?" , repo . ID ) .
2017-01-06 02:05:09 -05:00
Join ( "LEFT" , "star" , "`user`.id = star.uid" )
2020-01-24 19:00:29 +00:00
if opts . Page > 0 {
2021-09-24 19:32:56 +08:00
sess = db . SetSessionPagination ( sess , & opts )
2020-01-24 19:00:29 +00:00
2021-11-24 17:49:20 +08:00
users := make ( [ ] * user_model . User , 0 , opts . PageSize )
2020-01-24 19:00:29 +00:00
return users , sess . Find ( & users )
2017-01-06 02:05:09 -05:00
}
2020-01-24 19:00:29 +00:00
2021-11-24 17:49:20 +08:00
users := make ( [ ] * user_model . User , 0 , 8 )
2017-01-06 02:05:09 -05:00
return users , sess . Find ( & users )
2016-12-29 12:58:24 -02:00
}
2023-06-05 15:25:43 +02:00
// ClearRepoStars clears all stars for a repository and from the user that starred it.
// Used when a repository is set to private.
func ClearRepoStars ( ctx context . Context , repoID int64 ) error {
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 {
return err
}
if _ , err := db . Exec ( ctx , "UPDATE `repository` SET num_stars = 0 WHERE id = ?" , repoID ) ; err != nil {
return err
}
return db . DeleteBeans ( ctx , Star { RepoID : repoID } )
}