Basically what I want to achieve is a combination of:
Slick 3.0.0 database agnostism and Slick 3 reusable generic repository
I tried a lot, actually, but I can't get this to work at all.
abstract class BaseModel[T <: slick.lifted.AbstractTable[_]](query: TableQuery[T], val driver: JdbcProfile, val dbTableName: String)
{
lazy val all: TableQuery[T] = TableQuery[T]
import driver.api._
def createTable = all.schema.create
def dropTable = all.schema.create
abstract class BaseTable[B](val tag: Tag) extends Table[B](tag, dbTableName)
{
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
}
}
Now here we have a problem already:
def createTable = all.schema.create and the same with dropTable... -> schema cannot be resolved here, although I import the driver before.
But an even bigger problem comes in when I subclass this:
Here is the code
class NodeModel(driver: JdbcProfile, dbTableName: String) extends BaseModel[NodeTable](TableQuery[NodeTable], driver, dbTableName) {
val dbDriver = driver
import dbDriver.api._
class NodeTable(tag: Tag) extends BaseTable[Node](tag)
{
override def * = id.? <> (Node, Node.unapply)
}
//lazy val all: TableQuery[NodeTable] = TableQuery[NodeTable]
def createTable: DBIO[Unit] = all.schema.create
def dropTable: DBIO[Unit] = all.schema.drop
def insert(node: Node) = all += node
}
This won't compile obviously because I cannot pass NodeTable as T, but gives an idea of what I want to achieve.
Do you have any idea how to solve this? I also tried with companion objects, moving the BaseTable out of the BaseModel and trying to load a simpleDriver... but it looks like that functionality was removed from Slick in a recent version :(
Database agnostic and Code is highly reusable
I am using
SlickwithPlayframeworkand this is how I achieved database agnostic and generic repository.Note that this work is inspired from Active Slick
I want to have basic crud operations like this to be defined on my
case class. I should be able to docount,update,deleteandcreate. I want to write the curd code just once and reuse it for ever.Here is the snippet which demonstrates this.
CrudActions.scala
Now lets get our
Entityinto picture. Note thatEntityis nothing but our case classEntityiscase classon which we do crud operations. For locating our entity lets also haveIdin place.Idis important for locating and operating an entity or record in the database. AlsoIduniquely identities for entityEntityActionsLike.scala
Now lets implement these methods. For doing operations we need
TableandTableQuery. Lets say we havetableandtableQuery. The good about traits is we can declare a contract and leave the implementation details to subclasses or subtypesEntityActions.scala
ActiveRecord.scala
ModelContract.scala
How to Use
Sample.scala
Now we can do operations on
Dogdirectly like thisThis implicit does the magic for us
You can also add
schemecreation and dropping logic in EntityActions