aboutsummaryrefslogtreecommitdiff
path: root/models
diff options
context:
space:
mode:
Diffstat (limited to 'models')
-rw-r--r--models/action.go6
-rw-r--r--models/error.go21
-rw-r--r--models/issue.go199
-rw-r--r--models/repo.go4
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
}