Newer
Older
gitbucket_jkp / src / main / scala / service / RepositoryService.scala
@takezoe takezoe on 8 Oct 2013 10 KB Resolve length issue in Slick.
  1. package service
  2.  
  3. import model._
  4. import scala.slick.driver.H2Driver.simple._
  5. import Database.threadLocalSession
  6. import util.JGitUtil
  7.  
  8. trait RepositoryService { self: AccountService =>
  9. import RepositoryService._
  10.  
  11. /**
  12. * Creates a new repository.
  13. *
  14. * @param repositoryName the repository name
  15. * @param userName the user name of the repository owner
  16. * @param description the repository description
  17. * @param isPrivate the repository type (private is true, otherwise false)
  18. * @param originRepositoryName specify for the forked repository. (default is None)
  19. * @param originUserName specify for the forked repository. (default is None)
  20. */
  21. def createRepository(repositoryName: String, userName: String, description: Option[String], isPrivate: Boolean,
  22. originRepositoryName: Option[String] = None, originUserName: Option[String] = None,
  23. parentRepositoryName: Option[String] = None, parentUserName: Option[String] = None): Unit = {
  24. Repositories insert
  25. Repository(
  26. userName = userName,
  27. repositoryName = repositoryName,
  28. isPrivate = isPrivate,
  29. description = description,
  30. defaultBranch = "master",
  31. registeredDate = currentDate,
  32. updatedDate = currentDate,
  33. lastActivityDate = currentDate,
  34. originUserName = originUserName,
  35. originRepositoryName = originRepositoryName,
  36. parentUserName = parentUserName,
  37. parentRepositoryName = parentRepositoryName)
  38.  
  39. IssueId insert (userName, repositoryName, 0)
  40. }
  41.  
  42. def deleteRepository(userName: String, repositoryName: String): Unit = {
  43. Activities .filter(_.byRepository(userName, repositoryName)).delete
  44. CommitLog .filter(_.byRepository(userName, repositoryName)).delete
  45. Collaborators .filter(_.byRepository(userName, repositoryName)).delete
  46. IssueLabels .filter(_.byRepository(userName, repositoryName)).delete
  47. Labels .filter(_.byRepository(userName, repositoryName)).delete
  48. IssueComments .filter(_.byRepository(userName, repositoryName)).delete
  49. Issues .filter(_.byRepository(userName, repositoryName)).delete
  50. PullRequests .filter(_.byRepository(userName, repositoryName)).delete
  51. IssueId .filter(_.byRepository(userName, repositoryName)).delete
  52. Milestones .filter(_.byRepository(userName, repositoryName)).delete
  53. WebHooks .filter(_.byRepository(userName, repositoryName)).delete
  54. Repositories .filter(_.byRepository(userName, repositoryName)).delete
  55. }
  56.  
  57. /**
  58. * Returns the repository names of the specified user.
  59. *
  60. * @param userName the user name of repository owner
  61. * @return the list of repository names
  62. */
  63. def getRepositoryNamesOfUser(userName: String): List[String] =
  64. Query(Repositories) filter(_.userName is userName.bind) map (_.repositoryName) list
  65.  
  66. /**
  67. * Returns the specified repository information.
  68. *
  69. * @param userName the user name of the repository owner
  70. * @param repositoryName the repository name
  71. * @param baseUrl the base url of this application
  72. * @return the repository information
  73. */
  74. def getRepository(userName: String, repositoryName: String, baseUrl: String): Option[RepositoryInfo] = {
  75. (Query(Repositories) filter { t => t.byRepository(userName, repositoryName) } firstOption) map { repository =>
  76. // for getting issue count and pull request count
  77. val issues = Query(Issues).filter { t =>
  78. t.byRepository(repository.userName, repository.repositoryName) && (t.closed is false.bind)
  79. }.map(_.pullRequest).list
  80.  
  81. new RepositoryInfo(
  82. JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName, baseUrl),
  83. repository,
  84. issues.size,
  85. issues.filter(_ == true).size,
  86. getForkedCount(
  87. repository.originUserName.getOrElse(repository.userName),
  88. repository.originRepositoryName.getOrElse(repository.repositoryName)
  89. ))
  90. }
  91. }
  92.  
  93. def getUserRepositories(userName: String, baseUrl: String): List[RepositoryInfo] = {
  94. Query(Repositories).filter { t1 =>
  95. (t1.userName is userName.bind) ||
  96. (Query(Collaborators).filter { t2 => t2.byRepository(t1.userName, t1.repositoryName) && (t2.collaboratorName is userName.bind)} exists)
  97. }.sortBy(_.lastActivityDate desc).list.map{ repository =>
  98. new RepositoryInfo(
  99. JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName, baseUrl),
  100. repository,
  101. getForkedCount(
  102. repository.originUserName.getOrElse(repository.userName),
  103. repository.originRepositoryName.getOrElse(repository.repositoryName)
  104. ))
  105. }
  106. }
  107.  
  108. /**
  109. * Returns the list of visible repositories for the specified user.
  110. * If repositoryUserName is given then filters results by repository owner.
  111. *
  112. * @param loginAccount the logged in account
  113. * @param baseUrl the base url of this application
  114. * @param repositoryUserName the repository owner (if None then returns all repositories which are visible for logged in user)
  115. * @return the repository information which is sorted in descending order of lastActivityDate.
  116. */
  117. def getVisibleRepositories(loginAccount: Option[Account], baseUrl: String, repositoryUserName: Option[String] = None): List[RepositoryInfo] = {
  118. (loginAccount match {
  119. // for Administrators
  120. case Some(x) if(x.isAdmin) => Query(Repositories)
  121. // for Normal Users
  122. case Some(x) if(!x.isAdmin) =>
  123. Query(Repositories) filter { t => (t.isPrivate is false.bind) ||
  124. (Query(Collaborators).filter { t2 => t2.byRepository(t.userName, t.repositoryName) && (t2.collaboratorName is x.userName.bind)} exists)
  125. }
  126. // for Guests
  127. case None => Query(Repositories) filter(_.isPrivate is false.bind)
  128. }).filter { t =>
  129. repositoryUserName.map { userName => t.userName is userName.bind } getOrElse ConstColumn.TRUE
  130. }.sortBy(_.lastActivityDate desc).list.map{ repository =>
  131. new RepositoryInfo(
  132. JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName, baseUrl),
  133. repository,
  134. getForkedCount(
  135. repository.originUserName.getOrElse(repository.userName),
  136. repository.originRepositoryName.getOrElse(repository.repositoryName)
  137. ))
  138. }
  139. }
  140.  
  141. /**
  142. * Updates the last activity date of the repository.
  143. */
  144. def updateLastActivityDate(userName: String, repositoryName: String): Unit =
  145. Repositories.filter(_.byRepository(userName, repositoryName)).map(_.lastActivityDate).update(currentDate)
  146. /**
  147. * Save repository options.
  148. */
  149. def saveRepositoryOptions(userName: String, repositoryName: String,
  150. description: Option[String], defaultBranch: String, isPrivate: Boolean): Unit =
  151. Repositories.filter(_.byRepository(userName, repositoryName))
  152. .map { r => r.description.? ~ r.defaultBranch ~ r.isPrivate ~ r.updatedDate }
  153. .update (description, defaultBranch, isPrivate, currentDate)
  154.  
  155. /**
  156. * Add collaborator to the repository.
  157. *
  158. * @param userName the user name of the repository owner
  159. * @param repositoryName the repository name
  160. * @param collaboratorName the collaborator name
  161. */
  162. def addCollaborator(userName: String, repositoryName: String, collaboratorName: String): Unit =
  163. Collaborators insert(Collaborator(userName, repositoryName, collaboratorName))
  164.  
  165. /**
  166. * Remove collaborator from the repository.
  167. *
  168. * @param userName the user name of the repository owner
  169. * @param repositoryName the repository name
  170. * @param collaboratorName the collaborator name
  171. */
  172. def removeCollaborator(userName: String, repositoryName: String, collaboratorName: String): Unit =
  173. Collaborators.filter(_.byPrimaryKey(userName, repositoryName, collaboratorName)).delete
  174.  
  175. /**
  176. * Remove all collaborators from the repository.
  177. *
  178. * @param userName the user name of the repository owner
  179. * @param repositoryName the repository name
  180. */
  181. def removeCollaborators(userName: String, repositoryName: String): Unit =
  182. Collaborators.filter(_.byRepository(userName, repositoryName)).delete
  183.  
  184. /**
  185. * Returns the list of collaborators name which is sorted with ascending order.
  186. *
  187. * @param userName the user name of the repository owner
  188. * @param repositoryName the repository name
  189. * @return the list of collaborators name
  190. */
  191. def getCollaborators(userName: String, repositoryName: String): List[String] =
  192. Query(Collaborators).filter(_.byRepository(userName, repositoryName)).sortBy(_.collaboratorName).map(_.collaboratorName).list
  193.  
  194. def hasWritePermission(owner: String, repository: String, loginAccount: Option[Account]): Boolean = {
  195. loginAccount match {
  196. case Some(a) if(a.isAdmin) => true
  197. case Some(a) if(a.userName == owner) => true
  198. case Some(a) if(getCollaborators(owner, repository).contains(a.userName)) => true
  199. case _ => false
  200. }
  201. }
  202.  
  203. private def getForkedCount(userName: String, repositoryName: String): Int =
  204. Query(Repositories.filter { t =>
  205. (t.originUserName is userName.bind) && (t.originRepositoryName is repositoryName.bind)
  206. }.length).first
  207.  
  208.  
  209. def getForkedRepositories(userName: String, repositoryName: String): List[String] =
  210. Query(Repositories).filter { t =>
  211. (t.originUserName is userName.bind) && (t.originRepositoryName is repositoryName.bind)
  212. }
  213. .sortBy(_.userName asc).map(_.userName).list
  214.  
  215. }
  216.  
  217. object RepositoryService {
  218.  
  219. case class RepositoryInfo(owner: String, name: String, url: String, repository: Repository,
  220. issueCount: Int, pullCount: Int, commitCount: Int, forkedCount: Int,
  221. branchList: List[String], tags: List[util.JGitUtil.TagInfo]){
  222.  
  223. /**
  224. * Creates instance with issue count and pull request count.
  225. */
  226. def this(repo: JGitUtil.RepositoryInfo, model: Repository, issueCount: Int, pullCount: Int, forkedCount: Int) =
  227. this(repo.owner, repo.name, repo.url, model, issueCount, pullCount, repo.commitCount, forkedCount, repo.branchList, repo.tags)
  228.  
  229. /**
  230. * Creates instance without issue count and pull request count.
  231. */
  232. def this(repo: JGitUtil.RepositoryInfo, model: Repository, forkedCount: Int) =
  233. this(repo.owner, repo.name, repo.url, model, 0, 0, repo.commitCount, forkedCount, repo.branchList, repo.tags)
  234. }
  235.  
  236. case class RepositoryTreeNode(owner: String, name: String, children: List[RepositoryTreeNode])
  237.  
  238. }