Last active
May 3, 2016 12:29
-
-
Save sake92/7db67bfe400cc45775b86d58f1b6e7d8 to your computer and use it in GitHub Desktop.
Slick mapping more than 22 columns with case classes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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