Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subtype for a table element in a Scala Slick Query

Tags:

scala

slick

I'm trying to modify a trait that I have that is used for Scala Slick database queries. Here is two methods that I have so far:

protected def findByPrimaryKey(id: PrimaryKeyType): Query[Table[_], T, Seq]

/**
 * return the row that corresponds with this record
 * @param t - the row to find
 * @return query - the sql query to find this record
 */

protected def find(t: T): Query[Table[_], T, Seq]

I want to modify these two method signatures to allow for subtypes of T. An instance of this is if I have a trait definition for a record, but need a concrete implementation of that trait to actually use for slick. I've tried doing something like this:

/**
 * return all rows that have a certain primary key
 * @param id
 * @return Query object corresponding to the selected rows
 */
protected def findByPrimaryKey(id: PrimaryKeyType): Query[Table[_], _ <: T, Seq]

/**
 * return the row that corresponds with this record
 * @param t - the row to find
 * @return query - the sql query to find this record
 */

protected def find(t: T): Query[Table[_], _ <: T, Seq]

however I get a compilation error as follows:

[error]  found   : slick.driver.PostgresDriver.simple.Query[slick.driver.PostgresDriver.simple.Table[_],_$8,Seq] where type _$8 <: T
[error]     (which expands to)  scala.slick.lifted.Query[slick.driver.PostgresDriver.Table[_],_$8,Seq]
[error]  required: slick.driver.PostgresDriver.simple.Query[slick.driver.PostgresDriver.simple.Table[_],T,Seq]
[error]     (which expands to)  scala.slick.lifted.Query[slick.driver.PostgresDriver.Table[_],T,Seq]
[error] Note: _$8 <: T, but class Query is invariant in type U.
[error] You may wish to investigate a wildcard type such as `_ <: T`. (SLS 3.2.10)
[error]         val query: Query[Table[_], T, Seq] = find(t)
[error]                                                  ^
[error] /home/chris/dev/suredbits-core/src/main/scala/com/suredbits/core/db/CRUDActor.scala:58: type mismatch;
[error]  found   : slick.driver.PostgresDriver.simple.Query[slick.driver.PostgresDriver.simple.Table[_],_$8,Seq] where type _$8 <: T
[error]     (which expands to)  scala.slick.lifted.Query[slick.driver.PostgresDriver.Table[_],_$8,Seq]
[error]  required: slick.driver.PostgresDriver.simple.Query[slick.driver.PostgresDriver.simple.Table[_],T,Seq]
[error]     (which expands to)  scala.slick.lifted.Query[slick.driver.PostgresDriver.Table[_],T,Seq]
[error] Note: _$8 <: T, but class Query is invariant in type U.
[error] You may wish to investigate a wildcard type such as `_ <: T`. (SLS 3.2.10)
[error]         val query: Query[Table[_], T, Seq] = find(t)
[error]                                                  ^

and I am unsure of what to do to get the outcome that I want.

like image 905
Chris Stewart Avatar asked Aug 19 '15 19:08

Chris Stewart


1 Answers

Ideally, you should make Query variant with T. But since that is out of your control, you could do it like this (it should work):

protected def find[U <: T](t: U): Query[Table[_], U, Seq]

But I sense you are dealing with a bigger problem here. Why do you need such abstraction? What is your class design?

like image 173
Rok Kralj Avatar answered Nov 05 '22 09:11

Rok Kralj