paulmdavies
paulmdavies

Reputation: 1288

Slick transform subset of Table Columns into a Case Class

I'm using Scala 2.10.2 and Slick 2.1.0.

I have a table which looks something a bit like this:

class MyTable( val tag : Tag ) extends Table[Int,Int,String]( tag, "coordinates" )
{
    def x = column[Int]( "x" )
    def y = column[Int]( "y" )
    def data = column[String]( "data" )

    def * = ( x, y, data )
}

Now, I've created a case class:

case class Coordinate( val x : Int, val y : Int )

I'd like to change my table definition to something like the following:

class MyTable( val tag : Tag ) extends Table[Coordinate,String]( tag, "coordinates" )
{
    def x = column[Int]( "x" )
    def y = column[Int]( "y" )
    def data = column[String]( "data" )

    def * = ( Coordinate( x, y ), data )
}

However, this doesn't work, because x in the definition of * is a Column[Int] rather than an Int. I know you can provide a transformation between all of the columns of your table and a case class, is there a way to just convert some of the columns as I'd like to here?

Thanks.

Upvotes: 2

Views: 748

Answers (1)

tuxdna
tuxdna

Reputation: 8487

You can try this:

import play.api.db.slick.Config.driver.simple._
import scala.slick.lifted.Tag

case class Coordinate(val x: Int, val y: Int)

class MyTable(val tag: Tag) extends Table[(Coordinate, String)](tag, "coordinates") {
  def x = column[Int]("x")
  def y = column[Int]("y")
  def data = column[String]("data")

  def * = (x, y, data).shaped <> ({
    case (x, y, data) => (Coordinate(x, y), data)
  }, { ct: Tuple2[Coordinate, String] =>
    Some(ct._1.x, ct._1.y, ct._2)
  })
}

object Coordinates {

  val mytable = TableQuery[MyTable]

  def insert(ct: (Coordinate, String))(implicit session: Session) = {
    mytable.insert(ct)
  }

  def search(x: Int, y: Int)(implicit session: Session): Option[(Coordinate, String)] = {
    mytable.where(_.x === x).where(_.y === y).firstOption
  }

}

Upvotes: 2

Related Questions