好的,所以我想创建一个HListCaseClassShape,让我创建克服22个arity限制的case类。所以,从Stefan Zeiger的代码here开始。
final class HListShape[Level <: ShapeLevel, M <: HList, U <: HList : ClassTag, P <: HList](val shapes: Seq[Shape[_, _, _, _]]) extends MappedScalaProductShape[Level, HList, M, U, P] {
def buildValue(elems: IndexedSeq[Any]) = elems.foldRight(HNil: HList)(_ :: _)
def copy(shapes: Seq[Shape[_ <: ShapeLevel, _, _, _]]) = new HListShape(shapes)
}
implicit def hnilShape[Level <: ShapeLevel] = new HListShape[Level, HNil.type, HNil.type, HNil.type](Nil)
implicit def hconsShape[Level <: ShapeLevel, M1, M2 <: HList, U1, U2 <: HList, P1, P2 <: HList](implicit s1: Shape[_ <: Level, M1, U1, P1], s2: HListShape[_ <: Level, M2, U2, P2]) =
new HListShape[Level, M1 :: M2, U1 :: U2, P1 :: P2](s1 +: s2.shapes)
然后我继续创建我的HListCaseClassShape:
class HListCaseClassShape[P <: Product, LiftedList, LiftedCaseClass <: P, PlainList, PlainCaseClass <: P](
mapLifted: LiftedList => LiftedCaseClass, mapPlain: PlainList => PlainCaseClass)(
implicit columnShapes: Shape[FlatShapeLevel, LiftedList, PlainList, LiftedList], classTag: ClassTag[PlainCaseClass])
extends MappedScalaProductShape[FlatShapeLevel, P, LiftedCaseClass, PlainCaseClass, LiftedCaseClass] {
val shapes = columnShapes.asInstanceOf[HListShape[_,_,_,_]].shapes
override def toMapped(v: Any) = {
val folded = v.asInstanceOf[Product].productIterator.foldRight(HNil: HList)(_ :: _)
folded.asInstanceOf[PlainList]
}
def buildValue(elems: IndexedSeq[Any]) = {
val list = elems.foldRight(HNil: HList)(_ :: _)
mapLifted(list.asInstanceOf[LiftedList])
}
def copy(s: Seq[Shape[_ <: ShapeLevel, _, _, _]]) = new HListCaseClassShape(mapLifted, mapPlain) { override val shapes = s }
}
最后,我尝试将其实例化
case class LiftedB(data1: Rep[String], data2: Rep[String], data3: Rep[String], data4: Rep[String], data5: Rep[String], data6: Rep[String], data7: Rep[String], data8: Rep[String], data9: Rep[String], data10: Rep[String], data11: Rep[String], data12: Rep[String], data13: Rep[String], data14: Rep[String], data15: Rep[String], data16: Rep[String], data17: Rep[String], data18: Rep[String], data19: Rep[String], data20: Rep[String], data21: Rep[String], data22: Rep[String], data23: Rep[String], data24: Rep[String], data25: Rep[String])
case class B(data1: String, data2: String, data3: String, data4: String, data5: String, data6: String, data7: String, data8: String, data9: String, data10: String, data11: String, data12: String, data13: String, data14: String, data15: String, data16: String, data17: String, data18: String, data19: String, data20: String, data21: String, data22: String, data23: String, data24: String, data25: String )
...然后是形状:
type DirectConsList = HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HNil]]]]]]]]]]]]]]]]]]]]]]]]]
type LiftedConsList = HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HNil]]]]]]]]]]]]]]]]]]]]]]]]]
implicit object BShape extends HListCaseClassShape[
Product,
LiftedConsList,
LiftedB,
DirectConsList,
B](toLifted, toDirect)
def toLifted(list: LiftedConsList) = {
list match {
case data1 :: data2 :: data3 :: data4 :: data5 :: data6 :: data7 :: data8 :: data9 :: data10 :: data11 :: data12 :: data13 :: data14 :: data15 :: data16 :: data17 :: data18 :: data19 :: data20 :: data21 :: data22 :: data23 :: data24 :: data25 :: HNil => {
LiftedB(data1, data2, data3, data4, data5, data6, data7, data8, data9, data10, data11, data12, data13, data14, data15, data16, data17, data18, data19, data20, data21, data22, data23, data24, data25 )
}
case _ => throw new Exception("malformed HList")
}
}
def toDirect(list:DirectConsList) = {
list match {
case data1 :: data2 :: data3 :: data4 :: data5 :: data6 :: data7 :: data8 :: data9 :: data10 :: data11 :: data12 :: data13 :: data14 :: data15 :: data16 :: data17 :: data18 :: data19 :: data20 :: data21 :: data22 :: data23 :: data24 :: data25 :: HNil => {
B(data1, data2, data3, data4, data5, data6, data7, data8, data9, data10, data11, data12, data13, data14, data15, data16, data17, data18, data19, data20, data21, data22, data23, data24, data25 )
}
case _ => throw new Exception("malformed HList")
}
}
只有当我通过db.stream实例化并运行它才会抛出异常:
Exception in thread "main" java.lang.ClassCastException: slick.collection.heterogeneous.HCons cannot be cast to com.example.CaseClassShapeQueryExample$B
at com.example.CaseClassShapeQueryExample$$anonfun$2.apply(CaseClassShapeQueryExample.scala:106)
at slick.backend.DatabasePublisher$$anon$3$$anonfun$onNext$1.apply(DatabasePublisher.scala:48)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
所以它得到了从查询中返回的普通元组对象(即DirectConsList
),但我无法将其转换为B
对象。我做错了什么???
答案 0 :(得分:0)
在mapPlain(folded.asInstanceOf[PlainList])
方法中,我所遗漏的所有内容都是toMapped
。工作HListCaseClassShape的实现如下:
class HListCaseClassShape[P <: Product, LiftedList, LiftedCaseClass <: P, PlainList, PlainCaseClass <: P](
mapLifted: LiftedList => LiftedCaseClass, mapPlain: PlainList => PlainCaseClass)(
implicit columnShapes: Shape[FlatShapeLevel, LiftedList, PlainList, LiftedList], classTag: ClassTag[PlainCaseClass])
extends MappedScalaProductShape[FlatShapeLevel, P, LiftedCaseClass, PlainCaseClass, LiftedCaseClass] {
val shapes = columnShapes.asInstanceOf[HListShape[_,_,_,_]].shapes
override def toMapped(v: Any) = {
val folded = v.asInstanceOf[Product].productIterator.foldRight(HNil: HList)(_ :: _)
mapPlain(folded.asInstanceOf[PlainList])
}
def buildValue(elems: IndexedSeq[Any]) = {
val list = elems.foldRight(HNil: HList)(_ :: _)
mapLifted(list.asInstanceOf[LiftedList])
}
def copy(s: Seq[Shape[_ <: ShapeLevel, _, _, _]]) = new HListCaseClassShape(mapLifted, mapPlain) { override val shapes = s }
}
另外,要点:Apple's docs。