Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slick 2.0: How to convert lifted query results to a case class?

Tags:

scala

slick

in order to implement a ReSTfull APIs stack, I need to convert data extracted from a DB to JSON format. I think that the best way is to extract data from the DB and then convert the row set to JSON using Json.toJson() passing as argument a case class after having defined a implicit serializer (writes).

Here's my case class and companion object:

package deals.db.interf.slick2

import scala.slick.driver.MySQLDriver.simple._
import play.api.libs.json.Json

case class PartnerInfo(
    id: Int, 
    name: String, 
    site: String, 
    largeLogo: String, 
    smallLogo: String, 
    publicationSite: String
)

object PartnerInfo {

  def toCaseClass( ?? ) = { // what type are the arguments to be passed?
    PartnerInfo( fx(??) ) // how to transform the input types (slick) to Scala types?
  }

  // Notice I'm using slick 2.0.0 RC1 
  class PartnerInfoTable(tag: Tag) extends Table[(Int, String, String, String, String, String)](tag, "PARTNER"){
        def id = column[Int]("id")
        def name = column[String]("name")
        def site = column[String]("site")
        def largeLogo = column[String]("large_logo")
        def smallLogo = column[String]("small_logo")
        def publicationSite = column[String]("publication_site")

        def * = (id, name, site, largeLogo, smallLogo, publicationSite) 
   }


  val partnerInfos = TableQuery[PartnerInfoTable]


  def qPartnerInfosForPuglisher(publicationSite: String) = { 
    for ( 
      pi <- partnerInfos if ( pi.publicationSite == publicationSite )
    ) yield toCaseClass( _ ) // Pass all the table columns to toCaseClass()
  }


  implicit val partnerInfoWrites = Json.writes[PartnerInfo]

}

What I cannot get is how to implement the toCaseClass() method in order to transform the column types from Slick 2 to Scala types - notice the function fx() in the body of toCaseClass() is only meant to give emphasis to that.

I'm wondering if is it possible to get the Scala type from Slick column type because it is clearly passed in the table definition, but I cannot find how to get it.

Any idea?

like image 457
Max Avatar asked Jan 12 '14 17:01

Max


Video Answer


1 Answers

I believe the simplest method here would be to map PartnerInfo in the table schema:

  class PartnerInfoTable(tag: Tag) extends Table[PartnerInfo](tag, "PARTNER"){
        def id = column[Int]("id")
        def name = column[String]("name")
        def site = column[String]("site")
        def largeLogo = column[String]("large_logo")
        def smallLogo = column[String]("small_logo")
        def publicationSite = column[String]("publication_site")

        def * = (id, name, site, largeLogo, smallLogo, publicationSite) <> (PartnerInfo.tupled, PartnerInfo.unapply)
   }

val partnerInfos = TableQuery[PartnerInfoTable]


  def qPartnerInfosForPuglisher(publicationSite: String) = { 
    for ( 
      pi <- partnerInfos if ( pi.publicationSite == publicationSite )
    ) yield pi
  }

Otherwise PartnerInfo.tupled should do the trick:

 def toCaseClass(pi:(Int, String, String, String, String, String)) = PartnerInfo.tupled(pi)
like image 73
vitalii Avatar answered Oct 26 '22 23:10

vitalii