aboutsummaryrefslogtreecommitdiff
path: root/models
diff options
context:
space:
mode:
Diffstat (limited to 'models')
-rw-r--r--models/issue.go86
-rw-r--r--models/org.go2
-rw-r--r--models/release.go2
-rw-r--r--models/repo.go73
-rw-r--r--models/user.go50
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)
}
// ___________ .__ .__