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
}
}