scala - Slick: Avoiding asInstanceOf[T] and Improving Type signature -


the code below works, can't think doing inappropriate asinstanceof[b] cast.

essentially, after passing tablequery of type, want mapper turn action take results , map list of daos according function pass it.

what stuck on type of function, or perhaps how expose inner type of tablequery type. want [b <: tableelementtype] f: b => a instead of potentially brutal cast b.

i guess think know going agencyrow in example below map agencydao, how can capture in type signature of method?


mapper

  def mapper[a <: basedao, b <: databaseaccessobject, t <: tablequery[e], e <: abstracttable[_]](query: t, f: b => a) : seq[a] = {     val result = exec(query.result)     result.map(o => f(o.asinstanceof[b]))   }    def exec[t](action: dbio[t]): t = await.result(db.run(action), 4 seconds) 

consuming mapper (test code)

val list = mapper[agencydao, agencyrow, tablequery[agency], agency](agencies, agencydaodomainobject.convertfromrow)         list.length should equal(75) 

slick schema

case class agencyrow(id: int, name: option[string] = none) extends databaseaccessobject  class agency(_tabletag: tag) extends table[agencyrow](_tabletag, "agency") {    def * = (id, name) <>(agencyrow.tupled, agencyrow.unapply)    def ? = (rep.some(id), name).shaped.<>({ r => import r._; _1.map(_ => agencyrow.tupled((_1.get, _2))) }, (_: any) => throw new exception("inserting ? projection not supported."))     val id: rep[int] = column[int]("id", o.autoinc, o.primarykey)    val name: rep[option[string]] = column[option[string]]("name", o.length(200, varying = true), o.default(none)) }  lazy val agency = new tablequery(tag => new agency(tag))enter code here 

dao mapper

package object implicits {    implicit class domainobjectops[a <: basedao](a: a)(implicit ev: domainobject[a]) {    def name = ev.name(a)    def id = ev.id(a)   } }     trait basedao trait domainobject[a <: basedao] {   def id(a: a): int   def name(a: a): string }  case class agencydao(val id: int, val name: string) extends basedao object agencydao {   implicit object agencydaodomainobject extends domainobject[agencydao] {     def converttorow(o: agencydao) = agencyrow(o.id, some(o.name))     def convertfromrow(o: agencyrow) = agencydao(o.id, o.name.getorelse(""))      override def id(a: agencydao) = a.id     override def name(a: agencydao) = a.name   } } 

in case else might possibly find relevant or instructive: rather call resulton query inside mapper, passed in result called, returns dbioaction[r]. slick has convenient alias dbio[r], , r can asked extend seq[b] eliminating need cast. now:

updated mapper

def resultmapper[a <: basedao, b <: databaseaccessobject, s <: dbio[seq[b]]](action: s)(implicit rowmapper: b => a) : seq[a] = {    val result = exec(action)    result.map(rowmapper) } 

updated call

implicit val rowmapper: agencyrow => agencydao = agencydaodomainobject.convertfromrow val action = agencies.result //turns query dbioaction val list = resultmapper[agencydao, agencyrow, dbio[seq[agencyrow]]](action)  

Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -