diff options
Diffstat (limited to 'models')
-rw-r--r-- | models/issue.go | 86 | ||||
-rw-r--r-- | models/org.go | 2 | ||||
-rw-r--r-- | models/release.go | 2 | ||||
-rw-r--r-- | models/repo.go | 73 | ||||
-rw-r--r-- | models/user.go | 50 |
5 files changed, 155 insertions, 58 deletions
diff --git a/models/issue.go b/models/issue.go index 067f0a0b..edc46689 100644 --- a/models/issue.go +++ b/models/issue.go @@ -88,6 +88,23 @@ func (i *Issue) AfterSet(colName string, _ xorm.Cell) { log.Error(3, "GetCommentsByIssueID[%d]: %v", i.ID, err) } + i.Labels, err = GetLabelsByIssueID(i.ID) + if err != nil { + log.Error(3, "GetLabelsByIssueID[%d]: %v", i.ID, err) + } + + case "poster_id": + i.Poster, err = GetUserByID(i.PosterID) + if err != nil { + if IsErrUserNotExist(err) { + i.PosterID = -1 + i.Poster = NewFakeUser() + } else { + log.Error(3, "GetUserByID[%d]: %v", i.ID, err) + } + return + } + case "milestone_id": if i.MilestoneID == 0 { return @@ -97,6 +114,7 @@ func (i *Issue) AfterSet(colName string, _ xorm.Cell) { if err != nil { log.Error(3, "GetMilestoneById[%d]: %v", i.ID, err) } + case "assignee_id": if i.AssigneeID == 0 { return @@ -106,6 +124,7 @@ func (i *Issue) AfterSet(colName string, _ xorm.Cell) { if err != nil { log.Error(3, "GetUserByID[%d]: %v", i.ID, err) } + case "deadline_unix": i.Deadline = time.Unix(i.DeadlineUnix, 0).Local() case "created_unix": @@ -120,21 +139,19 @@ func (i *Issue) HashTag() string { return "issue-" + com.ToStr(i.ID) } +// State returns string representation of issue status. +func (i *Issue) State() string { + if i.IsClosed { + return "closed" + } + return "open" +} + // IsPoster returns true if given user by ID is the poster. func (i *Issue) IsPoster(uid int64) bool { return i.PosterID == uid } -func (i *Issue) GetPoster() (err error) { - i.Poster, err = GetUserByID(i.PosterID) - if IsErrUserNotExist(err) { - i.PosterID = -1 - i.Poster = NewFakeUser() - return nil - } - return err -} - func (i *Issue) hasLabel(e Engine, labelID int64) bool { return hasIssueLabel(e, i.ID, labelID) } @@ -175,11 +192,6 @@ func (i *Issue) getLabels(e Engine) (err error) { return nil } -// GetLabels retrieves all labels of issue and assign to corresponding field. -func (i *Issue) GetLabels() error { - return i.getLabels(x) -} - func (i *Issue) removeLabel(e *xorm.Session, label *Label) error { return deleteIssueLabel(e, i, label) } @@ -303,6 +315,19 @@ func (i *Issue) GetPullRequest() (err error) { // It's caller's responsibility to create action. func newIssue(e *xorm.Session, repo *Repository, issue *Issue, labelIDs []int64, uuids []string, isPull bool) (err error) { + issue.Name = strings.TrimSpace(issue.Name) + issue.Index = repo.NextIssueIndex() + + if issue.AssigneeID > 0 { + // Silently drop invalid assignee + valid, err := hasAccess(e, &User{Id: issue.AssigneeID}, repo, ACCESS_MODE_WRITE) + if err != nil { + return fmt.Errorf("hasAccess: %v", err) + } else if !valid { + issue.AssigneeID = 0 + } + } + if _, err = e.Insert(issue); err != nil { return err } @@ -325,6 +350,10 @@ func newIssue(e *xorm.Session, repo *Repository, issue *Issue, labelIDs []int64, } for _, label := range labels { + if label.RepoID != repo.ID { + continue + } + if err = issue.addLabel(e, label); err != nil { return fmt.Errorf("addLabel: %v", err) } @@ -377,6 +406,10 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string) return fmt.Errorf("newIssue: %v", err) } + if err = sess.Commit(); err != nil { + return fmt.Errorf("Commit: %v", err) + } + // Notify watchers. act := &Action{ ActUserID: issue.Poster.Id, @@ -389,11 +422,11 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string) RepoName: repo.Name, IsPrivate: repo.IsPrivate, } - if err = notifyWatchers(sess, act); err != nil { - return err + if err = NotifyWatchers(act); err != nil { + log.Error(4, "notifyWatchers: %v", err) } - return sess.Commit() + return nil } // GetIssueByRef returns an Issue specified by a GFM reference. @@ -467,6 +500,10 @@ type IssuesOptions struct { // Issues returns a list of issues by given conditions. func Issues(opts *IssuesOptions) ([]*Issue, error) { + if opts.Page <= 0 { + opts.Page = 1 + } + sess := x.Limit(setting.IssuePagingNum, (opts.Page-1)*setting.IssuePagingNum) if opts.RepoID > 0 { @@ -997,6 +1034,9 @@ func (m *Milestone) BeforeUpdate() { func (m *Milestone) AfterSet(colName string, _ xorm.Cell) { switch colName { + case "num_closed_issues": + m.NumOpenIssues = m.NumIssues - m.NumClosedIssues + case "deadline_unix": m.Deadline = time.Unix(m.DeadlineUnix, 0).Local() if m.Deadline.Year() == 9999 { @@ -1007,14 +1047,18 @@ func (m *Milestone) AfterSet(colName string, _ xorm.Cell) { if time.Now().Local().After(m.Deadline) { m.IsOverDue = true } + case "closed_date_unix": m.ClosedDate = time.Unix(m.ClosedDateUnix, 0).Local() } } -// CalOpenIssues calculates the open issues of milestone. -func (m *Milestone) CalOpenIssues() { - m.NumOpenIssues = m.NumIssues - m.NumClosedIssues +// State returns string representation of milestone status. +func (m *Milestone) State() string { + if m.IsClosed { + return "closed" + } + return "open" } // NewMilestone creates new milestone of repository. diff --git a/models/org.go b/models/org.go index c2665902..62a57ae0 100644 --- a/models/org.go +++ b/models/org.go @@ -169,7 +169,7 @@ func GetOrgByName(name string) (*User, error) { } u := &User{ LowerName: strings.ToLower(name), - Type: ORGANIZATION, + Type: USER_TYPE_ORGANIZATION, } has, err := x.Get(u) if err != nil { diff --git a/models/release.go b/models/release.go index 2379bdc6..69ce6c13 100644 --- a/models/release.go +++ b/models/release.go @@ -39,7 +39,7 @@ type Release struct { } func (r *Release) BeforeInsert() { - r.CreatedUnix = r.Created.UTC().Unix() + r.CreatedUnix = time.Now().UTC().Unix() } func (r *Release) AfterSet(colName string, _ xorm.Cell) { diff --git a/models/repo.go b/models/repo.go index 4ee99dab..abe67a6d 100644 --- a/models/repo.go +++ b/models/repo.go @@ -1049,11 +1049,16 @@ func CountPublicRepositories() int64 { return countRepositories(false) } +func Repositories(page, pageSize int) (_ []*Repository, err error) { + repos := make([]*Repository, 0, pageSize) + return repos, x.Limit(pageSize, (page-1)*pageSize).Asc("id").Find(&repos) +} + // RepositoriesWithUsers returns number of repos in given page. func RepositoriesWithUsers(page, pageSize int) (_ []*Repository, err error) { - repos := make([]*Repository, 0, pageSize) - if err = x.Limit(pageSize, (page-1)*pageSize).Asc("id").Find(&repos); err != nil { - return nil, err + repos, err := Repositories(page, pageSize) + if err != nil { + return nil, fmt.Errorf("Repositories: %v", err) } for i := range repos { @@ -1474,9 +1479,9 @@ func GetRepositories(uid int64, private bool) ([]*Repository, error) { } // GetRecentUpdatedRepositories returns the list of repositories that are recently updated. -func GetRecentUpdatedRepositories(page int) (repos []*Repository, err error) { - return repos, x.Limit(setting.ExplorePagingNum, (page-1)*setting.ExplorePagingNum). - Where("is_private=?", false).Limit(setting.ExplorePagingNum).Desc("updated_unix").Find(&repos) +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) } func getRepositoryCount(e Engine, u *User) (int64, error) { @@ -1488,32 +1493,52 @@ func GetRepositoryCount(u *User) (int64, error) { return getRepositoryCount(x, u) } -type SearchOption struct { - Keyword string - Uid int64 - Limit int - Private bool +type SearchRepoOptions struct { + Keyword string + OwnerID int64 + OrderBy string + Private bool // Include private repositories in results + Page int + PageSize int // Can be smaller than or equal to setting.ExplorePagingNum } -// SearchRepositoryByName returns given number of repositories whose name contains keyword. -func SearchRepositoryByName(opt SearchOption) (repos []*Repository, err error) { - if len(opt.Keyword) == 0 { - return repos, nil +// SearchRepositoryByName takes keyword and part of repository name to search, +// it returns results in given range and number of total results. +func SearchRepositoryByName(opts *SearchRepoOptions) (repos []*Repository, _ int64, _ error) { + if len(opts.Keyword) == 0 { + return repos, 0, nil + } + opts.Keyword = strings.ToLower(opts.Keyword) + + if opts.PageSize <= 0 || opts.PageSize > setting.ExplorePagingNum { + opts.PageSize = setting.ExplorePagingNum + } + if opts.Page <= 0 { + opts.Page = 1 } - opt.Keyword = strings.ToLower(opt.Keyword) - repos = make([]*Repository, 0, opt.Limit) + repos = make([]*Repository, 0, opts.PageSize) - // Append conditions. - sess := x.Limit(opt.Limit) - if opt.Uid > 0 { - sess.Where("owner_id=?", opt.Uid) + // Append conditions + sess := x.Where("lower_name like ?", "%"+opts.Keyword+"%") + if opts.OwnerID > 0 { + sess.And("owner_id = ?", opts.OwnerID) } - if !opt.Private { + if !opts.Private { sess.And("is_private=?", false) } - sess.And("lower_name like ?", "%"+opt.Keyword+"%").Find(&repos) - return repos, err + + var countSess xorm.Session + countSess = *sess + count, err := countSess.Count(new(Repository)) + if err != nil { + return nil, 0, fmt.Errorf("Count: %v", err) + } + + if len(opts.OrderBy) > 0 { + sess.OrderBy(opts.OrderBy) + } + return repos, count, sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Find(&repos) } // DeleteRepositoryArchives deletes all repositories' archives. diff --git a/models/user.go b/models/user.go index 865178b4..82f92789 100644 --- a/models/user.go +++ b/models/user.go @@ -36,8 +36,8 @@ import ( type UserType int const ( - INDIVIDUAL UserType = iota // Historic reason to make it starts at 0. - ORGANIZATION + USER_TYPE_INDIVIDUAL UserType = iota // Historic reason to make it starts at 0. + USER_TYPE_ORGANIZATION ) var ( @@ -389,7 +389,7 @@ func (u *User) IsWriterOfRepo(repo *Repository) bool { // IsOrganization returns true if user is actually a organization. func (u *User) IsOrganization() bool { - return u.Type == ORGANIZATION + return u.Type == USER_TYPE_ORGANIZATION } // IsUserOrgOwner returns true if user is in the owner team of given organization. @@ -1114,16 +1114,44 @@ func GetUserByEmail(email string) (*User, error) { return nil, ErrUserNotExist{0, email} } -// SearchUserByName returns given number of users whose name contains keyword. -func SearchUserByName(opt SearchOption) (us []*User, err error) { - if len(opt.Keyword) == 0 { - return us, nil +type SearchUserOptions struct { + Keyword string + Type UserType + OrderBy string + Page int + PageSize int // Can be smaller than or equal to setting.ExplorePagingNum +} + +// SearchUserByName takes keyword and part of user name to search, +// it returns results in given range and number of total results. +func SearchUserByName(opts *SearchUserOptions) (users []*User, _ int64, _ error) { + if len(opts.Keyword) == 0 { + return users, 0, nil + } + opts.Keyword = strings.ToLower(opts.Keyword) + + if opts.PageSize <= 0 || opts.PageSize > setting.ExplorePagingNum { + opts.PageSize = setting.ExplorePagingNum + } + if opts.Page <= 0 { + opts.Page = 1 } - opt.Keyword = strings.ToLower(opt.Keyword) - us = make([]*User, 0, opt.Limit) - err = x.Limit(opt.Limit).Where("type=0").And("lower_name like ?", "%"+opt.Keyword+"%").Find(&us) - return us, err + users = make([]*User, 0, opts.PageSize) + // Append conditions + sess := x.Where("lower_name like ?", "%"+opts.Keyword+"%").And("type = ?", opts.Type) + + var countSess xorm.Session + countSess = *sess + count, err := countSess.Count(new(User)) + if err != nil { + return nil, 0, fmt.Errorf("Count: %v", err) + } + + if len(opts.OrderBy) > 0 { + sess.OrderBy(opts.OrderBy) + } + return users, count, sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Find(&users) } // ___________ .__ .__ |