Skip to content

Instantly share code, notes, and snippets.

@cokeSchlumpf
Created July 9, 2014 15:52
Show Gist options
  • Save cokeSchlumpf/2f10d29c831a0803bd18 to your computer and use it in GitHub Desktop.
Save cokeSchlumpf/2f10d29c831a0803bd18 to your computer and use it in GitHub Desktop.
Slick DAO Capabilities
**
* DAOCapabilities for slick entities.
*
* @author [email protected]
* @since 4/14/14
*/
abstract class AbstractDAOCapabilities[ENTITY <: EntityCapabilities[ENTITY], TABLE <: AbstractTable[ENTITY]](cons: Tag => TABLE)
extends DAOCapabilities[Option[Long], ENTITY]
with LoggingCapabilities {
import de.rodenstock.fue.commons.play.controllers.stackable.CurrentRequest._
import scala.language.reflectiveCalls
/**
* Variable for entity name. It will be determined during initialization.
*/
private var _entityName: String = _
/**
* Slick table query for the given table.
*/
val entities = new TableQuery(initializeTableQuery) {
val findById = this.findBy(_.id)
}
/**
* Initializes the table and stores the tables name as class attribute. This function has side-effects!
*
* @param tag
* The slick tag.
* @return
* The initialized table.
*/
private def initializeTableQuery(tag: Tag): TABLE = {
val table = cons(tag)
_entityName = table.tableName
table
}
/**
* @return The display name of the entity (used for logging, generic ui, ...)
*/
def entityName = if (_entityName == null) {
throw andLog(new IllegalStateException("The entity name is not defined yet - Something went wrong."))
} else {
_entityName
}
/**
* Companion method to insert or update an entity (depending if it's already stored or not).
*
* @param entity
* The entity to be stored.
* @param request
* The current request context.
* @return
* The saved entity.
*/
override def save(entity: ENTITY)(implicit request: RequestWithAttributes[_]): ENTITY = {
// We need to store entity.id in a value, since the generic Long of ID_TYPE will get lost due to type erasure.
val id: Option[Long] = entity.id
id match {
case Some(_) => update(entity)
case None => insert(entity)
}
}
/**
* Deletes an existing entity.
*
* @param id
* The id of the entity which should be deleted.
* @param request
* The current request context.
* @return
*/
override def deleteById(id: Option[Long])(implicit request: RequestWithAttributes[_]): Unit = {
entities.where(_.id === id).delete
}
/**
* Deletes an existing entity.
*
* @param entity
* The entity which should be deleted.
* @param request
* The current request context.
* @return
*/
override def delete(entity: ENTITY)(implicit request: RequestWithAttributes[_]): Unit = deleteById(entity.id)
/**
* Update an existing entity.
* @param entity
* The entity to update.
* @param request
* The current request context.
* @return
* The updated entity.
*/
override def update(entity: ENTITY)(implicit request: RequestWithAttributes[_]): ENTITY = {
// We need to store entity.id in a value, since the generic Long of ID_TYPE will get lost due to type erasure.
val id: Option[Long] = entity.id
id match {
case Some(_) =>
entities.where(_.id === entity.id).update(entity)
entity
case None =>
throw andLog(new IllegalArgumentException("Entity ID is not defined. Update must be called with an already stored entity."))
}
}
/**
* Get a list of all available entities.
*
* @param request
* The current request context.
* @return
* The list of all available entities.
*/
override def list(implicit request: RequestWithAttributes[_]): Seq[ENTITY] = entities.list
/**
* Insert a new entity.
*
* @param entity
* The entity to insert.
* @param request
* The current request context.
* @return
* The inserted entity.
*/
override def insert(entity: ENTITY)(implicit request: RequestWithAttributes[_]): ENTITY = {
// We need to store entity.id in a value, since the generic Long of ID_TYPE will get lost due to type erasure.
val id: Option[Long] = entity.id
id match {
case Some(_) =>
throw andLog(new IllegalArgumentException("Entity ID is already defined. Insert must be called with a new entity."))
case None =>
val newId = (entities returning entities.map(_.id)) += entity
entity.withId(Some(newId))
}
}
/**
* Return the count of all existing entities.
*
* @param request
* The current request context.
* @return
* The calculated count of existing entities.
*/
override def count(implicit request: RequestWithAttributes[_]): Int = list.size
/**
* Find the attribute by its id.
*
* @param id
* The id to look for.
* @param request
* The current request context.
* @return
* Some entity if it exists, else None.
*/
override def findById(id: Option[Long])(implicit request: RequestWithAttributes[_]): Option[ENTITY] = entities.findById(id.get).firstOption
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment