列数可变的通用滑动表定义

时间:2018-08-24 21:01:03

标签: scala slick shapeless slick-3.0

在我们的应用程序中,我们有许多具有可变列数的自动生成的表。

由于我们使用slick来查询应用程序的普通关系表,因此我们认为我们也将使用slick来查询生成的表,从而使我们能够在普通表和生成的表之间使用联接,并使我们能够将已定义且有效的查询逻辑用于普通表。

生成的表具有一些预先已知的公共列(这些列将用于查询/联接),并且每个生成的表之间有许多不同的列。

我们在接线时遇到了麻烦。我们曾尝试使用slickless来构建列的HList,但是在正确使用语法和编译时遇到了麻烦。

使用当前的Scala / Slick / Slickless API和限制是否有可能实现?如果是这样,理想情况下,我们希望能够检索所有列并在查询中使用它们。但是,即使我们不能在查询中使用变化的列,我们也愿意使用slick,因为它至少可以检索所有列并填充case类。

下面是一个示例代码片段,用于显示到目前为止我们所获得的(即使它没有编译)

  // This is the case class we want to work with in our
  // application logic
  case class Row
  (
    normalColumn: String,
    allTheOtherColumns: Seq[Any]
  )

  // If we could just wire this somehow with slick, the values
  // would be correctly populated
  val ncols = 5 //This varies between the generated tables
  implicit def getResultRow: GetResult[Row] = GetResult {
    prs =>
      import prs._
      Row.tupled((
        <<[String],
        (0 until ncols).map(_ => nextObject())
      ))
  }

  // This is the slick table definition, receiving the table name
  // and the varying column names as parameters
  class RowTable
  (
    _tableTag: Tag,
    _tableName: String,
    cols: Seq[String]
  ) extends Table[Row](_tableTag, _tableName) {

    val normalColumn: Rep[String] = column[String]("normal_column")
    // The varying columns are not necessarily of Long type,
    // they can be of any type. This is just an example.
    val allTheOtherColumns: Seq[Rep[Long]] = cols.map(c => column[Long](c))

    def * = {
      val shapelessColumns = normalColumn ::
        allTheOtherColumns.reverse.
          foldLeft(HNil.asInstanceOf[HList])((a, b) => b :: a) :: HNil
      // This line here does not compile, as it complains it can't
      // find an implicit argument of type Shape.
      // We tried providing a custom one, but gave up midway as it
      // looked like we were getting too close to the Slick
      // internal API.
      shapelessColumns.mappedWith(Generic[Row])
    }
  }

0 个答案:

没有答案