package service import scala.slick.driver.H2Driver.simple._ import Database.threadLocalSession import scala.slick.jdbc.{StaticQuery => Q} import Q.interpolation import model._ import Issues._ trait IssuesService { def getIssue(owner: String, repository: String, issueId: String) = if (issueId forall (_.isDigit)) Query(Issues) filter { t => (t.userName is owner.bind) && (t.repositoryName is repository.bind) && (t.issueId is issueId.toInt.bind) } firstOption else None def searchIssue(owner: String, repository: String, // TODO It is better to have a DTO closed: Boolean) = Query(Issues) filter { t => (t.userName is owner.bind) && (t.repositoryName is repository.bind) && (t.closed is closed.bind) } list def saveIssue(owner: String, repository: String, loginUser: String, title: String, content: Option[String]) = // next id number sql"SELECT ISSUE_ID + 1 FROM ISSUE_ID WHERE USER_NAME = $owner AND REPOSITORY_NAME = $repository FOR UPDATE".as[Int] .firstOption.filter { id => Issues insert Issue( owner, repository, id, loginUser, None, None, title, content, false, currentDate, currentDate) // increment issue id IssueId.filter { t => (t.userName is owner.bind) && (t.repositoryName is repository.bind) }.map(_.issueId).update(id) > 0 } get def createMilestone(owner: String, repository: String, title: String, description: Option[String], dueDate: Option[java.util.Date]) = Milestones.autoInc insert (owner, repository, title, description, dueDate, None) def updateMilestone(milestone: Milestone): Unit = Query(Milestones) .filter { m => (m.userName is milestone.userName.bind) && (m.repositoryName is milestone.repositoryName.bind) && (m.milestoneId is milestone.milestoneId.bind)} .map { m => m.title ~ m.description.? ~ m.dueDate.? ~ m.closedDate.? } .update ( milestone.title, milestone.description, milestone.dueDate, milestone.closedDate) def deleteMilestone(owner: String, repository: String, milestoneId: Int): Unit = { Query(Issues) .filter { i => (i.userName is owner.bind) && (i.repositoryName is repository.bind) && (i.milestoneId is milestoneId.bind)} .map { i => i.milestoneId.? } .update(None) Query(Milestones) .filter { i => (i.userName is owner.bind) && (i.repositoryName is repository.bind) && (i.milestoneId is milestoneId.bind)} .delete } def getMilestone(owner: String, repository: String, milestoneId: Int): Option[Milestone] = Query(Milestones) .filter(m => (m.userName is owner.bind) && (m.repositoryName is repository.bind) && (m.milestoneId is milestoneId.bind)) .sortBy(_.milestoneId desc) .firstOption def getMilestoneIssueCounts(owner: String, repository: String): Map[(Int, Boolean), Int] = { import scala.slick.jdbc.{GetResult, StaticQuery} import StaticQuery.interpolation case class IssueCount(userName: String, repositoryName: String, milestoneId: Int, closed: Boolean, count: Int) implicit val getIssueCount = GetResult(r => IssueCount(r.<<, r.<<, r.<<, r.<<, r.<<)) sql""" select USER_NAME, REPOSITORY_NAME, MILESTONE_ID, CLOSED, COUNT(ISSUE_ID) from ISSUE where USER_NAME = $owner AND REPOSITORY_NAME = $repository AND MILESTONE_ID IS NOT NULL group by USER_NAME, REPOSITORY_NAME, MILESTONE_ID, CLOSED""" .as[IssueCount] .list .map { x => (x.milestoneId, x.closed) -> x.count } .toMap } def getMilestones(owner: String, repository: String): List[Milestone] = Query(Milestones) .filter(m => (m.userName is owner.bind) && (m.repositoryName is repository.bind)) .sortBy(_.milestoneId desc) .list }