光滑2.10-RC1,Scala 2.11.x,绕过22个arity限制与案例类(异类)

mde*_*ich 6 scala case-class shapeless slick

case class假设您有以下代码,我在将具有> 22列的表专门映射到a时遇到问题

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

}
Run Code Online (Sandbox Code Playgroud)

你究竟如何构建/提取表格TwentyThreeCaseClass.示例代码给出了如何为TableHList 制作一个光滑的映射,但没有给出关于如何通过一个映射表到一个case类> 22参数的代码HList(你不能使用元组,因为Scala中的arity限制仍然适用于元组,你不能用二十二个元素组成一个元组)

iso是存在的,因为我们使用这个通用的ISO代码从一个映射HListcase class具有相同的形状在我们无形的代码光滑的外面,所以从理论上讲,你应该能够使用ISO构建从case类HList,我只是有不知道如何在光滑的形状中使用iso

编辑:有一个问题在光滑的github上问一个问题在这里https://github.com/slick/slick/issues/519#issuecomment-48327043

mde*_*ich 8

弄清楚,它非常难看,因为它不是通用的.

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
            ))
          }))
Run Code Online (Sandbox Code Playgroud)

事实证明有一些事情

  1. 这与无形无关,Slick使用自己的HList实现(它具有与无形的完全相同的语法!)
  2. 据我所知,Slick HList似乎没有任何通用的方法来处理映射到a case class(以及从case类转到Slick`HLIst)之类的东西
  3. Eiher将Slick转换Hlist为无形的库HList将是方便的,或Slick的通用能力Hlist.前者可能是一个更好的选择,因为无形已经比Slick更好地使用通用的东西,并且它可能超出Slicks范围

做点什么

def gen = Generic[TwentyThreeCaseClass]
...
.shaped <>
      ({case x => gen.from(x)}, {TwentyThreeCaseClass => Option(gen.to(x))})
Run Code Online (Sandbox Code Playgroud)

会更加理想

这是另一个例子

https://github.com/playframework/play-slick/issues/214

  • @mdedetrich这样的代码真的让我质疑Slick是真实世界,数据库密集型应用程序的可行选择.它似乎造成混乱,并且缺少许多必需的功能(fetch-size/batch-size,乐观/悲观锁定,事务传播等......) (9认同)