Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicit GetResult for nested classes in Slick

Tags:

scala

slick

From what I've read, there is a way to work with nested classes to solve the problem of tables with more than 22 fields. It looks like this (with a simple table):

case class UserRow(id:Int, address1:Address, address2:Address)
case class Address(street:String,city:String)

class User(tag:Tag) extends Table[UserRow](tag, "User"){
  def id = column[Int]("id", O.PrimaryKey)
  def street1 = column[String]("STREET1")
  def city1 = column[String]("CITY1")
  def street2 = column[String]("STREET2")
  def city2 = column[String]("CITY2")
  def * = (id, address1, address2) <> (UserRow.tupled, UserRow.unapply)
  def address1 = (street1, city1) <> (Address.tupled, Address.unapply)
  def address2 = (street2, city2) <> (Address.tupled, Address.unapply)
}

What I've realized is that plain SQL - which requires implicit values - doesn't work with this solution or at least I haven't been able to make it works.

I thought I could define the implicit values in the same way as the nested classes, like this:

implicit val getAddressResult = GetResult(r => Address(r.<<, r.<<))
implicit val getUserResult = GetResult(r => UserRow(r.<<, r.<<, r.<<))

But it doesn't work. It compiles but when running, it says that the user table is not found.

I'm very new in Scala and Slick so I could have misunderstood some information or have some wrong concepts. What am I doing wrong?

UPDATE

This is what I'm doing in the test:

user.ddl.create
user += UserRow(0, Address("s11", "c11"), Address("s12", "c12"))
user += UserRow(1, Address("s21", "c21"), Address("s22", "c22"))
user += UserRow(2, Address("s31", "c31"), Address("s32", "c32"))
println(user.list)
val sqlPlain = sql"SELECT * FROM user".as[UserRow]
println(sqlPlain)
println(sqlPlain.list)

All of it works until the last sentence where I get the error "Table "USER" not found". Also the exact same test works perfect for a non nested case class.

UPDATE 2

As cvogt has correctly indicated to me, I was misunderstanding the error reported and it wasn't related to the implicit GetResult values. His answer is correct as well as my first approach.

like image 243
Henry Vonfire Avatar asked Feb 11 '15 09:02

Henry Vonfire


1 Answers

Pass the PositionedResult r to the corresponding GetResult objects:

implicit val getAddressResult = GetResult(r => Address(r.<<, r.<<))
implicit val getUserResult =
  GetResult(r => UserRow(r.<<, getAddressResult(r), getAddressResult(r)))
like image 64
cvogt Avatar answered Nov 01 '22 07:11

cvogt