Przeglądaj źródła

Rewrite XORM queries

tags/v1.0.0
Thibault Meyer 7 lat temu
rodzic
commit
a4454f5d0f
No account linked to committer's email address

+ 6
- 2
models/access.go Wyświetl plik

// GetAccessibleRepositories finds repositories which the user has access but does not own. // GetAccessibleRepositories finds repositories which the user has access but does not own.
// If limit is smaller than 1 means returns all found results. // If limit is smaller than 1 means returns all found results.
func (user *User) GetAccessibleRepositories(limit int) (repos []*Repository, _ error) { func (user *User) GetAccessibleRepositories(limit int) (repos []*Repository, _ error) {
sess := x.Where("owner_id !=? ", user.ID).Desc("updated_unix")
sess := x.
Where("owner_id !=? ", user.ID).
Desc("updated_unix")
if limit > 0 { if limit > 0 {
sess.Limit(limit) sess.Limit(limit)
repos = make([]*Repository, 0, limit) repos = make([]*Repository, 0, limit)
} else { } else {
repos = make([]*Repository, 0, 10) repos = make([]*Repository, 0, 10)
} }
return repos, sess.Join("INNER", "access", "access.user_id = ? AND access.repo_id = repository.id", user.ID).Find(&repos)
return repos, sess.
Join("INNER", "access", "access.user_id = ? AND access.repo_id = repository.id", user.ID).
Find(&repos)
} }


func maxAccessMode(modes ...AccessMode) AccessMode { func maxAccessMode(modes ...AccessMode) AccessMode {

+ 18
- 13
models/action.go Wyświetl plik

type ActionType int type ActionType int


const ( const (
ActionCreateRepo ActionType = iota + 1 // 1
ActionRenameRepo // 2
ActionStarRepo // 3
ActionWatchRepo // 4
ActionCommitRepo // 5
ActionCreateIssue // 6
ActionCreateRepo ActionType = iota + 1 // 1
ActionRenameRepo // 2
ActionStarRepo // 3
ActionWatchRepo // 4
ActionCommitRepo // 5
ActionCreateIssue // 6
ActionCreatePullRequest // 7 ActionCreatePullRequest // 7
ActionTransferRepo // 8
ActionPushTag // 9
ActionCommentIssue // 10
ActionTransferRepo // 8
ActionPushTag // 9
ActionCommentIssue // 10
ActionMergePullRequest // 11 ActionMergePullRequest // 11
ActionCloseIssue // 12
ActionReopenIssue // 13
ActionCloseIssue // 12
ActionReopenIssue // 13
ActionClosePullRequest // 14 ActionClosePullRequest // 14
ActionReopenPullRequest // 15 ActionReopenPullRequest // 15
) )
// actorID can be -1 when isProfile is true or to skip the permission check. // actorID can be -1 when isProfile is true or to skip the permission check.
func GetFeeds(ctxUser *User, actorID, offset int64, isProfile bool) ([]*Action, error) { func GetFeeds(ctxUser *User, actorID, offset int64, isProfile bool) ([]*Action, error) {
actions := make([]*Action, 0, 20) actions := make([]*Action, 0, 20)
sess := x.Limit(20, int(offset)).Desc("id").Where("user_id = ?", ctxUser.ID)
sess := x.
Limit(20, int(offset)).
Desc("id").
Where("user_id = ?", ctxUser.ID)
if isProfile { if isProfile {
sess.And("is_private = ?", false).And("act_user_id = ?", ctxUser.ID)
sess.
And("is_private = ?", false).
And("act_user_id = ?", ctxUser.ID)
} else if actorID != -1 && ctxUser.IsOrganization() { } else if actorID != -1 && ctxUser.IsOrganization() {
// FIXME: only need to get IDs here, not all fields of repository. // FIXME: only need to get IDs here, not all fields of repository.
repos, _, err := ctxUser.GetUserRepositories(actorID, 1, ctxUser.NumRepos) repos, _, err := ctxUser.GetUserRepositories(actorID, 1, ctxUser.NumRepos)

+ 7
- 2
models/admin.go Wyświetl plik

// Notices returns number of notices in given page. // Notices returns number of notices in given page.
func Notices(page, pageSize int) ([]*Notice, error) { func Notices(page, pageSize int) ([]*Notice, error) {
notices := make([]*Notice, 0, pageSize) notices := make([]*Notice, 0, pageSize)
return notices, x.Limit(pageSize, (page-1)*pageSize).Desc("id").Find(&notices)
return notices, x.
Limit(pageSize, (page-1)*pageSize).
Desc("id").
Find(&notices)
} }


// DeleteNotice deletes a system notice by given ID. // DeleteNotice deletes a system notice by given ID.
if len(ids) == 0 { if len(ids) == 0 {
return nil return nil
} }
_, err := x.Where("id IN (" + strings.Join(base.Int64sToStrings(ids), ",") + ")").Delete(new(Notice))
_, err := x.
Where("id IN (" + strings.Join(base.Int64sToStrings(ids), ",") + ")").
Delete(new(Notice))
return err return err
} }

+ 1
- 1
models/git_diff.go Wyświetl plik

"strings" "strings"


"github.com/Unknwon/com" "github.com/Unknwon/com"
"github.com/go-gitea/git"
"github.com/go-gitea/gitea/modules/base" "github.com/go-gitea/gitea/modules/base"
"github.com/go-gitea/gitea/modules/log" "github.com/go-gitea/gitea/modules/log"
"github.com/go-gitea/gitea/modules/process" "github.com/go-gitea/gitea/modules/process"
"github.com/go-gitea/gitea/modules/setting" "github.com/go-gitea/gitea/modules/setting"
"github.com/go-gitea/gitea/modules/template/highlight" "github.com/go-gitea/gitea/modules/template/highlight"
"github.com/go-gitea/git"
"github.com/sergi/go-diff/diffmatchpatch" "github.com/sergi/go-diff/diffmatchpatch"
"golang.org/x/net/html/charset" "golang.org/x/net/html/charset"
"golang.org/x/text/transform" "golang.org/x/text/transform"

+ 41
- 14
models/issue.go Wyświetl plik

"time" "time"


"github.com/Unknwon/com" "github.com/Unknwon/com"
"github.com/go-xorm/xorm"
api "github.com/go-gitea/go-sdk/gitea" api "github.com/go-gitea/go-sdk/gitea"
"github.com/go-xorm/xorm"
gouuid "github.com/satori/go.uuid" gouuid "github.com/satori/go.uuid"


"github.com/go-gitea/gitea/modules/base" "github.com/go-gitea/gitea/modules/base"
sess := x.Limit(setting.UI.IssuePagingNum, (opts.Page-1)*setting.UI.IssuePagingNum) sess := x.Limit(setting.UI.IssuePagingNum, (opts.Page-1)*setting.UI.IssuePagingNum)


if opts.RepoID > 0 { if opts.RepoID > 0 {
sess.Where("issue.repo_id=?", opts.RepoID).And("issue.is_closed=?", opts.IsClosed)
sess.
Where("issue.repo_id=?", opts.RepoID).
And("issue.is_closed=?", opts.IsClosed)
} else if opts.RepoIDs != nil { } else if opts.RepoIDs != nil {
// In case repository IDs are provided but actually no repository has issue. // In case repository IDs are provided but actually no repository has issue.
if len(opts.RepoIDs) == 0 { if len(opts.RepoIDs) == 0 {
return make([]*Issue, 0), nil return make([]*Issue, 0), nil
} }
sess.In("issue.repo_id", base.Int64sToStrings(opts.RepoIDs)).And("issue.is_closed=?", opts.IsClosed)
sess.
In("issue.repo_id", base.Int64sToStrings(opts.RepoIDs)).
And("issue.is_closed=?", opts.IsClosed)
} else { } else {
sess.Where("issue.is_closed=?", opts.IsClosed) sess.Where("issue.is_closed=?", opts.IsClosed)
} }
if len(opts.Labels) > 0 && opts.Labels != "0" { if len(opts.Labels) > 0 && opts.Labels != "0" {
labelIDs := base.StringsToInt64s(strings.Split(opts.Labels, ",")) labelIDs := base.StringsToInt64s(strings.Split(opts.Labels, ","))
if len(labelIDs) > 0 { if len(labelIDs) > 0 {
sess.Join("INNER", "issue_label", "issue.id = issue_label.issue_id").In("issue_label.label_id", labelIDs)
sess.
Join("INNER", "issue_label", "issue.id = issue_label.issue_id").
In("issue_label.label_id", labelIDs)
} }
} }


if opts.IsMention { if opts.IsMention {
sess.Join("INNER", "issue_user", "issue.id = issue_user.issue_id").And("issue_user.is_mentioned = ?", true)
sess.
Join("INNER", "issue_user", "issue.id = issue_user.issue_id").
And("issue_user.is_mentioned = ?", true)


if opts.UserID > 0 { if opts.UserID > 0 {
sess.And("issue_user.uid = ?", opts.UserID) sess.And("issue_user.uid = ?", opts.UserID)
} }


ius := make([]*IssueUser, 0, 10) ius := make([]*IssueUser, 0, 10)
sess := x.Limit(20, (page-1)*20).Where("is_closed=?", isClosed).In("repo_id", rids)
sess := x.
Limit(20, (page-1)*20).
Where("is_closed=?", isClosed).
In("repo_id", rids)
err := sess.Find(&ius) err := sess.Find(&ius)
return ius, err return ius, err
} }
// GetIssueUserPairsByMode returns issue-user pairs by given repository and user. // GetIssueUserPairsByMode returns issue-user pairs by given repository and user.
func GetIssueUserPairsByMode(uid, rid int64, isClosed bool, page, filterMode int) ([]*IssueUser, error) { func GetIssueUserPairsByMode(uid, rid int64, isClosed bool, page, filterMode int) ([]*IssueUser, error) {
ius := make([]*IssueUser, 0, 10) ius := make([]*IssueUser, 0, 10)
sess := x.Limit(20, (page-1)*20).Where("uid=?", uid).And("is_closed=?", isClosed)
sess := x.
Limit(20, (page-1)*20).
Where("uid=?", uid).
And("is_closed=?", isClosed)
if rid > 0 { if rid > 0 {
sess.And("repo_id=?", rid) sess.And("repo_id=?", rid)
} }
stats := &IssueStats{} stats := &IssueStats{}


countSession := func(opts *IssueStatsOptions) *xorm.Session { countSession := func(opts *IssueStatsOptions) *xorm.Session {
sess := x.Where("issue.repo_id = ?", opts.RepoID).And("is_pull = ?", opts.IsPull)
sess := x.
Where("issue.repo_id = ?", opts.RepoID).
And("is_pull = ?", opts.IsPull)


if len(opts.Labels) > 0 && opts.Labels != "0" { if len(opts.Labels) > 0 && opts.Labels != "0" {
labelIDs := base.StringsToInt64s(strings.Split(opts.Labels, ",")) labelIDs := base.StringsToInt64s(strings.Split(opts.Labels, ","))
if len(labelIDs) > 0 { if len(labelIDs) > 0 {
sess.Join("INNER", "issue_label", "issue.id = issue_id").In("label_id", labelIDs)
sess.
Join("INNER", "issue_label", "issue.id = issue_id").
In("label_id", labelIDs)
} }
} }


stats := &IssueStats{} stats := &IssueStats{}


countSession := func(isClosed, isPull bool, repoID int64, repoIDs []int64) *xorm.Session { countSession := func(isClosed, isPull bool, repoID int64, repoIDs []int64) *xorm.Session {
sess := x.Where("issue.is_closed = ?", isClosed).And("issue.is_pull = ?", isPull)
sess := x.
Where("issue.is_closed = ?", isClosed).
And("issue.is_pull = ?", isPull)


if repoID > 0 || len(repoIDs) == 0 { if repoID > 0 || len(repoIDs) == 0 {
sess.And("repo_id = ?", repoID) sess.And("repo_id = ?", repoID)
// GetRepoIssueStats returns number of open and closed repository issues by given filter mode. // GetRepoIssueStats returns number of open and closed repository issues by given filter mode.
func GetRepoIssueStats(repoID, uid int64, filterMode int, isPull bool) (numOpen int64, numClosed int64) { func GetRepoIssueStats(repoID, uid int64, filterMode int, isPull bool) (numOpen int64, numClosed int64) {
countSession := func(isClosed, isPull bool, repoID int64) *xorm.Session { countSession := func(isClosed, isPull bool, repoID int64) *xorm.Session {
sess := x.Where("issue.repo_id = ?", isClosed).
sess := x.
Where("issue.repo_id = ?", isClosed).
And("is_pull = ?", isPull). And("is_pull = ?", isPull).
And("repo_id = ?", repoID) And("repo_id = ?", repoID)


} }


func countRepoMilestones(e Engine, repoID int64) int64 { func countRepoMilestones(e Engine, repoID int64) int64 {
count, _ := e.Where("repo_id=?", repoID).Count(new(Milestone))
count, _ := e.
Where("repo_id=?", repoID).
Count(new(Milestone))
return count return count
} }


} }


func countRepoClosedMilestones(e Engine, repoID int64) int64 { func countRepoClosedMilestones(e Engine, repoID int64) int64 {
closed, _ := e.Where("repo_id=? AND is_closed=?", repoID, true).Count(new(Milestone))
closed, _ := e.
Where("repo_id=? AND is_closed=?", repoID, true).
Count(new(Milestone))
return closed return closed
} }




// MilestoneStats returns number of open and closed milestones of given repository. // MilestoneStats returns number of open and closed milestones of given repository.
func MilestoneStats(repoID int64) (open int64, closed int64) { func MilestoneStats(repoID int64) (open int64, closed int64) {
open, _ = x.Where("repo_id=? AND is_closed=?", repoID, false).Count(new(Milestone))
open, _ = x.
Where("repo_id=? AND is_closed=?", repoID, false).
Count(new(Milestone))
return open, CountRepoClosedMilestones(repoID) return open, CountRepoClosedMilestones(repoID)
} }



+ 3
- 1
models/issue_comment.go Wyświetl plik



func getCommentsByIssueIDSince(e Engine, issueID, since int64) ([]*Comment, error) { func getCommentsByIssueIDSince(e Engine, issueID, since int64) ([]*Comment, error) {
comments := make([]*Comment, 0, 10) comments := make([]*Comment, 0, 10)
sess := e.Where("issue_id = ?", issueID).Asc("created_unix")
sess := e.
Where("issue_id = ?", issueID).
Asc("created_unix")
if since > 0 { if since > 0 {
sess.And("updated_unix >= ?", since) sess.And("updated_unix >= ?", since)
} }

+ 21
- 5
models/issue_label.go Wyświetl plik

// it silently ignores label IDs that are not belong to the repository. // it silently ignores label IDs that are not belong to the repository.
func GetLabelsInRepoByIDs(repoID int64, labelIDs []int64) ([]*Label, error) { func GetLabelsInRepoByIDs(repoID int64, labelIDs []int64) ([]*Label, error) {
labels := make([]*Label, 0, len(labelIDs)) labels := make([]*Label, 0, len(labelIDs))
return labels, x.Where("repo_id = ?", repoID).In("id", base.Int64sToStrings(labelIDs)).Asc("name").Find(&labels)
return labels, x.
Where("repo_id = ?", repoID).
In("id", base.Int64sToStrings(labelIDs)).
Asc("name").
Find(&labels)
} }


// GetLabelsByRepoID returns all labels that belong to given repository by ID. // GetLabelsByRepoID returns all labels that belong to given repository by ID.
func GetLabelsByRepoID(repoID int64) ([]*Label, error) { func GetLabelsByRepoID(repoID int64) ([]*Label, error) {
labels := make([]*Label, 0, 10) labels := make([]*Label, 0, 10)
return labels, x.Where("repo_id = ?", repoID).Asc("name").Find(&labels)
return labels, x.
Where("repo_id = ?", repoID).
Asc("name").
Find(&labels)
} }


func getLabelsByIssueID(e Engine, issueID int64) ([]*Label, error) { func getLabelsByIssueID(e Engine, issueID int64) ([]*Label, error) {
} }


labels := make([]*Label, 0, len(labelIDs)) labels := make([]*Label, 0, len(labelIDs))
return labels, e.Where("id > 0").In("id", base.Int64sToStrings(labelIDs)).Asc("name").Find(&labels)
return labels, e.
Where("id > 0").
In("id", base.Int64sToStrings(labelIDs)).
Asc("name").
Find(&labels)
} }


// GetLabelsByIssueID returns all labels that belong to given issue by ID. // GetLabelsByIssueID returns all labels that belong to given issue by ID.


if _, err = sess.Id(labelID).Delete(new(Label)); err != nil { if _, err = sess.Id(labelID).Delete(new(Label)); err != nil {
return err return err
} else if _, err = sess.Where("label_id = ?", labelID).Delete(new(IssueLabel)); err != nil {
} else if _, err = sess.
Where("label_id = ?", labelID).
Delete(new(IssueLabel)); err != nil {
return err return err
} }




func getIssueLabels(e Engine, issueID int64) ([]*IssueLabel, error) { func getIssueLabels(e Engine, issueID int64) ([]*IssueLabel, error) {
issueLabels := make([]*IssueLabel, 0, 10) issueLabels := make([]*IssueLabel, 0, 10)
return issueLabels, e.Where("issue_id=?", issueID).Asc("label_id").Find(&issueLabels)
return issueLabels, e.
Where("issue_id=?", issueID).
Asc("label_id").
Find(&issueLabels)
} }


// GetIssueLabels returns all issue-label relations of given issue by ID. // GetIssueLabels returns all issue-label relations of given issue by ID.

+ 1
- 1
models/login_source.go Wyświetl plik

var SecurityProtocolNames = map[ldap.SecurityProtocol]string{ var SecurityProtocolNames = map[ldap.SecurityProtocol]string{
ldap.SecurityProtocolUnencrypted: "Unencrypted", ldap.SecurityProtocolUnencrypted: "Unencrypted",
ldap.SecurityProtocolLDAPS: "LDAPS", ldap.SecurityProtocolLDAPS: "LDAPS",
ldap.SecurityProtocolStartTLS: "StartTLS",
ldap.SecurityProtocolStartTLS: "StartTLS",
} }


// Ensure structs implemented interface. // Ensure structs implemented interface.

+ 1
- 1
models/mail.go Wyświetl plik

) )


const ( const (
MailAuthActivate base.TplName = "auth/activate"
MailAuthActivate base.TplName = "auth/activate"
MailAuthActivateEmail base.TplName = "auth/activate_email" MailAuthActivateEmail base.TplName = "auth/activate_email"
MailAuthResetPassword base.TplName = "auth/reset_passwd" MailAuthResetPassword base.TplName = "auth/reset_passwd"
MailAuthRegisterNotify base.TplName = "auth/register_notify" MailAuthRegisterNotify base.TplName = "auth/register_notify"

+ 67
- 43
models/org.go Wyświetl plik

"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"


"github.com/go-gitea/gitea/modules/base" "github.com/go-gitea/gitea/modules/base"
"github.com/go-gitea/gitea/modules/log"
) )


var ( var (
} }


func (org *User) getTeams(e Engine) error { func (org *User) getTeams(e Engine) error {
return e.Where("org_id=?", org.ID).OrderBy("CASE WHEN name LIKE '" + OWNER_TEAM + "' THEN '' ELSE name END").Find(&org.Teams)
return e.
Where("org_id=?", org.ID).
OrderBy("CASE WHEN name LIKE '" + OWNER_TEAM + "' THEN '' ELSE name END").
Find(&org.Teams)
} }


// GetTeams returns all teams that belong to organization. // GetTeams returns all teams that belong to organization.


// CountOrganizations returns number of organizations. // CountOrganizations returns number of organizations.
func CountOrganizations() int64 { func CountOrganizations() int64 {
count, _ := x.Where("type=1").Count(new(User))
count, _ := x.
Where("type=1").
Count(new(User))
return count return count
} }


// Organizations returns number of organizations in given page. // Organizations returns number of organizations in given page.
func Organizations(page, pageSize int) ([]*User, error) { func Organizations(page, pageSize int) ([]*User, error) {
orgs := make([]*User, 0, pageSize) orgs := make([]*User, 0, pageSize)
return orgs, x.Limit(pageSize, (page-1)*pageSize).Where("type=1").Asc("name").Find(&orgs)
return orgs, x.
Limit(pageSize, (page-1)*pageSize).
Where("type=1").
Asc("name").
Find(&orgs)
} }


// DeleteOrganization completely and permanently deletes everything of organization. // DeleteOrganization completely and permanently deletes everything of organization.


// IsOrganizationOwner returns true if given user is in the owner team. // IsOrganizationOwner returns true if given user is in the owner team.
func IsOrganizationOwner(orgId, uid int64) bool { func IsOrganizationOwner(orgId, uid int64) bool {
has, _ := x.Where("is_owner=?", true).And("uid=?", uid).And("org_id=?", orgId).Get(new(OrgUser))
has, _ := x.
Where("is_owner=?", true).
And("uid=?", uid).
And("org_id=?", orgId).
Get(new(OrgUser))
return has return has
} }


// IsOrganizationMember returns true if given user is member of organization. // IsOrganizationMember returns true if given user is member of organization.
func IsOrganizationMember(orgId, uid int64) bool { func IsOrganizationMember(orgId, uid int64) bool {
has, _ := x.Where("uid=?", uid).And("org_id=?", orgId).Get(new(OrgUser))
has, _ := x.
Where("uid=?", uid).
And("org_id=?", orgId).
Get(new(OrgUser))
return has return has
} }


// IsPublicMembership returns true if given user public his/her membership. // IsPublicMembership returns true if given user public his/her membership.
func IsPublicMembership(orgId, uid int64) bool { func IsPublicMembership(orgId, uid int64) bool {
has, _ := x.Where("uid=?", uid).And("org_id=?", orgId).And("is_public=?", true).Get(new(OrgUser))
has, _ := x.
Where("uid=?", uid).
And("org_id=?", orgId).
And("is_public=?", true).
Get(new(OrgUser))
return has return has
} }


// GetOrgUsersByOrgID returns all organization-user relations by organization ID. // GetOrgUsersByOrgID returns all organization-user relations by organization ID.
func GetOrgUsersByOrgID(orgID int64) ([]*OrgUser, error) { func GetOrgUsersByOrgID(orgID int64) ([]*OrgUser, error) {
ous := make([]*OrgUser, 0, 10) ous := make([]*OrgUser, 0, 10)
err := x.Where("org_id=?", orgID).Find(&ous)
err := x.
Where("org_id=?", orgID).
Find(&ous)
return ous, err return ous, err
} }


// ChangeOrgUserStatus changes public or private membership status. // ChangeOrgUserStatus changes public or private membership status.
func ChangeOrgUserStatus(orgID, uid int64, public bool) error { func ChangeOrgUserStatus(orgID, uid int64, public bool) error {
ou := new(OrgUser) ou := new(OrgUser)
has, err := x.Where("uid=?", uid).And("org_id=?", orgID).Get(ou)
has, err := x.
Where("uid=?", uid).
And("org_id=?", orgID).
Get(ou)
if err != nil { if err != nil {
return err return err
} else if !has { } else if !has {
func RemoveOrgUser(orgID, userID int64) error { func RemoveOrgUser(orgID, userID int64) error {
ou := new(OrgUser) ou := new(OrgUser)


has, err := x.Where("uid=?", userID).And("org_id=?", orgID).Get(ou)
has, err := x.
Where("uid=?", userID).
And("org_id=?", orgID).
Get(ou)
if err != nil { if err != nil {
return fmt.Errorf("get org-user: %v", err) return fmt.Errorf("get org-user: %v", err)
} else if !has { } else if !has {
} }


if len(repoIDs) > 0 { if len(repoIDs) > 0 {
if _, err = sess.Where("user_id = ?", user.ID).In("repo_id", repoIDs).Delete(new(Access)); err != nil {
if _, err = sess.
Where("user_id = ?", user.ID).
In("repo_id", repoIDs).
Delete(new(Access)); err != nil {
return err return err
} }
} }
And("`team_user`.uid = ?", userID). And("`team_user`.uid = ?", userID).
Asc("`user`.name"). Asc("`user`.name").
Cols(cols...). Cols(cols...).
Find(&teams)
Find(&teams)
} }


// GetUserTeamIDs returns of all team IDs of the organization that user is memeber of. // GetUserTeamIDs returns of all team IDs of the organization that user is memeber of.
page = 1 page = 1
} }
repos := make([]*Repository, 0, pageSize) repos := make([]*Repository, 0, pageSize)
// FIXME: use XORM chain operations instead of raw SQL.
if err = x.SQL(fmt.Sprintf(`SELECT repository.* FROM repository
INNER JOIN team_repo
ON team_repo.repo_id = repository.id
WHERE (repository.owner_id = ? AND repository.is_private = ?) OR team_repo.team_id IN (%s)
GROUP BY repository.id
ORDER BY updated_unix DESC
LIMIT %d OFFSET %d`,
strings.Join(base.Int64sToStrings(teamIDs), ","), pageSize, (page-1)*pageSize),
org.ID, false).Find(&repos); err != nil {
if err := x.
Select("`repository`.*").
Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id").
Where("(`repository`.owner_id=? AND `repository`.is_private=?)", org.ID, false).
Or("team_repo.team_id IN (?)", strings.Join(base.Int64sToStrings(teamIDs), ",")).
GroupBy("`repository`.id").
OrderBy("updated_unix DESC").
Limit(pageSize, (page-1)*pageSize).
Find(&repos); err != nil {
return nil, 0, fmt.Errorf("get repositories: %v", err) return nil, 0, fmt.Errorf("get repositories: %v", err)
} }


results, err := x.Query(fmt.Sprintf(`SELECT repository.id FROM repository
INNER JOIN team_repo
ON team_repo.repo_id = repository.id
WHERE (repository.owner_id = ? AND repository.is_private = ?) OR team_repo.team_id IN (%s)
GROUP BY repository.id
ORDER BY updated_unix DESC`,
strings.Join(base.Int64sToStrings(teamIDs), ",")),
org.ID, false)
repoCount, err := x.
Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id").
Where("(`repository`.owner_id=? AND `repository`.is_private=?)", org.ID, false).
Or("team_repo.team_id IN (?)", strings.Join(base.Int64sToStrings(teamIDs), ",")).
GroupBy("`repository`.id").
Count(&Repository{})
if err != nil { if err != nil {
log.Error(4, "count user repositories in organization: %v", err)
return nil, 0, fmt.Errorf("count user repositories in organization: %v", err)
} }


return repos, int64(len(results)), nil
return repos, repoCount, nil
} }


// GetUserRepositories returns mirror repositories of the organization // GetUserRepositories returns mirror repositories of the organization
} }


repos := make([]*Repository, 0, 10) repos := make([]*Repository, 0, 10)
if err = x.SQL(fmt.Sprintf(`SELECT repository.* FROM repository
INNER JOIN team_repo
ON team_repo.repo_id = repository.id AND repository.is_mirror = ?
WHERE (repository.owner_id = ? AND repository.is_private = ?) OR team_repo.team_id IN (%s)
GROUP BY repository.id
ORDER BY updated_unix DESC`,
strings.Join(base.Int64sToStrings(teamIDs), ",")),
true, org.ID, false).Find(&repos); err != nil {
return nil, fmt.Errorf("get repositories: %v", err)
}
return repos, nil
return repos, x.
Select("`repository`.*").
Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id AND `repository`.is_mirror=?", true).
Where("(`repository`.owner_id=? AND `repository`.is_private=?)", org.ID, false).
Or("team_repo.team_id IN (?)", strings.Join(base.Int64sToStrings(teamIDs), ",")).
GroupBy("`repository`.id").
OrderBy("updated_unix DESC").
Find(&repos)
} }

+ 49
- 12
models/org_team.go Wyświetl plik



func (t *Team) getRepositories(e Engine) (err error) { func (t *Team) getRepositories(e Engine) (err error) {
teamRepos := make([]*TeamRepo, 0, t.NumRepos) teamRepos := make([]*TeamRepo, 0, t.NumRepos)
if err = x.Where("team_id=?", t.ID).Find(&teamRepos); err != nil {
if err = x.
Where("team_id=?", t.ID).
Find(&teamRepos); err != nil {
return fmt.Errorf("get team-repos: %v", err) return fmt.Errorf("get team-repos: %v", err)
} }


} }


t.LowerName = strings.ToLower(t.Name) t.LowerName = strings.ToLower(t.Name)
has, err = x.Where("org_id=?", t.OrgID).And("lower_name=?", t.LowerName).Get(new(Team))
has, err = x.
Where("org_id=?", t.OrgID).
And("lower_name=?", t.LowerName).
Get(new(Team))
if err != nil { if err != nil {
return err return err
} else if has { } else if has {
} }


t.LowerName = strings.ToLower(t.Name) t.LowerName = strings.ToLower(t.Name)
has, err := x.Where("org_id=?", t.OrgID).And("lower_name=?", t.LowerName).And("id!=?", t.ID).Get(new(Team))
has, err := x.
Where("org_id=?", t.OrgID).
And("lower_name=?", t.LowerName).
And("id!=?", t.ID).
Get(new(Team))
if err != nil { if err != nil {
return err return err
} else if has { } else if has {
} }


// Delete team-user. // Delete team-user.
if _, err = sess.Where("org_id=?", org.ID).Where("team_id=?", t.ID).Delete(new(TeamUser)); err != nil {
if _, err = sess.
Where("org_id=?", org.ID).
Where("team_id=?", t.ID).
Delete(new(TeamUser)); err != nil {
return err return err
} }


} }


func isTeamMember(e Engine, orgID, teamID, uid int64) bool { func isTeamMember(e Engine, orgID, teamID, uid int64) bool {
has, _ := e.Where("org_id=?", orgID).And("team_id=?", teamID).And("uid=?", uid).Get(new(TeamUser))
has, _ := e.
Where("org_id=?", orgID).
And("team_id=?", teamID).
And("uid=?", uid).
Get(new(TeamUser))
return has return has
} }




func getTeamMembers(e Engine, teamID int64) (_ []*User, err error) { func getTeamMembers(e Engine, teamID int64) (_ []*User, err error) {
teamUsers := make([]*TeamUser, 0, 10) teamUsers := make([]*TeamUser, 0, 10)
if err = e.Where("team_id=?", teamID).Find(&teamUsers); err != nil {
if err = e.
Where("team_id=?", teamID).
Find(&teamUsers); err != nil {
return nil, fmt.Errorf("get team-users: %v", err) return nil, fmt.Errorf("get team-users: %v", err)
} }
members := make([]*User, 0, len(teamUsers)) members := make([]*User, 0, len(teamUsers))


func getUserTeams(e Engine, orgId, uid int64) ([]*Team, error) { func getUserTeams(e Engine, orgId, uid int64) ([]*Team, error) {
tus := make([]*TeamUser, 0, 5) tus := make([]*TeamUser, 0, 5)
if err := e.Where("uid=?", uid).And("org_id=?", orgId).Find(&tus); err != nil {
if err := e.
Where("uid=?", uid).
And("org_id=?", orgId).
Find(&tus); err != nil {
return nil, err return nil, err
} }




// We make sure it exists before. // We make sure it exists before.
ou := new(OrgUser) ou := new(OrgUser)
if _, err = sess.Where("uid = ?", uid).And("org_id = ?", orgID).Get(ou); err != nil {
if _, err = sess.
Where("uid = ?", uid).
And("org_id = ?", orgID).
Get(ou); err != nil {
return err return err
} }
ou.NumTeams++ ou.NumTeams++
} }
if _, err := e.Delete(tu); err != nil { if _, err := e.Delete(tu); err != nil {
return err return err
} else if _, err = e.Id(t.ID).AllCols().Update(t); err != nil {
} else if _, err = e.
Id(t.ID).
AllCols().
Update(t); err != nil {
return err return err
} }




// This must exist. // This must exist.
ou := new(OrgUser) ou := new(OrgUser)
_, err = e.Where("uid = ?", uid).And("org_id = ?", org.ID).Get(ou)
_, err = e.
Where("uid = ?", uid).
And("org_id = ?", org.ID).
Get(ou)
if err != nil { if err != nil {
return err return err
} }
if t.IsOwnerTeam() { if t.IsOwnerTeam() {
ou.IsOwner = false ou.IsOwner = false
} }
if _, err = e.Id(ou.ID).AllCols().Update(ou); err != nil {
if _, err = e.
Id(ou.ID).
AllCols().
Update(ou); err != nil {
return err return err
} }
return nil return nil
} }


func hasTeamRepo(e Engine, orgID, teamID, repoID int64) bool { func hasTeamRepo(e Engine, orgID, teamID, repoID int64) bool {
has, _ := e.Where("org_id=?", orgID).And("team_id=?", teamID).And("repo_id=?", repoID).Get(new(TeamRepo))
has, _ := e.
Where("org_id=?", orgID).
And("team_id=?", teamID).
And("repo_id=?", repoID).
Get(new(TeamRepo))
return has return has
} }



+ 25
- 13
models/pull.go Wyświetl plik

"time" "time"


"github.com/Unknwon/com" "github.com/Unknwon/com"
"github.com/go-gitea/git"
"github.com/go-gitea/gitea/modules/log" "github.com/go-gitea/gitea/modules/log"
"github.com/go-gitea/gitea/modules/process" "github.com/go-gitea/gitea/modules/process"
"github.com/go-gitea/gitea/modules/setting" "github.com/go-gitea/gitea/modules/setting"
"github.com/go-gitea/gitea/modules/sync" "github.com/go-gitea/gitea/modules/sync"
"github.com/go-xorm/xorm"
"github.com/go-gitea/git"
api "github.com/go-gitea/go-sdk/gitea" api "github.com/go-gitea/go-sdk/gitea"
"github.com/go-xorm/xorm"
) )


var PullRequestQueue = sync.NewUniqueQueue(setting.Repository.PullRequestQueueLength) var PullRequestQueue = sync.NewUniqueQueue(setting.Repository.PullRequestQueueLength)
// by given head/base and repo/branch. // by given head/base and repo/branch.
func GetUnmergedPullRequest(headRepoID, baseRepoID int64, headBranch, baseBranch string) (*PullRequest, error) { func GetUnmergedPullRequest(headRepoID, baseRepoID int64, headBranch, baseBranch string) (*PullRequest, error) {
pr := new(PullRequest) pr := new(PullRequest)
has, err := x.Where("head_repo_id=? AND head_branch=? AND base_repo_id=? AND base_branch=? AND has_merged=? AND issue.is_closed=?",
headRepoID, headBranch, baseRepoID, baseBranch, false, false).
Join("INNER", "issue", "issue.id=pull_request.issue_id").Get(pr)
has, err := x.
Where("head_repo_id=? AND head_branch=? AND base_repo_id=? AND base_branch=? AND has_merged=? AND issue.is_closed=?",
headRepoID, headBranch, baseRepoID, baseBranch, false, false).
Join("INNER", "issue", "issue.id=pull_request.issue_id").
Get(pr)
if err != nil { if err != nil {
return nil, err return nil, err
} else if !has { } else if !has {
// by given head information (repo and branch). // by given head information (repo and branch).
func GetUnmergedPullRequestsByHeadInfo(repoID int64, branch string) ([]*PullRequest, error) { func GetUnmergedPullRequestsByHeadInfo(repoID int64, branch string) ([]*PullRequest, error) {
prs := make([]*PullRequest, 0, 2) prs := make([]*PullRequest, 0, 2)
return prs, x.Where("head_repo_id = ? AND head_branch = ? AND has_merged = ? AND issue.is_closed = ?",
repoID, branch, false, false).
Join("INNER", "issue", "issue.id = pull_request.issue_id").Find(&prs)
return prs, x.
Where("head_repo_id = ? AND head_branch = ? AND has_merged = ? AND issue.is_closed = ?",
repoID, branch, false, false).
Join("INNER", "issue", "issue.id = pull_request.issue_id").
Find(&prs)
} }


// GetUnmergedPullRequestsByBaseInfo returnss all pull requests that are open and has not been merged // GetUnmergedPullRequestsByBaseInfo returnss all pull requests that are open and has not been merged
// by given base information (repo and branch). // by given base information (repo and branch).
func GetUnmergedPullRequestsByBaseInfo(repoID int64, branch string) ([]*PullRequest, error) { func GetUnmergedPullRequestsByBaseInfo(repoID int64, branch string) ([]*PullRequest, error) {
prs := make([]*PullRequest, 0, 2) prs := make([]*PullRequest, 0, 2)
return prs, x.Where("base_repo_id=? AND base_branch=? AND has_merged=? AND issue.is_closed=?",
repoID, branch, false, false).
Join("INNER", "issue", "issue.id=pull_request.issue_id").Find(&prs)
return prs, x.
Where("base_repo_id=? AND base_branch=? AND has_merged=? AND issue.is_closed=?",
repoID, branch, false, false).
Join("INNER", "issue", "issue.id=pull_request.issue_id").
Find(&prs)
} }


func getPullRequestByID(e Engine, id int64) (*PullRequest, error) { func getPullRequestByID(e Engine, id int64) (*PullRequest, error) {
issueIDs = append(issueIDs, prs[i].IssueID) issueIDs = append(issueIDs, prs[i].IssueID)
} }
issues := make([]*Issue, 0, len(issueIDs)) issues := make([]*Issue, 0, len(issueIDs))
if err := e.Where("id > 0").In("id", issueIDs).Find(&issues); err != nil {
if err := e.
Where("id > 0").
In("id", issueIDs).
Find(&issues); err != nil {
return fmt.Errorf("find issues: %v", err) return fmt.Errorf("find issues: %v", err)
} }


pr := PullRequest{ pr := PullRequest{
HeadUserName: strings.ToLower(newUserName), HeadUserName: strings.ToLower(newUserName),
} }
_, err := x.Cols("head_user_name").Where("head_user_name = ?", strings.ToLower(oldUserName)).Update(pr)
_, err := x.
Cols("head_user_name").
Where("head_user_name = ?", strings.ToLower(oldUserName)).
Update(pr)
return err return err
} }



+ 7
- 2
models/release.go Wyświetl plik

// GetReleaseByID returns release with given ID. // GetReleaseByID returns release with given ID.
func GetReleaseByID(id int64) (*Release, error) { func GetReleaseByID(id int64) (*Release, error) {
rel := new(Release) rel := new(Release)
has, err := x.Id(id).Get(rel)
has, err := x.
Id(id).
Get(rel)
if err != nil { if err != nil {
return nil, err return nil, err
} else if !has { } else if !has {
if page <= 0 { if page <= 0 {
page = 1 page = 1
} }
err = x.Desc("created_unix").Limit(pageSize, (page-1)*pageSize).Find(&rels, Release{RepoID: repoID})
err = x.
Desc("created_unix").
Limit(pageSize, (page-1)*pageSize).
Find(&rels, Release{RepoID: repoID})
return rels, err return rels, err
} }



+ 99
- 60
models/repo.go Wyświetl plik



"github.com/Unknwon/cae/zip" "github.com/Unknwon/cae/zip"
"github.com/Unknwon/com" "github.com/Unknwon/com"
"github.com/go-gitea/git"
"github.com/go-gitea/gitea/modules/bindata" "github.com/go-gitea/gitea/modules/bindata"
"github.com/go-gitea/gitea/modules/log" "github.com/go-gitea/gitea/modules/log"
"github.com/go-gitea/gitea/modules/markdown" "github.com/go-gitea/gitea/modules/markdown"
"github.com/go-gitea/gitea/modules/process" "github.com/go-gitea/gitea/modules/process"
"github.com/go-gitea/gitea/modules/setting" "github.com/go-gitea/gitea/modules/setting"
"github.com/go-gitea/gitea/modules/sync" "github.com/go-gitea/gitea/modules/sync"
"github.com/go-xorm/xorm"
"github.com/go-gitea/git"
api "github.com/go-gitea/go-sdk/gitea" api "github.com/go-gitea/go-sdk/gitea"
"github.com/go-xorm/xorm"
version "github.com/mcuadros/go-version" version "github.com/mcuadros/go-version"
ini "gopkg.in/ini.v1" ini "gopkg.in/ini.v1"
) )
} }


accesses := make([]*Access, 0, 10) accesses := make([]*Access, 0, 10)
if err = e.Where("repo_id = ? AND mode >= ?", repo.ID, AccessModeWrite).Find(&accesses); err != nil {
if err = e.
Where("repo_id = ? AND mode >= ?", repo.ID, AccessModeWrite).
Find(&accesses); err != nil {
return nil, err return nil, err
} }




func getRepositoriesByForkID(e Engine, forkID int64) ([]*Repository, error) { func getRepositoriesByForkID(e Engine, forkID int64) ([]*Repository, error) {
repos := make([]*Repository, 0, 10) repos := make([]*Repository, 0, 10)
return repos, e.Where("fork_id=?", forkID).Find(&repos)
return repos, e.
Where("fork_id=?", forkID).
Find(&repos)
} }


// GetRepositoriesByForkID returns all repositories with given fork ID. // GetRepositoriesByForkID returns all repositories with given fork ID.
// Delete comments and attachments. // Delete comments and attachments.
issues := make([]*Issue, 0, 25) issues := make([]*Issue, 0, 25)
attachmentPaths := make([]string, 0, len(issues)) attachmentPaths := make([]string, 0, len(issues))
if err = sess.Where("repo_id=?", repoID).Find(&issues); err != nil {
if err = sess.
Where("repo_id=?", repoID).
Find(&issues); err != nil {
return err return err
} }
for i := range issues { for i := range issues {
} }


attachments := make([]*Attachment, 0, 5) attachments := make([]*Attachment, 0, 5)
if err = sess.Where("issue_id=?", issues[i].ID).Find(&attachments); err != nil {
if err = sess.
Where("issue_id=?", issues[i].ID).
Find(&attachments); err != nil {
return err return err
} }
for j := range attachments { for j := range attachments {


// GetUserRepositories returns a list of repositories of given user. // GetUserRepositories returns a list of repositories of given user.
func GetUserRepositories(userID int64, private bool, page, pageSize int) ([]*Repository, error) { func GetUserRepositories(userID int64, private bool, page, pageSize int) ([]*Repository, error) {
sess := x.Where("owner_id = ?", userID).Desc("updated_unix")
sess := x.
Where("owner_id = ?", userID).
Desc("updated_unix")
if !private { if !private {
sess.And("is_private=?", false) sess.And("is_private=?", false)
} }
// GetUserRepositories returns a list of mirror repositories of given user. // GetUserRepositories returns a list of mirror repositories of given user.
func GetUserMirrorRepositories(userID int64) ([]*Repository, error) { func GetUserMirrorRepositories(userID int64) ([]*Repository, error) {
repos := make([]*Repository, 0, 10) repos := make([]*Repository, 0, 10)
return repos, x.Where("owner_id = ?", userID).And("is_mirror = ?", true).Find(&repos)
return repos, x.
Where("owner_id = ?", userID).
And("is_mirror = ?", true).
Find(&repos)
} }


// GetRecentUpdatedRepositories returns the list of repositories that are recently updated. // GetRecentUpdatedRepositories returns the list of repositories that are recently updated.
func GetRecentUpdatedRepositories(page, pageSize int) (repos []*Repository, err error) { func GetRecentUpdatedRepositories(page, pageSize int) (repos []*Repository, err error) {
return repos, x.Limit(pageSize, (page-1)*pageSize).
Where("is_private=?", false).Limit(pageSize).Desc("updated_unix").Find(&repos)
return repos, x.
Limit(pageSize, (page-1)*pageSize).
Where("is_private=?", false).
Limit(pageSize).
Desc("updated_unix").
Find(&repos)
} }


func getRepositoryCount(e Engine, u *User) (int64, error) { func getRepositoryCount(e Engine, u *User) (int64, error) {


// DeleteRepositoryArchives deletes all repositories' archives. // DeleteRepositoryArchives deletes all repositories' archives.
func DeleteRepositoryArchives() error { func DeleteRepositoryArchives() error {
return x.Where("id > 0").Iterate(new(Repository),
func(idx int, bean interface{}) error {
repo := bean.(*Repository)
return os.RemoveAll(filepath.Join(repo.RepoPath(), "archives"))
})
return x.
Where("id > 0").
Iterate(new(Repository),
func(idx int, bean interface{}) error {
repo := bean.(*Repository)
return os.RemoveAll(filepath.Join(repo.RepoPath(), "archives"))
})
} }


func gatherMissingRepoRecords() ([]*Repository, error) { func gatherMissingRepoRecords() ([]*Repository, error) {
repos := make([]*Repository, 0, 10) repos := make([]*Repository, 0, 10)
if err := x.Where("id > 0").Iterate(new(Repository),
func(idx int, bean interface{}) error {
repo := bean.(*Repository)
if !com.IsDir(repo.RepoPath()) {
repos = append(repos, repo)
}
return nil
}); err != nil {
if err := x.
Where("id > 0").
Iterate(new(Repository),
func(idx int, bean interface{}) error {
repo := bean.(*Repository)
if !com.IsDir(repo.RepoPath()) {
repos = append(repos, repo)
}
return nil
}); err != nil {
if err2 := CreateRepositoryNotice(fmt.Sprintf("gatherMissingRepoRecords: %v", err)); err2 != nil { if err2 := CreateRepositoryNotice(fmt.Sprintf("gatherMissingRepoRecords: %v", err)); err2 != nil {
return nil, fmt.Errorf("CreateRepositoryNotice: %v", err) return nil, fmt.Errorf("CreateRepositoryNotice: %v", err)
} }


// RewriteRepositoryUpdateHook rewrites all repositories' update hook. // RewriteRepositoryUpdateHook rewrites all repositories' update hook.
func RewriteRepositoryUpdateHook() error { func RewriteRepositoryUpdateHook() error {
return x.Where("id > 0").Iterate(new(Repository),
func(idx int, bean interface{}) error {
repo := bean.(*Repository)
return createUpdateHook(repo.RepoPath())
})
return x.
Where("id > 0").
Iterate(new(Repository),
func(idx int, bean interface{}) error {
repo := bean.(*Repository)
return createUpdateHook(repo.RepoPath())
})
} }


// Prevent duplicate running tasks. // Prevent duplicate running tasks.


log.Trace("Doing: GitFsck") log.Trace("Doing: GitFsck")


if err := x.Where("id>0").Iterate(new(Repository),
func(idx int, bean interface{}) error {
repo := bean.(*Repository)
repoPath := repo.RepoPath()
if err := git.Fsck(repoPath, setting.Cron.RepoHealthCheck.Timeout, setting.Cron.RepoHealthCheck.Args...); err != nil {
desc := fmt.Sprintf("Fail to health check repository (%s): %v", repoPath, err)
log.Warn(desc)
if err = CreateRepositoryNotice(desc); err != nil {
log.Error(4, "CreateRepositoryNotice: %v", err)
if err := x.
Where("id>0").
Iterate(new(Repository),
func(idx int, bean interface{}) error {
repo := bean.(*Repository)
repoPath := repo.RepoPath()
if err := git.Fsck(repoPath, setting.Cron.RepoHealthCheck.Timeout, setting.Cron.RepoHealthCheck.Args...); err != nil {
desc := fmt.Sprintf("Fail to health check repository (%s): %v", repoPath, err)
log.Warn(desc)
if err = CreateRepositoryNotice(desc); err != nil {
log.Error(4, "CreateRepositoryNotice: %v", err)
}
} }
}
return nil
}); err != nil {
return nil
}); err != nil {
log.Error(4, "GitFsck: %v", err) log.Error(4, "GitFsck: %v", err)
} }
} }


func GitGcRepos() error { func GitGcRepos() error {
args := append([]string{"gc"}, setting.Git.GCArgs...) args := append([]string{"gc"}, setting.Git.GCArgs...)
return x.Where("id > 0").Iterate(new(Repository),
func(idx int, bean interface{}) error {
repo := bean.(*Repository)
if err := repo.GetOwner(); err != nil {
return err
}
_, stderr, err := process.ExecDir(
time.Duration(setting.Git.Timeout.GC)*time.Second,
RepoPath(repo.Owner.Name, repo.Name), "Repository garbage collection",
"git", args...)
if err != nil {
return fmt.Errorf("%v: %v", err, stderr)
}
return nil
})
return x.
Where("id > 0").
Iterate(new(Repository),
func(idx int, bean interface{}) error {
repo := bean.(*Repository)
if err := repo.GetOwner(); err != nil {
return err
}
_, stderr, err := process.ExecDir(
time.Duration(setting.Git.Timeout.GC)*time.Second,
RepoPath(repo.Owner.Name, repo.Name), "Repository garbage collection",
"git", args...)
if err != nil {
return fmt.Errorf("%v: %v", err, stderr)
}
return nil
})
} }


type repoChecker struct { type repoChecker struct {
userIDs = append(userIDs, userID) userIDs = append(userIDs, userID)
} }
users := make([]*User, 0, len(userIDs)) users := make([]*User, 0, len(userIDs))
if err := e.Where("id > 0").In("id", userIDs).Find(&users); err != nil {
if err := e.
Where("id > 0").
In("id", userIDs).
Find(&users); err != nil {
return fmt.Errorf("find users: %v", err) return fmt.Errorf("find users: %v", err)
} }
for i := range users { for i := range users {
repoIDs = append(repoIDs, repos[i].ID) repoIDs = append(repoIDs, repos[i].ID)
} }
mirrors := make([]*Mirror, 0, len(repoIDs)) mirrors := make([]*Mirror, 0, len(repoIDs))
if err := e.Where("id > 0").In("repo_id", repoIDs).Find(&mirrors); err != nil {
if err := e.
Where("id > 0").
In("repo_id", repoIDs).
Find(&mirrors); err != nil {
return fmt.Errorf("find mirrors: %v", err) return fmt.Errorf("find mirrors: %v", err)
} }


// Repository.GetWatchers returns range of users watching given repository. // Repository.GetWatchers returns range of users watching given repository.
func (repo *Repository) GetWatchers(page int) ([]*User, error) { func (repo *Repository) GetWatchers(page int) ([]*User, error) {
users := make([]*User, 0, ItemsPerPage) users := make([]*User, 0, ItemsPerPage)
sess := x.Limit(ItemsPerPage, (page-1)*ItemsPerPage).Where("watch.repo_id=?", repo.ID)
sess := x.
Limit(ItemsPerPage, (page-1)*ItemsPerPage).
Where("watch.repo_id=?", repo.ID)
if setting.UsePostgreSQL { if setting.UsePostgreSQL {
sess = sess.Join("LEFT", "watch", `"user".id=watch.user_id`) sess = sess.Join("LEFT", "watch", `"user".id=watch.user_id`)
} else { } else {


func (repo *Repository) GetStargazers(page int) ([]*User, error) { func (repo *Repository) GetStargazers(page int) ([]*User, error) {
users := make([]*User, 0, ItemsPerPage) users := make([]*User, 0, ItemsPerPage)
sess := x.Limit(ItemsPerPage, (page-1)*ItemsPerPage).Where("star.repo_id=?", repo.ID)
sess := x.
Limit(ItemsPerPage, (page-1)*ItemsPerPage).
Where("star.repo_id=?", repo.ID)
if setting.UsePostgreSQL { if setting.UsePostgreSQL {
sess = sess.Join("LEFT", "star", `"user".id=star.uid`) sess = sess.Join("LEFT", "star", `"user".id=star.uid`)
} else { } else {
// HasForkedRepo checks if given user has already forked a repository with given ID. // HasForkedRepo checks if given user has already forked a repository with given ID.
func HasForkedRepo(ownerID, repoID int64) (*Repository, bool) { func HasForkedRepo(ownerID, repoID int64) (*Repository, bool) {
repo := new(Repository) repo := new(Repository)
has, _ := x.Where("owner_id=? AND fork_id=?", ownerID, repoID).Get(repo)
has, _ := x.
Where("owner_id=? AND fork_id=?", ownerID, repoID).
Get(repo)
return repo, has return repo, has
} }



+ 4
- 1
models/repo_collaboration.go Wyświetl plik

return err return err
} }


if _, err = sess.Id(collaboration.ID).AllCols().Update(collaboration); err != nil {
if _, err = sess.
Id(collaboration.ID).
AllCols().
Update(collaboration); err != nil {
return fmt.Errorf("update collaboration: %v", err) return fmt.Errorf("update collaboration: %v", err)
} else if _, err = sess.Exec("UPDATE access SET mode = ? WHERE user_id = ? AND repo_id = ?", mode, uid, repo.ID); err != nil { } else if _, err = sess.Exec("UPDATE access SET mode = ? WHERE user_id = ? AND repo_id = ?", mode, uid, repo.ID); err != nil {
return fmt.Errorf("update access table: %v", err) return fmt.Errorf("update access table: %v", err)

+ 3
- 1
models/repo_editor.go Wyświetl plik

for i := 0; i < len(uploads); i++ { for i := 0; i < len(uploads); i++ {
ids[i] = uploads[i].ID ids[i] = uploads[i].ID
} }
if _, err = sess.In("id", ids).Delete(new(Upload)); err != nil {
if _, err = sess.
In("id", ids).
Delete(new(Upload)); err != nil {
return fmt.Errorf("delete uploads: %v", err) return fmt.Errorf("delete uploads: %v", err)
} }



+ 11
- 9
models/repo_mirror.go Wyświetl plik



log.Trace("Doing: MirrorUpdate") log.Trace("Doing: MirrorUpdate")


if err := x.Where("next_update_unix<=?", time.Now().Unix()).Iterate(new(Mirror), func(idx int, bean interface{}) error {
m := bean.(*Mirror)
if m.Repo == nil {
log.Error(4, "Disconnected mirror repository found: %d", m.ID)
return nil
}
if err := x.
Where("next_update_unix<=?", time.Now().Unix()).
Iterate(new(Mirror), func(idx int, bean interface{}) error {
m := bean.(*Mirror)
if m.Repo == nil {
log.Error(4, "Disconnected mirror repository found: %d", m.ID)
return nil
}


MirrorQueue.Add(m.RepoID)
return nil
}); err != nil {
MirrorQueue.Add(m.RepoID)
return nil
}); err != nil {
log.Error(4, "MirrorUpdate: %v", err) log.Error(4, "MirrorUpdate: %v", err)
} }
} }

+ 27
- 9
models/ssh_key.go Wyświetl plik

} }


// Key name of same user cannot be duplicated. // Key name of same user cannot be duplicated.
has, err := x.Where("owner_id = ? AND name = ?", ownerID, name).Get(new(PublicKey))
has, err := x.
Where("owner_id = ? AND name = ?", ownerID, name).
Get(new(PublicKey))
if err != nil { if err != nil {
return nil, err return nil, err
} else if has { } else if has {
// GetPublicKeyByID returns public key by given ID. // GetPublicKeyByID returns public key by given ID.
func GetPublicKeyByID(keyID int64) (*PublicKey, error) { func GetPublicKeyByID(keyID int64) (*PublicKey, error) {
key := new(PublicKey) key := new(PublicKey)
has, err := x.Id(keyID).Get(key)
has, err := x.
Id(keyID).
Get(key)
if err != nil { if err != nil {
return nil, err return nil, err
} else if !has { } else if !has {
// and returns public key found. // and returns public key found.
func SearchPublicKeyByContent(content string) (*PublicKey, error) { func SearchPublicKeyByContent(content string) (*PublicKey, error) {
key := new(PublicKey) key := new(PublicKey)
has, err := x.Where("content like ?", content+"%").Get(key)
has, err := x.
Where("content like ?", content+"%").
Get(key)
if err != nil { if err != nil {
return nil, err return nil, err
} else if !has { } else if !has {
// ListPublicKeys returns a list of public keys belongs to given user. // ListPublicKeys returns a list of public keys belongs to given user.
func ListPublicKeys(uid int64) ([]*PublicKey, error) { func ListPublicKeys(uid int64) ([]*PublicKey, error) {
keys := make([]*PublicKey, 0, 5) keys := make([]*PublicKey, 0, 5)
return keys, x.Where("owner_id = ?", uid).Find(&keys)
return keys, x.
Where("owner_id = ?", uid).
Find(&keys)
} }


// UpdatePublicKey updates given public key. // UpdatePublicKey updates given public key.


func checkDeployKey(e Engine, keyID, repoID int64, name string) error { func checkDeployKey(e Engine, keyID, repoID int64, name string) error {
// Note: We want error detail, not just true or false here. // Note: We want error detail, not just true or false here.
has, err := e.Where("key_id = ? AND repo_id = ?", keyID, repoID).Get(new(DeployKey))
has, err := e.
Where("key_id = ? AND repo_id = ?", keyID, repoID).
Get(new(DeployKey))
if err != nil { if err != nil {
return err return err
} else if has { } else if has {
return ErrDeployKeyAlreadyExist{keyID, repoID} return ErrDeployKeyAlreadyExist{keyID, repoID}
} }


has, err = e.Where("repo_id = ? AND name = ?", repoID, name).Get(new(DeployKey))
has, err = e.
Where("repo_id = ? AND name = ?", repoID, name).
Get(new(DeployKey))
if err != nil { if err != nil {
return err return err
} else if has { } else if has {


// HasDeployKey returns true if public key is a deploy key of given repository. // HasDeployKey returns true if public key is a deploy key of given repository.
func HasDeployKey(keyID, repoID int64) bool { func HasDeployKey(keyID, repoID int64) bool {
has, _ := x.Where("key_id = ? AND repo_id = ?", keyID, repoID).Get(new(DeployKey))
has, _ := x.
Where("key_id = ? AND repo_id = ?", keyID, repoID).
Get(new(DeployKey))
return has return has
} }


} }


// Check if this is the last reference to same key content. // Check if this is the last reference to same key content.
has, err := sess.Where("key_id = ?", key.KeyID).Get(new(DeployKey))
has, err := sess.
Where("key_id = ?", key.KeyID).
Get(new(DeployKey))
if err != nil { if err != nil {
return err return err
} else if !has { } else if !has {
// ListDeployKeys returns all deploy keys by given repository ID. // ListDeployKeys returns all deploy keys by given repository ID.
func ListDeployKeys(repoID int64) ([]*DeployKey, error) { func ListDeployKeys(repoID int64) ([]*DeployKey, error) {
keys := make([]*DeployKey, 0, 5) keys := make([]*DeployKey, 0, 5)
return keys, x.Where("repo_id = ?", repoID).Find(&keys)
return keys, x.
Where("repo_id = ?", repoID).
Find(&keys)
} }

+ 4
- 1
models/token.go Wyświetl plik

// ListAccessTokens returns a list of access tokens belongs to given user. // ListAccessTokens returns a list of access tokens belongs to given user.
func ListAccessTokens(uid int64) ([]*AccessToken, error) { func ListAccessTokens(uid int64) ([]*AccessToken, error) {
tokens := make([]*AccessToken, 0, 5) tokens := make([]*AccessToken, 0, 5)
return tokens, x.Where("uid=?", uid).Desc("id").Find(&tokens)
return tokens, x.
Where("uid=?", uid).
Desc("id").
Find(&tokens)
} }


// UpdateAccessToken updates information of access token. // UpdateAccessToken updates information of access token.

+ 55
- 28
models/user.go Wyświetl plik

Rands string `xorm:"VARCHAR(10)"` Rands string `xorm:"VARCHAR(10)"`
Salt string `xorm:"VARCHAR(10)"` Salt string `xorm:"VARCHAR(10)"`


Created time.Time `xorm:"-"`
CreatedUnix int64
Updated time.Time `xorm:"-"`
UpdatedUnix int64
Created time.Time `xorm:"-"`
CreatedUnix int64
Updated time.Time `xorm:"-"`
UpdatedUnix int64
LastLogin time.Time `xorm:"-"` LastLogin time.Time `xorm:"-"`
LastLoginUnix int64 LastLoginUnix int64


// User.GetFollwoers returns range of user's followers. // User.GetFollwoers returns range of user's followers.
func (u *User) GetFollowers(page int) ([]*User, error) { func (u *User) GetFollowers(page int) ([]*User, error) {
users := make([]*User, 0, ItemsPerPage) users := make([]*User, 0, ItemsPerPage)
sess := x.Limit(ItemsPerPage, (page-1)*ItemsPerPage).Where("follow.follow_id=?", u.ID)
sess := x.
Limit(ItemsPerPage, (page-1)*ItemsPerPage).
Where("follow.follow_id=?", u.ID)
if setting.UsePostgreSQL { if setting.UsePostgreSQL {
sess = sess.Join("LEFT", "follow", `"user".id=follow.user_id`) sess = sess.Join("LEFT", "follow", `"user".id=follow.user_id`)
} else { } else {
// GetFollowing returns range of user's following. // GetFollowing returns range of user's following.
func (u *User) GetFollowing(page int) ([]*User, error) { func (u *User) GetFollowing(page int) ([]*User, error) {
users := make([]*User, 0, ItemsPerPage) users := make([]*User, 0, ItemsPerPage)
sess := x.Limit(ItemsPerPage, (page-1)*ItemsPerPage).Where("follow.user_id=?", u.ID)
sess := x.
Limit(ItemsPerPage, (page-1)*ItemsPerPage).
Where("follow.user_id=?", u.ID)
if setting.UsePostgreSQL { if setting.UsePostgreSQL {
sess = sess.Join("LEFT", "follow", `"user".id=follow.follow_id`) sess = sess.Join("LEFT", "follow", `"user".id=follow.follow_id`)
} else { } else {
} }


func (u *User) getOrganizationCount(e Engine) (int64, error) { func (u *User) getOrganizationCount(e Engine) (int64, error) {
return e.Where("uid=?", u.ID).Count(new(OrgUser))
return e.
Where("uid=?", u.ID).
Count(new(OrgUser))
} }


// GetOrganizationCount returns count of membership of organization of user. // GetOrganizationCount returns count of membership of organization of user.
if len(name) == 0 { if len(name) == 0 {
return false, nil return false, nil
} }
return x.Where("id!=?", uid).Get(&User{LowerName: strings.ToLower(name)})
return x.
Where("id!=?", uid).
Get(&User{LowerName: strings.ToLower(name)})
} }


// GetUserSalt returns a ramdom user salt token. // GetUserSalt returns a ramdom user salt token.
} }


func countUsers(e Engine) int64 { func countUsers(e Engine) int64 {
count, _ := e.Where("type=0").Count(new(User))
count, _ := e.
Where("type=0").
Count(new(User))
return count return count
} }


// Users returns number of users in given page. // Users returns number of users in given page.
func Users(page, pageSize int) ([]*User, error) { func Users(page, pageSize int) ([]*User, error) {
users := make([]*User, 0, pageSize) users := make([]*User, 0, pageSize)
return users, x.Limit(pageSize, (page-1)*pageSize).Where("type=0").Asc("name").Find(&users)
return users, x.
Limit(pageSize, (page-1)*pageSize).
Where("type=0").
Asc("name").
Find(&users)
} }


// get user by erify code // get user by erify code
} }


// Delete all local copies of repository wiki that user owns. // Delete all local copies of repository wiki that user owns.
if err = x.Where("owner_id=?", u.ID).Iterate(new(Repository), func(idx int, bean interface{}) error {
repo := bean.(*Repository)
RemoveAllWithNotice("Delete repository wiki local copy", repo.LocalWikiPath())
return nil
}); err != nil {
if err = x.
Where("owner_id=?", u.ID).
Iterate(new(Repository), func(idx int, bean interface{}) error {
repo := bean.(*Repository)
RemoveAllWithNotice("Delete repository wiki local copy", repo.LocalWikiPath())
return nil
}); err != nil {
return fmt.Errorf("Delete repository wiki local copy: %v", err) return fmt.Errorf("Delete repository wiki local copy: %v", err)
} }


// Organization does not need email // Organization does not need email
if !u.IsOrganization() { if !u.IsOrganization() {
u.Email = strings.ToLower(u.Email) u.Email = strings.ToLower(u.Email)
has, err := e.Where("id!=?", u.ID).And("type=?", u.Type).And("email=?", u.Email).Get(new(User))
has, err := e.
Where("id!=?", u.ID).
And("type=?", u.Type).
And("email=?", u.Email).
Get(new(User))
if err != nil { if err != nil {
return err return err
} else if has { } else if has {
// DeleteInactivateUsers deletes all inactivate users and email addresses. // DeleteInactivateUsers deletes all inactivate users and email addresses.
func DeleteInactivateUsers() (err error) { func DeleteInactivateUsers() (err error) {
users := make([]*User, 0, 10) users := make([]*User, 0, 10)
if err = x.Where("is_active = ?", false).Find(&users); err != nil {
if err = x.
Where("is_active = ?", false).
Find(&users); err != nil {
return fmt.Errorf("get all inactive users: %v", err) return fmt.Errorf("get all inactive users: %v", err)
} }
// FIXME: should only update authorized_keys file once after all deletions. // FIXME: should only update authorized_keys file once after all deletions.
} }
} }


_, err = x.Where("is_activated = ?", false).Delete(new(EmailAddress))
_, err = x.
Where("is_activated = ?", false).
Delete(new(EmailAddress))
return err return err
} }




func GetUserByKeyID(keyID int64) (*User, error) { func GetUserByKeyID(keyID int64) (*User, error) {
user := new(User) user := new(User)
has, err := x.SQL("SELECT a.* FROM `user` AS a, public_key AS b WHERE a.id = b.owner_id AND b.id=?", keyID).Get(user)
if err != nil {
return nil, err
} else if !has {
return nil, ErrUserNotKeyOwner
}
return user, nil
return user, x.
Join("INNER", "public_key", "`public_key`.owner_id = `user`.id").
Where("`public_key`.id=?", keyID).
Find(user)
} }


func getUserByID(e Engine, id int64) (*User, error) { func getUserByID(e Engine, id int64) (*User, error) {
// GetUsersByIDs returns all resolved users from a list of Ids. // GetUsersByIDs returns all resolved users from a list of Ids.
func GetUsersByIDs(ids []int64) ([]*User, error) { func GetUsersByIDs(ids []int64) ([]*User, error) {
ous := make([]*User, 0, len(ids)) ous := make([]*User, 0, len(ids))
err := x.In("id", ids).Asc("name").Find(&ous)
err := x.
In("id", ids).
Asc("name").
Find(&ous)
return ous, err return ous, err
} }


searchQuery := "%" + opts.Keyword + "%" searchQuery := "%" + opts.Keyword + "%"
users = make([]*User, 0, opts.PageSize) users = make([]*User, 0, opts.PageSize)
// Append conditions // Append conditions
sess := x.Where("LOWER(lower_name) LIKE ?", searchQuery).
sess := x.
Where("LOWER(lower_name) LIKE ?", searchQuery).
Or("LOWER(full_name) LIKE ?", searchQuery). Or("LOWER(full_name) LIKE ?", searchQuery).
And("type = ?", opts.Type) And("type = ?", opts.Type)


if len(opts.OrderBy) > 0 { if len(opts.OrderBy) > 0 {
sess.OrderBy(opts.OrderBy) sess.OrderBy(opts.OrderBy)
} }
return users, count, sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Find(&users)
return users, count, sess.
Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).
Find(&users)
} }


// ___________ .__ .__ // ___________ .__ .__

+ 10
- 3
models/user_mail.go Wyświetl plik

// GetEmailAddresses returns all email addresses belongs to given user. // GetEmailAddresses returns all email addresses belongs to given user.
func GetEmailAddresses(uid int64) ([]*EmailAddress, error) { func GetEmailAddresses(uid int64) ([]*EmailAddress, error) {
emails := make([]*EmailAddress, 0, 5) emails := make([]*EmailAddress, 0, 5)
if err := x.Where("uid=?", uid).Find(&emails); err != nil {
if err := x.
Where("uid=?", uid).
Find(&emails); err != nil {
return nil, err return nil, err
} }


} }


email.IsActivated = true email.IsActivated = true
if _, err := sess.Id(email.ID).AllCols().Update(email); err != nil {
if _, err := sess.
Id(email.ID).
AllCols().
Update(email); err != nil {
return err return err
} else if err = updateUser(sess, user); err != nil { } else if err = updateUser(sess, user); err != nil {
return err return err
if email.ID > 0 { if email.ID > 0 {
_, err = x.Id(email.ID).Delete(new(EmailAddress)) _, err = x.Id(email.ID).Delete(new(EmailAddress))
} else { } else {
_, err = x.Where("email=?", email.Email).Delete(new(EmailAddress))
_, err = x.
Where("email=?", email.Email).
Delete(new(EmailAddress))
} }
return err return err
} }

+ 20
- 11
models/webhook.go Wyświetl plik



// GetActiveWebhooksByOrgID returns all active webhooks for an organization. // GetActiveWebhooksByOrgID returns all active webhooks for an organization.
func GetActiveWebhooksByOrgID(orgID int64) (ws []*Webhook, err error) { func GetActiveWebhooksByOrgID(orgID int64) (ws []*Webhook, err error) {
err = x.Where("org_id=?", orgID).And("is_active=?", true).Find(&ws)
err = x.
Where("org_id=?", orgID).
And("is_active=?", true).
Find(&ws)
return ws, err return ws, err
} }


type HookEventType string type HookEventType string


const ( const (
HookEventCreate HookEventType = "create"
HookEventPush HookEventType = "push"
HookEventCreate HookEventType = "create"
HookEventPush HookEventType = "push"
HookEventPullRequest HookEventType = "pull_request" HookEventPullRequest HookEventType = "pull_request"
) )


// HookTasks returns a list of hook tasks by given conditions. // HookTasks returns a list of hook tasks by given conditions.
func HookTasks(hookID int64, page int) ([]*HookTask, error) { func HookTasks(hookID int64, page int) ([]*HookTask, error) {
tasks := make([]*HookTask, 0, setting.Webhook.PagingNum) tasks := make([]*HookTask, 0, setting.Webhook.PagingNum)
return tasks, x.Limit(setting.Webhook.PagingNum, (page-1)*setting.Webhook.PagingNum).Where("hook_id=?", hookID).Desc("id").Find(&tasks)
return tasks, x.
Limit(setting.Webhook.PagingNum, (page-1)*setting.Webhook.PagingNum).
Where("hook_id=?", hookID).
Desc("id").
Find(&tasks)
} }


// CreateHookTask creates a new hook task, // CreateHookTask creates a new hook task,
// TODO: shoot more hooks at same time. // TODO: shoot more hooks at same time.
func DeliverHooks() { func DeliverHooks() {
tasks := make([]*HookTask, 0, 10) tasks := make([]*HookTask, 0, 10)
x.Where("is_delivered=?", false).Iterate(new(HookTask),
func(idx int, bean interface{}) error {
t := bean.(*HookTask)
t.deliver()
tasks = append(tasks, t)
return nil
})
x.
Where("is_delivered=?", false).
Iterate(new(HookTask),
func(idx int, bean interface{}) error {
t := bean.(*HookTask)
t.deliver()
tasks = append(tasks, t)
return nil
})


// Update hook task status. // Update hook task status.
for _, t := range tasks { for _, t := range tasks {

Ładowanie…
Anuluj
Zapisz