В нашем приложении у нас есть много автоматически сгенерированных таблиц с переменным числом столбцов.
Поскольку мы используем slick для запросов к нормальным реляционным таблицам нашего приложения, мы решили, что мы будем использовать slick также для запросов к сгенерированным таблицам, что позволит нам использовать соединения между обычными и сгенерированными таблицами и позволит нам использование уже определенной и работающей логики запросов для обычных таблиц.
Сгенерированные таблицы имеют некоторые общие столбцы, которые известны заранее (и те, которые будут использоваться для запроса / объединения), и количество столбцов, которые различаются в каждой сгенерированной таблице.
У нас проблемы с подключением. Мы пытались использовать Slickless для построения HList столбцов, но у нас возникают проблемы с правильным синтаксисом и компиляцией.
Возможно ли это с текущими API Scala / Slick / Slickless и ограничениями? Если это так, то в идеале мы хотели бы иметь возможность извлекать все столбцы и использовать их в запросах. Однако мы были бы готовы использовать 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])
}
}