diff options
Diffstat (limited to 'models')
-rw-r--r-- | models/action.go | 6 | ||||
-rw-r--r-- | models/error.go | 21 | ||||
-rw-r--r-- | models/issue.go | 199 | ||||
-rw-r--r-- | models/repo.go | 4 |
4 files changed, 162 insertions, 68 deletions
diff --git a/models/action.go b/models/action.go index 0d763be5..99cd1709 100644 --- a/models/action.go +++ b/models/action.go @@ -153,7 +153,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com url := fmt.Sprintf("%s/%s/%s/commit/%s", setting.AppSubUrl, repoUserName, repoName, c.Sha1) message := fmt.Sprintf(`<a href="%s">%s</a>`, url, c.Message) - if _, err = CreateComment(userId, issue.RepoId, issue.ID, 0, 0, COMMENT_TYPE_COMMIT, message, nil); err != nil { + if _, err = CreateComment(userId, issue.RepoID, issue.ID, 0, 0, COMMENT_TYPE_COMMIT, message, nil); err != nil { return err } } @@ -183,7 +183,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com return err } - if issue.RepoId == repoId { + if issue.RepoID == repoId { if issue.IsClosed { continue } @@ -242,7 +242,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com return err } - if issue.RepoId == repoId { + if issue.RepoID == repoId { if !issue.IsClosed { continue } diff --git a/models/error.go b/models/error.go index 067eace2..38a3c053 100644 --- a/models/error.go +++ b/models/error.go @@ -148,3 +148,24 @@ func IsErrRepoNotExist(err error) bool { func (err ErrRepoNotExist) Error() string { return fmt.Sprintf("repository does not exist [id: %d, uid: %d, name: %s]", err.ID, err.UID, err.Name) } + +// _____ .__.__ __ +// / \ |__| | ____ _______/ |_ ____ ____ ____ +// / \ / \| | | _/ __ \ / ___/\ __\/ _ \ / \_/ __ \ +// / Y \ | |_\ ___/ \___ \ | | ( <_> ) | \ ___/ +// \____|__ /__|____/\___ >____ > |__| \____/|___| /\___ > +// \/ \/ \/ \/ \/ + +type ErrMilestoneNotExist struct { + ID int64 + Index int64 +} + +func IsErrMilestoneNotExist(err error) bool { + _, ok := err.(ErrMilestoneNotExist) + return ok +} + +func (err ErrMilestoneNotExist) Error() string { + return fmt.Sprintf("milestone does not exist [id: %d, index: %d]", err.ID, err.Index) +} diff --git a/models/issue.go b/models/issue.go index 77b38cbc..9fd53b47 100644 --- a/models/issue.go +++ b/models/issue.go @@ -14,6 +14,7 @@ import ( "time" "github.com/Unknwon/com" + "github.com/go-xorm/xorm" "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" @@ -22,7 +23,6 @@ import ( var ( ErrIssueNotExist = errors.New("Issue does not exist") ErrLabelNotExist = errors.New("Label does not exist") - ErrMilestoneNotExist = errors.New("Milestone does not exist") ErrWrongIssueCounter = errors.New("Invalid number of issues for this milestone") ErrAttachmentNotExist = errors.New("Attachment does not exist") ErrAttachmentNotLinked = errors.New("Attachment does not belong to this issue") @@ -32,16 +32,17 @@ var ( // Issue represents an issue or pull request of repository. type Issue struct { ID int64 `xorm:"pk autoincr"` - RepoId int64 `xorm:"INDEX"` + RepoID int64 `xorm:"INDEX"` Index int64 // Index in one repository. Name string Repo *Repository `xorm:"-"` - PosterId int64 + PosterID int64 Poster *User `xorm:"-"` LabelIds string `xorm:"TEXT"` Labels []*Label `xorm:"-"` - MilestoneId int64 - AssigneeId int64 + MilestoneID int64 + Milestone *Milestone `xorm:"-"` + AssigneeID int64 Assignee *User `xorm:"-"` IsRead bool `xorm:"-"` IsPull bool // Indicates whether is a pull request or not. @@ -55,8 +56,24 @@ type Issue struct { Updated time.Time `xorm:"UPDATED"` } +func (i *Issue) BeforeSet(colName string, val xorm.Cell) { + var err error + switch colName { + case "milestone_id": + mid := (*val).(int64) + if mid <= 0 { + return + } + + i.Milestone, err = GetMilestoneById(mid) + if err != nil { + log.Error(3, "GetMilestoneById: %v", err) + } + } +} + func (i *Issue) GetPoster() (err error) { - i.Poster, err = GetUserById(i.PosterId) + i.Poster, err = GetUserById(i.PosterID) if IsErrUserNotExist(err) { i.Poster = &User{Name: "FakeUser"} return nil @@ -88,10 +105,11 @@ func (i *Issue) GetLabels() error { } func (i *Issue) GetAssignee() (err error) { - if i.AssigneeId == 0 { + if i.AssigneeID == 0 { return nil } - i.Assignee, err = GetUserById(i.AssigneeId) + + i.Assignee, err = GetUserById(i.AssigneeID) if IsErrUserNotExist(err) { return nil } @@ -121,7 +139,7 @@ func NewIssue(issue *Issue) (err error) { if _, err = sess.Insert(issue); err != nil { return err - } else if _, err = sess.Exec("UPDATE `repository` SET num_issues = num_issues + 1 WHERE id = ?", issue.RepoId); err != nil { + } else if _, err = sess.Exec("UPDATE `repository` SET num_issues = num_issues + 1 WHERE id = ?", issue.RepoID); err != nil { return err } @@ -129,9 +147,9 @@ func NewIssue(issue *Issue) (err error) { return err } - if issue.MilestoneId > 0 { + if issue.MilestoneID > 0 { // FIXES(280): Update milestone counter. - return ChangeMilestoneAssign(0, issue.MilestoneId, issue) + return ChangeMilestoneAssign(0, issue.MilestoneID, issue) } return @@ -162,7 +180,7 @@ func GetIssueByRef(ref string) (issue *Issue, err error) { // GetIssueByIndex returns issue by given index in repository. func GetIssueByIndex(rid, index int64) (*Issue, error) { - issue := &Issue{RepoId: rid, Index: index} + issue := &Issue{RepoID: rid, Index: index} has, err := x.Get(issue) if err != nil { return nil, err @@ -184,8 +202,8 @@ func GetIssueById(id int64) (*Issue, error) { return issue, nil } -// GetIssues returns a list of issues by given conditions. -func GetIssues(uid, assigneeID, repoID, posterID, milestoneID int64, page int, isClosed, isMention bool, labelIds, sortType string) ([]Issue, error) { +// Issues returns a list of issues by given conditions. +func Issues(uid, assigneeID, repoID, posterID, milestoneID int64, page int, isClosed, isMention bool, labelIds, sortType string) ([]*Issue, error) { sess := x.Limit(setting.IssuePagingNum, (page-1)*setting.IssuePagingNum) if repoID > 0 { @@ -237,7 +255,7 @@ func GetIssues(uid, assigneeID, repoID, posterID, milestoneID int64, page int, i sess.Join("INNER", "issue_user", queryStr) } - var issues []Issue + issues := make([]*Issue, 0, setting.IssuePagingNum) return issues, sess.Find(&issues) } @@ -626,8 +644,8 @@ func DeleteLabel(repoID, labelID int64) error { // Milestone represents a milestone of repository. type Milestone struct { - Id int64 - RepoId int64 `xorm:"INDEX"` + ID int64 `xorm:"pk autoincr"` + RepoID int64 `xorm:"INDEX"` Index int64 Name string Content string `xorm:"TEXT"` @@ -639,9 +657,24 @@ type Milestone struct { Completeness int // Percentage(1-100). Deadline time.Time DeadlineString string `xorm:"-"` + IsOverDue bool `xorm:"-"` ClosedDate time.Time } +func (m *Milestone) BeforeSet(colName string, val xorm.Cell) { + if colName == "deadline" { + t := (*val).(time.Time) + if t.Year() == 9999 { + return + } + + m.DeadlineString = t.Format("2006-01-02") + if time.Now().After(t) { + m.IsOverDue = true + } + } +} + // CalOpenIssues calculates the open issues of milestone. func (m *Milestone) CalOpenIssues() { m.NumOpenIssues = m.NumIssues - m.NumClosedIssues @@ -661,7 +694,7 @@ func NewMilestone(m *Milestone) (err error) { } rawSql := "UPDATE `repository` SET num_milestones = num_milestones + 1 WHERE id = ?" - if _, err = sess.Exec(rawSql, m.RepoId); err != nil { + if _, err = sess.Exec(rawSql, m.RepoID); err != nil { sess.Rollback() return err } @@ -670,81 +703,115 @@ func NewMilestone(m *Milestone) (err error) { // GetMilestoneById returns the milestone by given ID. func GetMilestoneById(id int64) (*Milestone, error) { - m := &Milestone{Id: id} + m := &Milestone{ID: id} has, err := x.Get(m) if err != nil { return nil, err } else if !has { - return nil, ErrMilestoneNotExist + return nil, ErrMilestoneNotExist{id, 0} } return m, nil } // GetMilestoneByIndex returns the milestone of given repository and index. func GetMilestoneByIndex(repoId, idx int64) (*Milestone, error) { - m := &Milestone{RepoId: repoId, Index: idx} + m := &Milestone{RepoID: repoId, Index: idx} has, err := x.Get(m) if err != nil { return nil, err } else if !has { - return nil, ErrMilestoneNotExist + return nil, ErrMilestoneNotExist{0, idx} } return m, nil } -// GetMilestones returns a list of milestones of given repository and status. -func GetMilestones(repoId int64, isClosed bool) ([]*Milestone, error) { +// GetAllRepoMilestones returns all milestones of given repository. +func GetAllRepoMilestones(repoID int64) ([]*Milestone, error) { miles := make([]*Milestone, 0, 10) - err := x.Where("repo_id=?", repoId).And("is_closed=?", isClosed).Find(&miles) - return miles, err + return miles, x.Where("repo_id=?", repoID).Find(&miles) +} + +// GetMilestones returns a list of milestones of given repository and status. +func GetMilestones(repoID int64, page int, isClosed bool) ([]*Milestone, error) { + miles := make([]*Milestone, 0, setting.IssuePagingNum) + sess := x.Where("repo_id=? AND is_closed=?", repoID, isClosed) + if page > 0 { + sess = sess.Limit(setting.IssuePagingNum, (page-1)*setting.IssuePagingNum) + } + return miles, sess.Find(&miles) + +} + +func updateMilestone(e Engine, m *Milestone) error { + _, err := e.Id(m.ID).AllCols().Update(m) + return err } // UpdateMilestone updates information of given milestone. func UpdateMilestone(m *Milestone) error { - _, err := x.Id(m.Id).Update(m) - return err + return updateMilestone(x, m) +} + +func countRepoMilestones(e Engine, repoID int64) int64 { + count, _ := e.Where("repo_id=?", repoID).Count(new(Milestone)) + return count +} + +// CountRepoMilestones returns number of milestones in given repository. +func CountRepoMilestones(repoID int64) int64 { + return countRepoMilestones(x, repoID) +} + +func countRepoClosedMilestones(e Engine, repoID int64) int64 { + closed, _ := e.Where("repo_id=? AND is_closed=?", repoID, true).Count(new(Milestone)) + return closed +} + +// CountRepoClosedMilestones returns number of closed milestones in given repository. +func CountRepoClosedMilestones(repoID int64) int64 { + return countRepoClosedMilestones(x, repoID) +} + +// MilestoneStats returns number of open and closed milestones of given repository. +func MilestoneStats(repoID int64) (open int64, closed int64) { + open, _ = x.Where("repo_id=? AND is_closed=?", repoID, false).Count(new(Milestone)) + return open, CountRepoClosedMilestones(repoID) } // ChangeMilestoneStatus changes the milestone open/closed status. func ChangeMilestoneStatus(m *Milestone, isClosed bool) (err error) { - repo, err := GetRepositoryById(m.RepoId) + repo, err := GetRepositoryById(m.RepoID) if err != nil { return err } sess := x.NewSession() - defer sess.Close() + defer sessionRelease(sess) if err = sess.Begin(); err != nil { return err } m.IsClosed = isClosed - if _, err = sess.Id(m.Id).AllCols().Update(m); err != nil { - sess.Rollback() + if err = updateMilestone(sess, m); err != nil { return err } - if isClosed { - repo.NumClosedMilestones++ - } else { - repo.NumClosedMilestones-- - } - if _, err = sess.Id(repo.Id).Update(repo); err != nil { - sess.Rollback() + repo.NumMilestones = int(countRepoMilestones(sess, repo.Id)) + repo.NumClosedMilestones = int(countRepoClosedMilestones(sess, repo.Id)) + if _, err = sess.Id(repo.Id).AllCols().Update(repo); err != nil { return err } return sess.Commit() } -// ChangeMilestoneIssueStats updates the open/closed issues counter and progress for the -// milestone associated witht the given issue. +// ChangeMilestoneIssueStats updates the open/closed issues counter and progress +// for the milestone associated witht the given issue. func ChangeMilestoneIssueStats(issue *Issue) error { - if issue.MilestoneId == 0 { + if issue.MilestoneID == 0 { return nil } - m, err := GetMilestoneById(issue.MilestoneId) - + m, err := GetMilestoneById(issue.MilestoneID) if err != nil { return err } @@ -786,7 +853,7 @@ func ChangeMilestoneAssign(oldMid, mid int64, issue *Issue) (err error) { m.Completeness = 0 } - if _, err = sess.Id(m.Id).Cols("num_issues,num_completeness,num_closed_issues").Update(m); err != nil { + if _, err = sess.Id(m.ID).Cols("num_issues,num_completeness,num_closed_issues").Update(m); err != nil { sess.Rollback() return err } @@ -814,13 +881,13 @@ func ChangeMilestoneAssign(oldMid, mid int64, issue *Issue) (err error) { } m.Completeness = m.NumClosedIssues * 100 / m.NumIssues - if _, err = sess.Id(m.Id).Cols("num_issues,num_completeness,num_closed_issues").Update(m); err != nil { + if _, err = sess.Id(m.ID).Cols("num_issues,num_completeness,num_closed_issues").Update(m); err != nil { sess.Rollback() return err } rawSql := "UPDATE `issue_user` SET milestone_id = ? WHERE issue_id = ?" - if _, err = sess.Exec(rawSql, m.Id, issue.ID); err != nil { + if _, err = sess.Exec(rawSql, m.ID, issue.ID); err != nil { sess.Rollback() return err } @@ -829,34 +896,40 @@ func ChangeMilestoneAssign(oldMid, mid int64, issue *Issue) (err error) { return sess.Commit() } -// DeleteMilestone deletes a milestone. -func DeleteMilestone(m *Milestone) (err error) { - sess := x.NewSession() - defer sess.Close() - if err = sess.Begin(); err != nil { +// DeleteMilestoneByID deletes a milestone by given ID. +func DeleteMilestoneByID(mid int64) error { + m, err := GetMilestoneById(mid) + if err != nil { + if IsErrMilestoneNotExist(err) { + return nil + } return err } - if _, err = sess.Delete(m); err != nil { - sess.Rollback() + repo, err := GetRepositoryById(m.RepoID) + if err != nil { return err } - rawSql := "UPDATE `repository` SET num_milestones = num_milestones - 1 WHERE id = ?" - if _, err = sess.Exec(rawSql, m.RepoId); err != nil { - sess.Rollback() + sess := x.NewSession() + defer sessionRelease(sess) + if err = sess.Begin(); err != nil { return err } - rawSql = "UPDATE `issue` SET milestone_id = 0 WHERE milestone_id = ?" - if _, err = sess.Exec(rawSql, m.Id); err != nil { - sess.Rollback() + if _, err = sess.Id(m.ID).Delete(m); err != nil { return err } - rawSql = "UPDATE `issue_user` SET milestone_id = 0 WHERE milestone_id = ?" - if _, err = sess.Exec(rawSql, m.Id); err != nil { - sess.Rollback() + repo.NumMilestones = int(countRepoMilestones(sess, repo.Id)) + repo.NumClosedMilestones = int(countRepoClosedMilestones(sess, repo.Id)) + if _, err = sess.Id(repo.Id).AllCols().Update(repo); err != nil { + return err + } + + if _, err = sess.Exec("UPDATE `issue` SET milestone_id=0 WHERE milestone_id=?", m.ID); err != nil { + return err + } else if _, err = sess.Exec("UPDATE `issue_user` SET milestone_id=0 WHERE milestone_id=?", m.ID); err != nil { return err } return sess.Commit() diff --git a/models/repo.go b/models/repo.go index 117837fc..c61bef2f 100644 --- a/models/repo.go +++ b/models/repo.go @@ -867,7 +867,7 @@ func DeleteRepository(uid, repoID int64, userName string) error { return err } else if _, err = sess.Delete(&IssueUser{RepoId: repoID}); err != nil { return err - } else if _, err = sess.Delete(&Milestone{RepoId: repoID}); err != nil { + } else if _, err = sess.Delete(&Milestone{RepoID: repoID}); err != nil { return err } else if _, err = sess.Delete(&Release{RepoId: repoID}); err != nil { return err @@ -886,7 +886,7 @@ func DeleteRepository(uid, repoID int64, userName string) error { } } - if _, err = sess.Delete(&Issue{RepoId: repoID}); err != nil { + if _, err = sess.Delete(&Issue{RepoID: repoID}); err != nil { return err } |