-
Notifications
You must be signed in to change notification settings - Fork 26
Step #10 : Entity mapping
mandubian edited this page Nov 15, 2012
·
3 revisions
// Dog definition
case class Dog(name: String, age: Int)
object DogSchema {
val name = Attribute( KW(":dog/name"), SchemaType.string, Cardinality.one).withDoc("Dog's name")
val age = Attribute( KW(":dog/age"), SchemaType.long, Cardinality.one).withDoc("Dog's age")
val schema = Seq(name, age)
}
// Person definition
case class Person(name: String, age: Int, dogs: Set[Ref[Dog]])
object PersonSchema {
val name = Attribute( KW(":person/name"), SchemaType.string, Cardinality.one).withDoc("Person's name")
val age = Attribute( KW(":person/age"), SchemaType.long, Cardinality.one).withDoc("Person's age")
val dogs = Attribute( KW(":person/dogs"), SchemaType.ref, Cardinality.many).withDoc("Person's dogs")
val schema = Seq(name, age, dogs)
}
// provisions schemas (blocking here to simplify code ;) )
Await.result(
transact(PersonSchema.schema ++ DogSchema.schema),
Duration("2 seconds")
)
// Typesafe Dog mappers based on Schema
implicit val dogReader = (
DogSchema.name.read[String] and
DogSchema.age.read[Int]
)(Dog)
implicit val dogWriter = (
DogSchema.name.write[String] and
DogSchema.age.write[Int]
)(unlift(Dog.unapply))
// Typesafe Person mappers based on Schema
implicit val personReader = (
PersonSchema.name.read[String] and
PersonSchema.age.read[Int] and
PersonSchema.dogs.read[Set[Ref[Dog]]]
)(Person)
implicit val personDogListWriter = (
PersonSchema.name.write[String] and
PersonSchema.age.write[Int] and
PersonSchema.dogs.write[Set[Ref[Dog]]]
)(unlift(Person.unapply))
// Creates Scala Data
val medor = Dog("medor", 5)
val tmpMedorId = DId(Partition.USER) // Temporary Id
val brutus = Dog("brutus", 3)
val tmpBrutusId = DId(Partition.USER) // Temporary Id
// creates person using previous tempids
val toto = Person("toto", 30, Set(Ref(tmpMedorId)(medor), Ref(tmpBrutusId)(brutus)))
val tmpTotoId = DId(Partition.USER) // Temporary Id
// Provisioning Data to Datomic
transact(
toAddEntity(tmpMedorId)(medor),
toAddEntity(tmpBrutusId)(brutus),
toAddEntity(tmpTotoId)(toto) // using temporary Id
).map{ tx =>
// resolving final Ids
tx.resolve(tmpMedorId, tmpBrutusId, tmpTotoId) match {
case (Some(medorId), Some(brutusId), Some(totoId)) =>
fromEntity[Person]( database.entity(totoId) ).map{ person =>
person must beEqualTo(
Person(
"toto",
30,
Set(Ref(DId(medorId))(medor), Ref(DId(brutusId))(brutus)) // USING FINAL IDS
)
)
}
}