Slick 2.0 Generic CRUD operations Slick 2.0 Generic CRUD operations postgresql postgresql

Slick 2.0 Generic CRUD operations


I managed to make it work, this is my generic trait:

import scala.slick.driver.PostgresDriverimport scala.slick.driver.PostgresDriver.simple._import path.to.RichTabletrait PostgresGeneric[T <: RichTable[A], A] {  val tableReference: TableQuery[T]  def insert(row: T#TableElementType)(implicit s: Session) =     tableReference.insert(row)  def insertAndGetId(row: T#TableElementType)(implicit s: Session) =     (tableReference returning tableReference.map(_.id)) += row  def deleteById(id: Long)(implicit s: Session): Boolean =     tableReference.filter(_.id === id).delete == 1  def updateById(id: Long, row: T#TableElementType)(implicit s: Session): Boolean =     tableReference.filter(_.id === id).update(row) == 1  def selectById(id: Long)(implicit s: Session): Option[T#TableElementType] =     tableReference.filter(_.id === id).firstOption  def existsById(id: Long)(implicit s: Session): Boolean = {    (for {      row <- tableReference      if row.id === id    } yield row).firstOption.isDefined  }}

Where RichTable is an abstract class with an id field, this, with the upper bound constraint is useful to get the id field of T#TableElementType (see this for more info):

import scala.slick.driver.PostgresDriver.simple._import scala.slick.jdbc.{GetResult => GR}abstract class RichTable[T](tag: Tag, name: String) extends Table[T](tag, name) {  val id: Column[Long] = column[Long]("id", O.PrimaryKey, O.AutoInc)}

And my campaign table now looks like this:

import scala.slick.driver.PostgresDriver.simple._import scala.slick.jdbc.{GetResult => GR}import scala.slick.lifted.TableQuerycase class CampaignRow(id: Long, name: Option[String])class Campaign(tag: Tag) extends RichTable[CampaignRow](tag, "campaign") {  def * = (id, name) <>(CampaignRow.tupled, CampaignRow.unapply)  def ? = (id.?, name).shaped.<>({    r => import r._; _1.map(_ => CampaignRow.tupled((_1.get, _2)))  }, (_: Any) => throw new Exception("Inserting into ? projection not supported."))  override val id: Column[Long] = column[Long]("id", O.AutoInc, O.PrimaryKey)  val name: Column[Option[String]] = column[Option[String]]("name")}

The model implementing the generic trait looks like this:

 object CampaignModel extends PostgresGeneric[Campaign, CampaignRow] {   override val tableReference: PostgresDriver.simple.TableQuery[Tables.Campaign] =      TableQuery[Campaign]   def insertCampaign(row: CampaignRow) = {     insert(CampaignRow(0, "test"))   } }