Skip to content

Instantly share code, notes, and snippets.

@fride
Forked from cvogt/gist:9239494
Created February 27, 2014 10:34
Show Gist options
  • Save fride/9247804 to your computer and use it in GitHub Desktop.
Save fride/9247804 to your computer and use it in GitHub Desktop.
// Please comment in case of typos or bugs
import scala.slick.driver.H2Driver._
val db = Database.for...(...)
case class Record( ... )
class Records extends Table[Record](...){
...
def * = ... <> (Record.tupled,Record.unapply)
// place additional methods here which return values of type Column
// (compute artificial columns based on other columns) based on a
// records row
def foo = (col1+col2, col3)
...
}
object records extends TableQuery(new Records(_)){
// Only place methods here which return a not-yet executed Query or
// (individually meaningful) Column which is based on the WHOLE table.
// Seldom useful, often better placed in RecordQueryExentions
def foos = this.map(_.foo) // <- can only be used on the whole table
...
}
// usage:
db.withSession{ records.map(_.foo).run }
db.withSession{ records.foos.run }
implicit class RecordQueryExtensions(val q: Query[Records,Record]) extends AnyVal{
// Only place methods here which return a not-yet executed Query or
// (individually meaningful) Column.
// Methods placed here can be chained/combined.
...
def foos = q.map(_.foo)
}
// usage:
db.withSession{ records.filter(_.age < 30).foos.run }
object RecordsDAO{
// place methods here that require a database connection
// i.e. do not compose without executing queries, e.g.
// methods take Session argument
// usage:
// db.withSession{ RecordsDAO.foos }
// or
// db.withSession{ implicit session => Records.DAO.foos }
def foos(implicit s:Session) = records.foos.run
...
}
// usage:
db.withSession{ RecordsDAO.foos }
db.withSession{ implicit session => Records.DAO.foos }
// Alternative DAO implementation:
case class RecordsDAO(implicit s:Session){
// centralized implicit session into class argument
def foos = records.foos.run
...
}
// usage:
db.withSession{ RecordsDAO().foos }
db.withSession{ implicit session => RecordsDAO().foos }
// Another alternative DAO implementation:
object RecordsDAO{
// in user code
// no withSession boilerplate but no
// control over foos / transaction management
def foos = db.withSession{ records.foos.run }
// or:
def foos = db.withSession{ implicit s => records.foos.run }
// or:
def foos = db.withSession{ records.foos.list()(_) }
...
}
// usage:
RecordsDAO.foos
// Alternative Table class implementation using a mapped projection case class
// Allows projection case classes to be nested and re-used in queries and multiple tables.
// Uses the recently born CaseClassShape suggested here:
// https://github.com/slick/slick/pull/692
case class RecordProjection( ... : Column[...], ... : Column[...], ... ){
// place additional methods here which return values of type Column
// (compute artificial columns based on other columns) based on a
// records row
def foo = (col1+col2, col3)
...
}
implicit object RecordShape extends CaseClassShape(RecordProjection.tupled,Record.tupled)
class Records extends Table[Record](...){
def projection = RecordProjection(column(...),column(...),...) // column types can be inferred
def * = projection
}
val records = TableQuery[Records].map(_.projection)
// usage:
db.withSession{ records.map(_.foo).run }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment