Skip to content

Instantly share code, notes, and snippets.

@sake92
Last active May 3, 2016 12:29
Show Gist options
  • Save sake92/7db67bfe400cc45775b86d58f1b6e7d8 to your computer and use it in GitHub Desktop.
Save sake92/7db67bfe400cc45775b86d58f1b6e7d8 to your computer and use it in GitHub Desktop.
Slick mapping more than 22 columns with case classes
package slick22
import slick.driver.H2Driver.api._
import scala.concurrent.Await
import scala.concurrent.duration.Duration
import scala.concurrent.ExecutionContext.Implicits.global
object PersonTableExample extends App {
/**
* Instead of auto-generated code for PersonRow that is a HList we use nested mapped entity(nested case classes).
* @see [[https://github.com/slick/slick/blob/ff992bb492129674ba730e5e5503eae43d66afd0/slick-testkit/src/main/scala/com/typesafe/slick/testkit/tests/MapperTest.scala#L153]]
* @see [[http://stackoverflow.com/a/28408343/4496364]]
* @see [[https://groups.google.com/d/msg/scalaquery/agAgJPuXYG8/cTHHyYfFKaUJ]]
*/
case class PersonRow(
base: PersonRowBase,
detail: PersonRowDetail)
case class PersonRowBase(
id: Int,
name: String,
surname: String)
case class PersonRowDetail(
phone: String,
address: String)
/** The Person table */
class Person(_tableTag: Tag) extends Table[PersonRow](_tableTag, "person") {
val id: Rep[Int] = column[Int]("id", O.AutoInc, O.PrimaryKey)
val name: Rep[String] = column[String]("name", O.Length(50, varying = true))
val surname: Rep[String] = column[String]("surname", O.Length(50, varying = true))
val phone: Rep[String] = column[String]("phone", O.Length(50, varying = true))
val address: Rep[String] = column[String]("address", O.Length(50, varying = true))
// for mapping PersonRow to tuples and back
private type PersonRowBaseTupleType = (Int, String, String)
private type PersonRowDetailTupleType = (String, String)
private type PersonRowTupleType = (PersonRowBaseTupleType, PersonRowDetailTupleType)
private val personShapedValue = (
(id, name, surname),
(phone, address)
).shaped[PersonRowTupleType]
private val toPersonRow: (PersonRowTupleType => PersonRow) = { personTuple =>
PersonRow(base = PersonRowBase.tupled.apply(personTuple._1), detail = PersonRowDetail.tupled.apply(personTuple._2))
}
private val toPersonTuple: (PersonRow => Option[PersonRowTupleType]) = { personRow =>
Some(PersonRowBase.unapply(personRow.base).get, PersonRowDetail.unapply(personRow.detail).get)
}
def * = personShapedValue <> (toPersonRow, toPersonTuple)
}
/** TableQuery object for table Person */
val Person = TableQuery[Person]
/* TESTING */
val db = Database.forConfig("h2mem1")
try {
val createTableAction = Person.schema.create
Await.ready(db.run(createTableAction), Duration.Inf) // just for demo, compose Future-s instead!
val newPerson = PersonRow(PersonRowBase(0, "Sake", "Hadzija"), PersonRowDetail("123456", "Sarajevo, Bosnia"))
val insertAction = Person += newPerson
Await.ready(db.run(insertAction), Duration.Inf) // just for demo, compose Future-s instead!
val findAllAction = Person.result
val persons = Await.result(db.run(findAllAction), Duration.Inf)
println(persons)
} finally {
db.close()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment