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.

234 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
  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. if err = sess.Commit(); err != nil {
  64. sess.Rollback()
  65. return nil, err
  66. }
  67. return issue, nil
  68. }
  69. // GetIssueById returns issue object by given id.
  70. func GetIssueByIndex(repoId, index int64) (*Issue, error) {
  71. issue := &Issue{RepoId: repoId, Index: index}
  72. has, err := orm.Get(issue)
  73. if err != nil {
  74. return nil, err
  75. } else if !has {
  76. return nil, ErrIssueNotExist
  77. }
  78. return issue, nil
  79. }
  80. // GetIssues returns a list of issues by given conditions.
  81. func GetIssues(userId, repoId, posterId, milestoneId int64, page int, isClosed, isMention bool, labels, sortType string) ([]Issue, error) {
  82. sess := orm.Limit(20, (page-1)*20)
  83. if repoId > 0 {
  84. sess.Where("repo_id=?", repoId).And("is_closed=?", isClosed)
  85. } else {
  86. sess.Where("is_closed=?", isClosed)
  87. }
  88. if userId > 0 {
  89. sess.And("assignee_id=?", userId)
  90. } else if posterId > 0 {
  91. sess.And("poster_id=?", posterId)
  92. } else if isMention {
  93. sess.And("mentions like '%$" + base.ToStr(userId) + "|%'")
  94. }
  95. if milestoneId > 0 {
  96. sess.And("milestone_id=?", milestoneId)
  97. }
  98. if len(labels) > 0 {
  99. for _, label := range strings.Split(labels, ",") {
  100. sess.And("mentions like '%$" + label + "|%'")
  101. }
  102. }
  103. switch sortType {
  104. case "oldest":
  105. sess.Asc("created")
  106. case "recentupdate":
  107. sess.Desc("updated")
  108. case "leastupdate":
  109. sess.Asc("updated")
  110. case "mostcomment":
  111. sess.Desc("num_comments")
  112. case "leastcomment":
  113. sess.Asc("num_comments")
  114. default:
  115. sess.Desc("created")
  116. }
  117. var issues []Issue
  118. err := sess.Find(&issues)
  119. return issues, err
  120. }
  121. // GetUserIssueCount returns the number of issues that were created by given user in repository.
  122. func GetUserIssueCount(userId, repoId int64) int64 {
  123. count, _ := orm.Where("poster_id=?", userId).And("repo_id=?", repoId).Count(new(Issue))
  124. return count
  125. }
  126. // UpdateIssue updates information of issue.
  127. func UpdateIssue(issue *Issue) error {
  128. _, err := orm.Id(issue.Id).AllCols().Update(issue)
  129. return err
  130. }
  131. // Label represents a list of labels of repository for issues.
  132. type Label struct {
  133. Id int64
  134. RepoId int64 `xorm:"index"`
  135. Names string
  136. Colors string
  137. }
  138. // Milestone represents a milestone of repository.
  139. type Milestone struct {
  140. Id int64
  141. Name string
  142. RepoId int64 `xorm:"index"`
  143. IsClosed bool
  144. Content string
  145. NumIssues int
  146. DueDate time.Time
  147. Created time.Time `xorm:"created"`
  148. }
  149. // Issue types.
  150. const (
  151. IT_PLAIN = iota // Pure comment.
  152. IT_REOPEN // Issue reopen status change prompt.
  153. IT_CLOSE // Issue close status change prompt.
  154. )
  155. // Comment represents a comment in commit and issue page.
  156. type Comment struct {
  157. Id int64
  158. Type int
  159. PosterId int64
  160. Poster *User `xorm:"-"`
  161. IssueId int64
  162. CommitId int64
  163. Line int64
  164. Content string
  165. Created time.Time `xorm:"created"`
  166. }
  167. // CreateComment creates comment of issue or commit.
  168. func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType int, content string) error {
  169. sess := orm.NewSession()
  170. defer sess.Close()
  171. sess.Begin()
  172. if _, err := orm.Insert(&Comment{PosterId: userId, Type: cmtType, IssueId: issueId,
  173. CommitId: commitId, Line: line, Content: content}); err != nil {
  174. sess.Rollback()
  175. return err
  176. }
  177. // Check comment type.
  178. switch cmtType {
  179. case IT_PLAIN:
  180. rawSql := "UPDATE `issue` SET num_comments = num_comments + 1 WHERE id = ?"
  181. if _, err := sess.Exec(rawSql, issueId); err != nil {
  182. sess.Rollback()
  183. return err
  184. }
  185. case IT_REOPEN:
  186. rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues - 1 WHERE id = ?"
  187. if _, err := sess.Exec(rawSql, repoId); err != nil {
  188. sess.Rollback()
  189. return err
  190. }
  191. case IT_CLOSE:
  192. rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues + 1 WHERE id = ?"
  193. if _, err := sess.Exec(rawSql, repoId); err != nil {
  194. sess.Rollback()
  195. return err
  196. }
  197. }
  198. return sess.Commit()
  199. }
  200. // GetIssueComments returns list of comment by given issue id.
  201. func GetIssueComments(issueId int64) ([]Comment, error) {
  202. comments := make([]Comment, 0, 10)
  203. err := orm.Asc("created").Find(&comments, &Comment{IssueId: issueId})
  204. return comments, err
  205. }