You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

229 lines
5.8 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package models
  5. import (
  6. "errors"
  7. "strings"
  8. "time"
  9. "github.com/gogits/gogs/modules/base"
  10. )
  11. var (
  12. ErrIssueNotExist = errors.New("Issue does not exist")
  13. )
  14. // Issue represents an issue or pull request of repository.
  15. type Issue struct {
  16. Id int64
  17. Index int64 // Index in one repository.
  18. Name string
  19. RepoId int64 `xorm:"index"`
  20. Repo *Repository `xorm:"-"`
  21. PosterId int64
  22. Poster *User `xorm:"-"`
  23. MilestoneId int64
  24. AssigneeId int64
  25. IsPull bool // Indicates whether is a pull request or not.
  26. IsClosed bool
  27. Labels string `xorm:"TEXT"`
  28. Mentions string `xorm:"TEXT"`
  29. Content string `xorm:"TEXT"`
  30. RenderedContent string `xorm:"-"`
  31. NumComments int
  32. Created time.Time `xorm:"created"`
  33. Updated time.Time `xorm:"updated"`
  34. }
  35. // CreateIssue creates new issue for repository.
  36. func CreateIssue(userId, repoId, milestoneId, assigneeId int64, issueCount int, name, labels, content string, isPull bool) (issue *Issue, err error) {
  37. // TODO: find out mentions
  38. mentions := ""
  39. sess := orm.NewSession()
  40. defer sess.Close()
  41. sess.Begin()
  42. issue = &Issue{
  43. Index: int64(issueCount) + 1,
  44. Name: name,
  45. RepoId: repoId,
  46. PosterId: userId,
  47. MilestoneId: milestoneId,
  48. AssigneeId: assigneeId,
  49. IsPull: isPull,
  50. Labels: labels,
  51. Mentions: mentions,
  52. Content: content,
  53. }
  54. if _, err = sess.Insert(issue); err != nil {
  55. sess.Rollback()
  56. return nil, err
  57. }
  58. rawSql := "UPDATE `repository` SET num_issues = num_issues + 1 WHERE id = ?"
  59. if _, err = sess.Exec(rawSql, repoId); err != nil {
  60. sess.Rollback()
  61. return nil, err
  62. }
  63. return issue, sess.Commit()
  64. }
  65. // GetIssueById returns issue object by given id.
  66. func GetIssueByIndex(repoId, index int64) (*Issue, error) {
  67. issue := &Issue{RepoId: repoId, Index: index}
  68. has, err := orm.Get(issue)
  69. if err != nil {
  70. return nil, err
  71. } else if !has {
  72. return nil, ErrIssueNotExist
  73. }
  74. return issue, nil
  75. }
  76. // GetIssues returns a list of issues by given conditions.
  77. func GetIssues(userId, repoId, posterId, milestoneId int64, page int, isClosed, isMention bool, labels, sortType string) ([]Issue, error) {
  78. sess := orm.Limit(20, (page-1)*20)
  79. if repoId > 0 {
  80. sess.Where("repo_id=?", repoId).And("is_closed=?", isClosed)
  81. } else {
  82. sess.Where("is_closed=?", isClosed)
  83. }
  84. if userId > 0 {
  85. sess.And("assignee_id=?", userId)
  86. } else if posterId > 0 {
  87. sess.And("poster_id=?", posterId)
  88. } else if isMention {
  89. sess.And("mentions like '%$" + base.ToStr(userId) + "|%'")
  90. }
  91. if milestoneId > 0 {
  92. sess.And("milestone_id=?", milestoneId)
  93. }
  94. if len(labels) > 0 {
  95. for _, label := range strings.Split(labels, ",") {
  96. sess.And("mentions like '%$" + label + "|%'")
  97. }
  98. }
  99. switch sortType {
  100. case "oldest":
  101. sess.Asc("created")
  102. case "recentupdate":
  103. sess.Desc("updated")
  104. case "leastupdate":
  105. sess.Asc("updated")
  106. case "mostcomment":
  107. sess.Desc("num_comments")
  108. case "leastcomment":
  109. sess.Asc("num_comments")
  110. default:
  111. sess.Desc("created")
  112. }
  113. var issues []Issue
  114. err := sess.Find(&issues)
  115. return issues, err
  116. }
  117. // GetUserIssueCount returns the number of issues that were created by given user in repository.
  118. func GetUserIssueCount(userId, repoId int64) int64 {
  119. count, _ := orm.Where("poster_id=?", userId).And("repo_id=?", repoId).Count(new(Issue))
  120. return count
  121. }
  122. // UpdateIssue updates information of issue.
  123. func UpdateIssue(issue *Issue) error {
  124. _, err := orm.Id(issue.Id).AllCols().Update(issue)
  125. return err
  126. }
  127. // Label represents a list of labels of repository for issues.
  128. type Label struct {
  129. Id int64
  130. RepoId int64 `xorm:"index"`
  131. Names string
  132. Colors string
  133. }
  134. // Milestone represents a milestone of repository.
  135. type Milestone struct {
  136. Id int64
  137. Name string
  138. RepoId int64 `xorm:"index"`
  139. IsClosed bool
  140. Content string
  141. NumIssues int
  142. DueDate time.Time
  143. Created time.Time `xorm:"created"`
  144. }
  145. // Issue types.
  146. const (
  147. IT_PLAIN = iota // Pure comment.
  148. IT_REOPEN // Issue reopen status change prompt.
  149. IT_CLOSE // Issue close status change prompt.
  150. )
  151. // Comment represents a comment in commit and issue page.
  152. type Comment struct {
  153. Id int64
  154. Type int
  155. PosterId int64
  156. Poster *User `xorm:"-"`
  157. IssueId int64
  158. CommitId int64
  159. Line int64
  160. Content string
  161. Created time.Time `xorm:"created"`
  162. }
  163. // CreateComment creates comment of issue or commit.
  164. func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType int, content string) error {
  165. sess := orm.NewSession()
  166. defer sess.Close()
  167. sess.Begin()
  168. if _, err := sess.Insert(&Comment{PosterId: userId, Type: cmtType, IssueId: issueId,
  169. CommitId: commitId, Line: line, Content: content}); err != nil {
  170. sess.Rollback()
  171. return err
  172. }
  173. // Check comment type.
  174. switch cmtType {
  175. case IT_PLAIN:
  176. rawSql := "UPDATE `issue` SET num_comments = num_comments + 1 WHERE id = ?"
  177. if _, err := sess.Exec(rawSql, issueId); err != nil {
  178. sess.Rollback()
  179. return err
  180. }
  181. case IT_REOPEN:
  182. rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues - 1 WHERE id = ?"
  183. if _, err := sess.Exec(rawSql, repoId); err != nil {
  184. sess.Rollback()
  185. return err
  186. }
  187. case IT_CLOSE:
  188. rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues + 1 WHERE id = ?"
  189. if _, err := sess.Exec(rawSql, repoId); err != nil {
  190. sess.Rollback()
  191. return err
  192. }
  193. }
  194. return sess.Commit()
  195. }
  196. // GetIssueComments returns list of comment by given issue id.
  197. func GetIssueComments(issueId int64) ([]Comment, error) {
  198. comments := make([]Comment, 0, 10)
  199. err := orm.Asc("created").Find(&comments, &Comment{IssueId: issueId})
  200. return comments, err
  201. }