Skip to content

Instantly share code, notes, and snippets.

@easel
Last active October 17, 2016 18:08
Show Gist options
  • Save easel/1c6a66aa2b1dacb3e37a to your computer and use it in GitHub Desktop.
Save easel/1c6a66aa2b1dacb3e37a to your computer and use it in GitHub Desktop.
generic slick foreign key
object SlickGroupsDAO {
case class Item(
name: String,
parentId: Option[Long] = None,
ctime: Timestamp = new Timestamp(DateTime.now.getMillis),
mtime: Timestamp = new Timestamp(DateTime.now.getMillis),
id: Long = 1
) extends SlickDTO
}
trait SlickTable extends HasDatabaseConfig[JdbcProfile] with Implicits with Logging {
import driver.api._
protected trait IdentifiedTable[Id <: BaseId, T <: Identified[Id, _]] {
self: Table[T] =>
def id: Rep[Id]
}
}
trait GroupsTable extends SlickTable {
import driver.api._
// scalastyle:off
class Groups(tag: Tag) extends Table[Item](tag, "accounts_groups") with IdentifiedTable[Item] {
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def parentId = column[Option[Long]]("parent_id")
def cTime = column[Timestamp]("ctime")
def mTime = column[Timestamp]("mtime")
// Every table needs a * projection with the same type as the table's type parameter
def * = (
name, parentId, cTime, mTime, id
) <> ((Item.apply _).tupled, Item.unapply)
def parent = foreignKey("parent_id", parentId, groups)(_.id.?)
}
val groups = TableQuery[Groups]
}
@javax.inject.Singleton
class SlickGroupsDAO @Inject() (
protected val dbConfigProvider: DatabaseConfigProvider
) extends SlickDAO[Item] with GroupsTable with Logging {
import driver.api._
type Items = Groups
val table = TableQuery[Groups]
def create(obj: Item): Item = {
val q = (table returning table.map(_.id)
into ((item, newId) => item.copy(id = newId))) += obj
block(db.run(q))
}
}
object SlickUsersDAO {
case class UserDTO(
// primary key, in this case it is String
id: SlickDTO.Id = -1,
groupId: SlickDTO.Id,
firstName: Option[String] = None,
lastName: Option[String] = None,
email: Option[String] = None,
password: Option[String] = None,
enabled: Boolean = true,
config: String = "{}",
cTime: Timestamp = new Timestamp(DateTime.now.getMillis),
mTime: Timestamp = new Timestamp(DateTime.now.getMillis),
trialExpires: Option[Timestamp] = None
) extends SlickDTO
trait UsersTable extends SlickTable with GroupsTable {
import driver.api._
// scalastyle:off
class Users(tag: Tag) extends Table[UserDTO](tag, "accounts_users") with IdentifiedTable[UserDTO] {
def id = column[SlickDTO.Id]("id", O.PrimaryKey, O.AutoInc)
def groupId = column[SlickDTO.Id]("group_id")
def firstName = column[Option[String]]("first_name")
def lastName = column[Option[String]]("last_name")
def email = column[Option[String]]("email")
def password = column[Option[String]]("password")
def enabled = column[Boolean]("enabled")
def config = column[String]("config")
def cTime = column[Timestamp]("ctime")
def mTime = column[Timestamp]("mtime")
def trialExpires = column[Option[Timestamp]]("trial_expires")
// Every table needs a * projection with the same type as the table's type parameter
def * = (
id, groupId, firstName, lastName, email, password, enabled, config,
cTime, mTime, trialExpires
) <> ((UserDTO.apply _).tupled, UserDTO.unapply)
def group = foreignKey("fk_group", groupId, groups)(_.id)
}
val users = TableQuery[Users]
}
@javax.inject.Singleton
class SlickUsersDAO @Inject() (
protected val dbConfigProvider: DatabaseConfigProvider,
val groupsDao: SlickGroupsDAO
) extends SlickDAO[UserDTO] with UsersTable with Logging {
import driver.api._
type Items = Users
val table = users
override def createTable(): Unit = {
groupsDao.createTable()
super.createTable()
}
override def dropTable(): Unit = {
super.dropTable()
groupsDao.dropTable()
}
def create(obj: UserDTO): UserDTO = {
val q = (table returning table.map(_.id)
into ((message, id) => message.copy(id = id))) += obj
db.run(q)
}
def getByEmail(email: String): Option[UserDTO] = {
val q = table.filter(_.email === email).result.headOption
db.run(q)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment