Skip to content

Instantly share code, notes, and snippets.

@Bunyod
Created October 27, 2016 07:27
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Bunyod/34d7df43d812f7dc2fdca58de0d06c3f to your computer and use it in GitHub Desktop.
Save Bunyod/34d7df43d812f7dc2fdca58de0d06c3f to your computer and use it in GitHub Desktop.
Slick one to many and grouping
object Entities {
case class Review(txt: String, userId: Long, id: Long)
case class User(name: String, id: Long)
case class ReviewEvent(event: String, reviewId: Long)
case class FullReview(r: Review, user: User, evts: Seq[ReviewEvent])
}
import javax.inject.{Inject, Singleton}
import Entities.{FullReview, Review}
import com.google.inject.ImplementedBy
import com.typesafe.scalalogging.slf4j.LazyLogging
import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider}
import slick.driver.JdbcProfile
import scala.concurrent.Future
trait ReviewsComponent
extends UsersComponent
{ self: HasDatabaseConfigProvider[JdbcProfile] =>
import driver.api._
class Reviews(tag: Tag) extends Table[Review](tag, "reviews") {
val users = TableQuery[Users]
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def userId = column[Int]("userId")
def txt = column[String]("txt")
def * = (id, userId, txt) <> (Review.tupled, Review.unapply)
def user = foreignKey("reviews_fk_user_id", userId, users)(_.id)
}
}
@ImplementedBy(classOf[ReviewsDaoImpl])
trait ReviewsDao {
def findAllReviews(): Future[Seq[FullReview]]
}
@Singleton
class ReviewsDaoImpl @Inject() (protected val dbConfigProvider: DatabaseConfigProvider)
extends HasDatabaseConfigProvider[JdbcProfile]
with ReviewsComponent
with ReviewsDao
with ReviewEventsComponent
with LazyLogging {
import driver.api._
val users = TableQuery[Users]
val reviews = TableQuery[Reviews]
val events = TableQuery[ReviewEvents]
override def findAllReviews(): Future[Seq[FullReview]] = {
val query = reviews
.join(users).on(_.userId === _.id)
.joinLeft(events).on(_._1.id === _.reviewId)
db.run(query.result).map { a =>
a.groupBy(_._1._1.id).map { case (_, tuples) =>
val ((review, user), _) = tuples.head
val reviewEvents = tuples.flatMap(_._2)
FullReview(review, user, reviewEvents)
}.toSeq
}
}
}
import javax.inject.{Inject, Singleton}
import Entities.{ReviewEvent, User}
import com.google.inject.ImplementedBy
import com.typesafe.scalalogging.slf4j.LazyLogging
import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider}
import slick.driver.JdbcProfile
import scala.concurrent.Future
trait ReviewEventsComponent
extends ReviewsComponent
{ self: HasDatabaseConfigProvider[JdbcProfile] =>
import driver.api._
class ReviewEvents(tag: Tag) extends Table[ReviewEvent](tag, "events"){
val reviews = TableQuery[Reviews]
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def event = column[String]("event")
def reviewId = column[Int]("reviewId")
def * = (id, event, reviewId) <> (ReviewEvent.tupled, ReviewEvent.unapply)
def review = foreignKey("events_fk_review_id", reviewId, reviews)(_.id)
}
}
@ImplementedBy(classOf[ReviewEventsDaoImpl])
trait ReviewEventsDao {
def findAllEvents(): Future[Seq[ReviewEvent]]
}
@Singleton
class ReviewEventsDaoImpl @Inject() (protected val dbConfigProvider: DatabaseConfigProvider)
extends HasDatabaseConfigProvider[JdbcProfile]
with ReviewEventsComponent
with ReviewEventsDao
with LazyLogging {
import driver.api._
val events = TableQuery[ReviewEvents]
override def findAllEvents(): Future[Seq[ReviewEvent]] = {
db.run(events.sortBy(_.id).result)
}
}
import javax.inject.{Inject, Singleton}
import Entities.User
import com.google.inject.ImplementedBy
import com.typesafe.scalalogging.slf4j.LazyLogging
import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider}
import slick.driver.JdbcProfile
import scala.concurrent.Future
trait UsersComponent
{ self: HasDatabaseConfigProvider[JdbcProfile] =>
import driver.api._
class Users(tag: Tag) extends Table[User](tag, "users") {
val users = TableQuery[Users]
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def * = (id, name) <> (User.tupled, User.unapply)
}
}
@ImplementedBy(classOf[UsersDaoImpl ])
trait UsersDao {
def findAllUsers(): Future[Seq[User]]
}
@Singleton
class UsersDaoImpl @Inject() (protected val dbConfigProvider: DatabaseConfigProvider)
extends HasDatabaseConfigProvider[JdbcProfile]
with UsersComponent
with UsersDao
with LazyLogging {
import driver.api._
val users = TableQuery[Users]
override def findAllUsers(): Future[Seq[User]] = {
db.run(users.sortBy(_.id).result)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment