aboutsummaryrefslogtreecommitdiffstats
path: root/apps/user_status
ModeNameSize
-rw-r--r--.l10nignore27logstatsplain
d---------appinfo74logstatsplain
d---------composer157logstatsplain
d---------css149logstatsplain
d---------img233logstatsplain
d---------l10n3218logstatsplain
d---------lib397logstatsplain
d---------src320logstatsplain
d---------tests72logstatsplain
lass="w"> true). Join("INNER", "issue_user", "issue.id = issue_user.issue_id and issue_user.is_mentioned = ?", true). And("issue_user.uid = ?", opts.UserID). Count(new(Issue)) if err != nil { return nil, err } } cond = cond.And(builder.Eq{"issue.is_closed": opts.IsClosed}) stats.AssignCount, err = x.Where(cond). Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). And("issue_assignees.assignee_id = ?", opts.UserID). Count(new(Issue)) if err != nil { return nil, err } stats.CreateCount, err = x.Where(cond). And("poster_id = ?", opts.UserID). Count(new(Issue)) if err != nil { return nil, err } stats.MentionCount, err = x.Where(cond). Join("INNER", "issue_user", "issue.id = issue_user.issue_id and issue_user.is_mentioned = ?", true). And("issue_user.uid = ?", opts.UserID). Count(new(Issue)) if err != nil { return nil, err } stats.YourRepositoriesCount, err = x.Where(cond). And(builder.In("issue.repo_id", opts.UserRepoIDs)). Count(new(Issue)) if err != nil { return nil, err } return stats, nil } // 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) { countSession := func(isClosed, isPull bool, repoID int64) *xorm.Session { sess := x. Where("is_closed = ?", isClosed). And("is_pull = ?", isPull). And("repo_id = ?", repoID) return sess } openCountSession := countSession(false, isPull, repoID) closedCountSession := countSession(true, isPull, repoID) switch filterMode { case FilterModeAssign: openCountSession.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). And("issue_assignees.assignee_id = ?", uid) closedCountSession.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). And("issue_assignees.assignee_id = ?", uid) case FilterModeCreate: openCountSession.And("poster_id = ?", uid) closedCountSession.And("poster_id = ?", uid) } openResult, _ := openCountSession.Count(new(Issue)) closedResult, _ := closedCountSession.Count(new(Issue)) return openResult, closedResult } // SearchIssueIDsByKeyword search issues on database func SearchIssueIDsByKeyword(kw string, repoID int64, limit, start int) (int64, []int64, error) { var repoCond = builder.Eq{"repo_id": repoID} var subQuery = builder.Select("id").From("issue").Where(repoCond) var cond = builder.And( repoCond, builder.Or( builder.Like{"name", kw}, builder.Like{"content", kw}, builder.In("id", builder.Select("issue_id"). From("comment"). Where(builder.And( builder.Eq{"type": CommentTypeComment}, builder.In("issue_id", subQuery), builder.Like{"content", kw}, )), ), ), ) var ids = make([]int64, 0, limit) err := x.Distinct("id").Table("issue").Where(cond).Limit(limit, start).Find(&ids) if err != nil { return 0, nil, err } total, err := x.Distinct("id").Table("issue").Where(cond).Count() if err != nil { return 0, nil, err } return total, ids, nil } func updateIssue(e Engine, issue *Issue) error { _, err := e.ID(issue.ID).AllCols().Update(issue) if err != nil { return err } return nil } // UpdateIssue updates all fields of given issue. func UpdateIssue(issue *Issue) error { sess := x.NewSession() defer sess.Close() if err := sess.Begin(); err != nil { return err } if err := updateIssue(sess, issue); err != nil { return err } if err := issue.neuterCrossReferences(sess); err != nil { return err } if err := issue.loadPoster(sess); err != nil { return err } if err := issue.addCrossReferences(sess, issue.Poster); err != nil { return err } return sess.Commit() } // UpdateIssueDeadline updates an issue deadline and adds comments. Setting a deadline to 0 means deleting it. func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *User) (err error) { // if the deadline hasn't changed do nothing if issue.DeadlineUnix == deadlineUnix { return nil } sess := x.NewSession() defer sess.Close() if err := sess.Begin(); err != nil { return err } // Update the deadline if err = updateIssueCols(sess, &Issue{ID: issue.ID, DeadlineUnix: deadlineUnix}, "deadline_unix"); err != nil { return err } // Make the comment if _, err = createDeadlineComment(sess, doer, issue, deadlineUnix); err != nil { return fmt.Errorf("createRemovedDueDateComment: %v", err) } return sess.Commit() } // Get Blocked By Dependencies, aka all issues this issue is blocked by. func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*Issue, err error) { return issueDeps, e. Table("issue_dependency"). Select("issue.*"). Join("INNER", "issue", "issue.id = issue_dependency.dependency_id"). Where("issue_id = ?", issue.ID). Find(&issueDeps) } // Get Blocking Dependencies, aka all issues this issue blocks. func (issue *Issue) getBlockingDependencies(e Engine) (issueDeps []*Issue, err error) { return issueDeps, e. Table("issue_dependency"). Select("issue.*"). Join("INNER", "issue", "issue.id = issue_dependency.issue_id"). Where("dependency_id = ?", issue.ID). Find(&issueDeps) } // BlockedByDependencies finds all Dependencies an issue is blocked by func (issue *Issue) BlockedByDependencies() ([]*Issue, error) { return issue.getBlockedByDependencies(x) } // BlockingDependencies returns all blocking dependencies, aka all other issues a given issue blocks func (issue *Issue) BlockingDependencies() ([]*Issue, error) { return issue.getBlockingDependencies(x) } func (issue *Issue) updateClosedNum(e Engine) (err error) { if issue.IsPull { _, err = e.Exec("UPDATE `repository` SET num_closed_pulls=(SELECT count(*) FROM issue WHERE repo_id=? AND is_pull=? AND is_closed=?) WHERE id=?", issue.RepoID, true, true, issue.RepoID, ) } else { _, err = e.Exec("UPDATE `repository` SET num_closed_issues=(SELECT count(*) FROM issue WHERE repo_id=? AND is_pull=? AND is_closed=?) WHERE id=?", issue.RepoID, false, true, issue.RepoID, ) } return } // ResolveMentionsByVisibility returns the users mentioned in an issue, removing those that // don't have access to reading it. Teams are expanded into their users, but organizations are ignored. func (issue *Issue) ResolveMentionsByVisibility(ctx DBContext, doer *User, mentions []string) (users []*User, err error) { if len(mentions) == 0 { return } if err = issue.loadRepo(ctx.e); err != nil { return } resolved := make(map[string]bool, 20) names := make([]string, 0, 20) resolved[doer.LowerName] = true for _, name := range mentions { name := strings.ToLower(name) if _, ok := resolved[name]; ok { continue } resolved[name] = false names = append(names, name) } if err := issue.Repo.getOwner(ctx.e); err != nil { return nil, err } if issue.Repo.Owner.IsOrganization() { // Since there can be users with names that match the name of a team, // if the team exists and can read the issue, the team takes precedence. teams := make([]*Team, 0, len(names)) if err := ctx.e. Join("INNER", "team_repo", "team_repo.team_id = team.id"). Where("team_repo.repo_id=?", issue.Repo.ID). In("team.lower_name", names). Find(&teams); err != nil { return nil, fmt.Errorf("find mentioned teams: %v", err) } if len(teams) != 0 { checked := make([]int64, 0, len(teams)) unittype := UnitTypeIssues if issue.IsPull { unittype = UnitTypePullRequests } for _, team := range teams { if team.Authorize >= AccessModeOwner { checked = append(checked, team.ID) resolved[team.LowerName] = true continue } has, err := ctx.e.Get(&TeamUnit{OrgID: issue.Repo.Owner.ID, TeamID: team.ID, Type: unittype}) if err != nil { return nil, fmt.Errorf("get team units (%d): %v", team.ID, err) } if has { checked = append(checked, team.ID) resolved[team.LowerName] = true } } if len(checked) != 0 { teamusers := make([]*User, 0, 20) if err := ctx.e. Join("INNER", "team_user", "team_user.uid = `user`.id"). In("`team_user`.team_id", checked). And("`user`.is_active = ?", true). And("`user`.prohibit_login = ?", false). Find(&teamusers); err != nil { return nil, fmt.Errorf("get teams users: %v", err) } if len(teamusers) > 0 { users = make([]*User, 0, len(teamusers)) for _, user := range teamusers { if already, ok := resolved[user.LowerName]; !ok || !already { users = append(users, user) resolved[user.LowerName] = true } } } } } // Remove names already in the list to avoid querying the database if pending names remain names = make([]string, 0, len(resolved)) for name, already := range resolved { if !already { names = append(names, name) } } if len(names) == 0 { return } } unchecked := make([]*User, 0, len(names)) if err := ctx.e. Where("`user`.is_active = ?", true). And("`user`.prohibit_login = ?", false). In("`user`.lower_name", names). Find(&unchecked); err != nil { return nil, fmt.Errorf("find mentioned users: %v", err) } for _, user := range unchecked { if already := resolved[user.LowerName]; already || user.IsOrganization() { continue } // Normal users must have read access to the referencing issue perm, err := getUserRepoPermission(ctx.e, issue.Repo, user) if err != nil { return nil, fmt.Errorf("getUserRepoPermission [%d]: %v", user.ID, err) } if !perm.CanReadIssuesOrPulls(issue.IsPull) { continue } users = append(users, user) } return } // UpdateIssuesMigrationsByType updates all migrated repositories' issues from gitServiceType to replace originalAuthorID to posterID func UpdateIssuesMigrationsByType(gitServiceType structs.GitServiceType, originalAuthorID, posterID int64) error { _, err := x.Table("issue"). Where("repo_id IN (SELECT id FROM repository WHERE original_service_type = ?)", gitServiceType). And("original_author_id = ?", originalAuthorID). Update(map[string]interface{}{ "poster_id": posterID, "original_author": "", "original_author_id": 0, }) return err }