Slick and Type Parameters.

19 views
Skip to first unread message

metasc...@gmail.com

unread,
Feb 17, 2018, 1:43:36 PM2/17/18
to Slick / ScalaQuery
Hi All,

I'm trying to create an abstract class called CrudRepository that will allow me to easily create CRUD type operations simply by sub-classing appropriately and providing the right type parameters.

So, for example if we wanted to have a class associated with a User table for which we want CRUD type operations, we can invoke this by saying:

class UserRepository(val dbConfig: DatabaseConfig) extends CrudRepository[String, User, Tables.User] {
  /* insert, update, delete and find are predefined for you, define other user functions here */
}

The problem I'm running into is that the compiler gives me the following error, everywhere === is used.

[error] /home/treehouse/work/nomic/app/repositories/CrudRepository.scala:61:59: value === is not a member of slick.lifted.Rep[K]
[error]     val q = table.filter[slick.lifted.Rep[Boolean]](_.key === key(obj))


The issue to me seems to be that the compiler needs the value of K in order to resolve ===, but that would defeat the whole purpose. Is there a way to accomplish this?

Any help will be much appreciated.

Thanks,

A.



The code for CrudRepository is below. The type parameters are as follows.
K is the type of 'keys' -- the one column that will be the key column for the table.
V is the type of each of the entries in the table,
T is the type of the slick Table we want to use. Tables.HasKeyColumn guarantees that every Table has a column called "key" which is the unique key for that table.

CachedRepository is unimportant here, but it basically provides an in-memory cache for fast lookup of records.


 
class CrudRepository[K, V, T <: Tables.HasKeyColumn[K, V]]
                     
(val dbConfig: DatabaseConfig[JdbcProfile])
                     
(implicit val ec: ExecutionContext) extends CachedRepository[K, V] with Logging {

   
import dbConfig.profile.api._
   
protected def db = dbConfig.db

   val table
: TableQuery[T]

   
/*----------------------------------------------------------------
    * Main entry points into the repository
    *----------------------------------------------------------------*/


   
def insert(obj: V): Future[V] = {
     db
.run(insertAction(obj)).map { id =>
       cache
(obj)
     
}
   
}

   
def update(obj: V): Future[V] = {
     db
.run(updateAction(obj)).map { _ =>
       uncache
(obj)
       cache
(obj)
     
}
   
}

   
def delete(obj: V): Future[Unit] = {
     db
.run(deleteAction(obj)).map { _ =>
       uncache
(obj)
     
}
   
}

   
override def find(k: K): Future[Seq[V]] = {
     db
.run(findAction(k))
   
}

   
/*----------------------------------------------------------------
    * DBIO Actions corresponding to repo operations for compositionality
    *----------------------------------------------------------------*/


   
def insertAction(obj: V): DBIO[Int] = {
     table
+= obj
   
}

   
def updateAction(obj: V): DBIO[Int] = {
     val q
= table.filter[slick.lifted.Rep[Boolean]](_.key === key(obj))
     q
.update(obj)
   
}

   
def deleteAction(obj: V): DBIO[Int] = {
     val q
= table.filter[slick.lifted.Rep[Boolean]](_.key === key(obj))
     q
.delete()
   
}

   
def findAction(k: K): DBIO[Seq[V]] = {
     table
.filter[slick.lifted.Rep[Boolean]](_.key === k).result
   
}
 
}


Reply all
Reply to author
Forward
0 new messages