I'm using Scala Slick-3.1.0 lib.
How is it possible to make a generic Slick filter function that takes TableQuery instance as an input and makes same slick filter on it?
I have several case classes (two for example) representing data stored in DB. Some fields are the same so classes could possibly extend common ancestor:
case class FirstData(symbol: String,
date: Timestamp,
firstField: Double)
case class SecondData(symbol: String,
date: Timestamp,
secondField: String)
Each of them has its own SQL Table in DB and is represented by separate Slick Table
class. Also they have same primary keys:
class FirstDataTable(tag: Tag) extends Table[FirstData](tag, "firstData") {
def symbol = column[String]("symbol")
def date = column[Timestamp]("date")
def firstField= column[Double]("firstField")
def * = (symbol, date, firstField) <> ((FirstData.apply _).tupled, FirstData.unapply)
def pk = primaryKey("pk_firstData", (symbol, date))
}
class SecondDataTable(tag: Tag) extends Table[SecondData](tag, "secondData"){
def symbol = column[String]("symbol")
def date = column[Timestamp]("date")
def secondField= column[String]("secondField")
def * = (symbol, date, secondField) <> ((SecondData.apply _).tupled, SecondData.unapply)
def pk = primaryKey("pk_secondData", (symbol, date))
}
Finally TableQuery
classes are:
val firstDataTableQuery = TableQuery[FirstDataTable]
val secondDataTableQuery = TableQuery[SecondDataTable]
etc ...
How is it possible to make a generic Slick filter query function that takes firstDataTableQuery
or secondDataTableQuery
as an argument and makes same slick query on input. Filtering only on their common fields or another way saying on their SQL Table representations common columns. For example like this:
def filter(genericTableQuery: TableQuery) = {
genericTableQuery.filter { data => dataFilterFunction(data.symbol)
}.filter(_.date >= someDate).sortBy(data => data.date.asc)
}
val firstTableResult = filter(firstDataTableQuery)
val seconfTableResult = filter(secondDataTableQuery)
etc ...
I looked on this topics, but still could not make up a solution:
Slick 3 reusable generic repository
Scala reflection to instantiate scala.slick.lifted.TableQuery
invariant, thanks a lot. You pointed me to the right direction. I slightly modified your answer and everything works )
Traits:
trait Data {
def symbol: String
def date: Timestamp
}
trait GenericDataTable[T <: Data] extends Table[T] {
def symbol: Rep[String]
def date: Rep[Timestamp]
def pk: PrimaryKey
}
FirstData and FirstDataTable classes look like this:
case class FirstData(
symbol: String,
date: Timestamp,
firstField: Double) extends Data
class FirstDataTable(tag: Tag) extends Table[FirstData(tag,"firstData")
with GenericDataTable[FirstData] {
def symbol = column[String]("symbol")
def date = column[Timestamp]("date")
def firstField= column[Double]("firstField")
def * = (symbol, date, firstField) <> ((FirstData.apply _).tupled, FirstData.unapply)
def pk = primaryKey("pk_firstData", (symbol, date))
}
Finally function looks like this:
private def filter[M <: Data, T <: GenericDataTable[M]] (genericTableQuery: TableQuery[T]) = {
genericTableQuery.filter { data => dataFilterFunction(data.symbol)}.
filter(_.date >= someDate).sortBy(data => data.date.asc)
}