I am having issues in mapping a Table that has > 22 columns specifically into a case class
, assuming you have the following code
import slick.driver.PostgresDriver
import scala.slick.collection.heterogenous._
import syntax._
import shapeless.Generic
case class TwentyThreeCaseClass(
val id:Option[Long],
val one:String,
val two:String,
val three:String,
val four:String,
val five:String,
val six:String,
val seven:String,
val eight:String,
val nine:String,
val ten:String,
val eleven:String,
val twelve:String,
val thirteen:String,
val fourteen:String,
val fifteen:String,
val sixteen:String,
val seventeen:String,
val eighteen:String,
val nineteen:String,
val twenty:String,
val twentyOne:String,
val twentyTwo:String,
val twentyThree:String,
val twentyFour:String
)
class TwentyThreeTable(tag:Tag) extends Table[TwentyThreeCaseClass](tag,"twenty_three_table") {
def id = column[Long]("id",O.PrimaryKey,O.AutoInc)
def one = column[String]("one")
def two = column[String]("two")
def three = column[String]("three")
def four = column[String]("four")
def five = column[String]("five")
def six = column[String]("six")
def seven = column[String]("seven")
def eight = column[String]("eight")
def nine = column[String]("nine")
def ten = column[String]("ten")
def eleven = column[String]("eleven")
def twelve = column[String]("twelve")
def thirteen = column[String]("thirteen")
def fourteen = column[String]("fourteen")
def fifteen = column[String]("fifteen")
def sixteen = column[String]("sixteen")
def seventeen = column[String]("seventeen")
def eighteen = column[String]("eighteen")
def nineteen = column[String]("nineteen")
def twenty = column[String]("twenty")
def twentyOne = column[String]("twentyOne")
def twentyTwo = column[String]("twentyTwo")
def twentyThree = column[String]("twentyThree")
def twentyFour = column[String]("twentyFour")
private def iso[L <: HList, M <: HList](l: L)
(implicit iso: Generic.Aux[TwentyThreeCaseClass, M], eq: L =:= M): TwentyThreeCaseClass = iso.from(l)
def * =
id.? ::
one ::
two ::
three ::
four ::
five ::
six ::
seven ::
eight ::
nine ::
ten ::
elven ::
twelve ::
thirteen ::
fourteen ::
fifteen ::
sixteen ::
seventeen ::
eighteen ::
nineteen ::
twenty ::
twentyOne ::
twentyTwo ::
twentyThree ::
twentyFour ::
HNil
// Do stuff here to map to a case class
}
How exactly would you go about constructing/extracting the table into the TwentyThreeCaseClass
. Example code is given on how to make a slick Table
map to a HList, but code is not given on how to map a Table to a case class > 22 parameters via a HList
(you can't use tuples, because the arity limit in Scala still applies for tuples, you can't make a tuple with more then twenty two elements)
The iso
is there, because we use this generic iso code to map from a HList
to a case class
with the same shape in our shapeless code outside of slick, so theoretically speaking you should be able to use iso to construct the case class from the HList
, i just have no idea how to use iso in the context of slick shapes
EDIT: There is the same question asked on the slick github as an issue here https://github.com/slick/slick/issues/519#issuecomment-48327043
Figured it out, its pretty ugly though since its not generic.
def * =
(id.? ::
one ::
two ::
three ::
four ::
five ::
six ::
seven ::
eight ::
nine ::
ten ::
elven ::
twelve ::
thirteen ::
fourteen ::
fifteen ::
sixteen ::
seventeen ::
eighteen ::
nineteen ::
twenty ::
twentyOne ::
twentyTwo ::
twentyThree ::
twentyFour ::
HNil).shaped <>
({case x => TwentyThreeCaseClass(
x(0),
x(1),
x(2),
x(3),
x(4),
x(5),
x(6),
x(7),
x(8),
x(9),
x(10),
x(11),
x(12),
x(13),
x(14),
x(15),
x(16),
x(17),
x(18),
x(19),
x(20),
x(21),
x(22),
x(23),
x(24)
)}, ({x:TwentyThreeCaseClass =>
Option((
x.id ::
x.one ::
x.two ::
x.three ::
x.four ::
x.five ::
x.six ::
x.seven ::
x.eight ::
x.nine ::
x.ten ::
x.eleven ::
x.twelve ::
x.thirteen ::
x.fourteen ::
x.fifteen ::
x.sixteen ::
x.seventeen ::
x.eighteen ::
x.nineteen ::
x.twenty ::
x.twentyOne ::
x.twentyTwo ::
x.twentyThree ::
x.twentyFour ::
HNil
))
}))
It turns out there are a few things
HList
implementation (which has the exact same syntax as shapeless!)HList
doesn't appear to have any generic methods for dealing with stuff like mapping to a case class
(and going from a case class to a Slick `HLIst)Hlist
to a shapeless HList
would be handy, or generic abilities for Slick Hlist
. The former may be a better option because shapeless already does generic stuff much better than Slick, and it may be out of Slicks scope Doing something like
def gen = Generic[TwentyThreeCaseClass]
...
.shaped <>
({case x => gen.from(x)}, {TwentyThreeCaseClass => Option(gen.to(x))})
Would be much more ideal
here is another example as well
https://github.com/playframework/play-slick/issues/214
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With