Question

I have types like A, B, C (which are not related to each other), a lazy postgresql database db (defined in an other class) and Slick 2.10 with Plain Queries; I'm kind of confused because of generics. I want to solve following:

def selectT[T](query: String, id: String): List[T] = {
    db withSession{
        Q.query[String, T](query).list(id)
    }
}

So the Method MUST have the result type List[T]. For T within the query i would to write the types A, B and C. (I have defined GetResults already). So this would be possible

if(typeOf[T] <:< typeOf[A]) //using TypeTags
    db withSession{
        Q.query[String, A](query).list(id)
    }
else if(typeOf[T] <:< typeOf[A])
    db withSession{
        Q.query[String, B](query).list(id)
    }
    ...

Every query for itself works, but then the result type of selectT doesn't fit anymore. On the other hand, i don't want to define the result type like List[AnyRef] or List[Any]. Also, the classes don't inherit from T (this would be simple). My code until now:

import scala.slick.session.Database
import Database.threadLocalSession
import scala.slick.jdbc.{GetResult, StaticQuery => Q}
import scala.reflect.runtime.universe._
import PostgreSQLDatabase.db

object SQLExtension{
    implicit val getAResult = GetResult(r => new A(...))
    implicit val getBResult = GetResult(r => new B(...))
    implicit val getCResult = GetResult(r => new C(...))

    def selectT[T](query: String, id: String): List[T] = {
        db withSession{
            Q.query[String, T](query).list(id)
        }
    }
}

So in a short way: I need several bounds/inheritances/other_soulution_concept for T so that I can handle A, B and C within the method, but still have List[T] as result type from the outside.

Thank you and a happy new year.

EDIT: 2014.01.09

@cvogt I tried your solution and it works fine for the definition. But If I want to call my function somewhere else, I got the Problem, that could not find implicit value for parameter getResult: scala.slick.jdbc.GetResult[T] and not enough arguments for method selectT: (implicit getResult: scala.slick.jdbc.GetResult[T])Option[T]. Unspecified value parameter getResult. But I have imported my GetResults?

protected[dao] def getById(id: String): Option[T] = {
      val ret = db.selectT[T](query, id)
      ret
}
Was it helpful?

Solution

If I understand correctly what you are aiming for, you just need to require an implicit GetResult for selectT.

...
import scala.slick.jdbc.GetResult
object SQLExtension{
    implicit val getAResult = GetResult(r => new A(...))
    implicit val getBResult = GetResult(r => new B(...))
    implicit val getCResult = GetResult(r => new C(...))

    def selectT[T](query: String, id: String)(implicit getResult: GetResult[T]): List[T] = {
        db withSession{
            Q.query[String, T](query).list(id)
        }
    }
}

Then you can write something like

import SQLExtensions._ // imports implicits and selectT
val res: List[A] = selectT[A]("select * from A_TABLE where id = ?",5)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top