From df931d09f5ba269545ec2af921ce62cc4ee0fb18 Mon Sep 17 00:00:00 2001 From: Gustavo De Micheli Date: Mon, 14 Nov 2016 09:29:48 +0100 Subject: [PATCH] Add support for Embedded Lists --- src/main/scala/oriented/OrientFormat.scala | 4 ++++ src/main/scala/oriented/free/dsl/ReadDSL.scala | 10 ++++++++++ .../oriented/free/interpreters/ReadInterpreter.scala | 4 ++++ src/test/scala/dsl/ReadSpec.scala | 12 ++++++++---- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/main/scala/oriented/OrientFormat.scala b/src/main/scala/oriented/OrientFormat.scala index fee076f..66f7aa8 100644 --- a/src/main/scala/oriented/OrientFormat.scala +++ b/src/main/scala/oriented/OrientFormat.scala @@ -39,6 +39,10 @@ trait OrientFormat[A] { def read[T](fieldName: String)(implicit orientFormat: OrientFormat[T]): OrientRead[T] = element.readEmbedded(fieldName, orientFormat) + def readList[T](fieldName: String)(implicit orientFormat: OrientFormat[T]): OrientRead[List[T]] = element.readList(fieldName, orientFormat) + + def readListOpt[T](fieldName: String)(implicit orientFormat: OrientFormat[T]): OrientRead[Option[List[T]]] = element.readListOpt(fieldName, orientFormat) + def readBoolean(fieldName: String): OrientRead[Boolean] = element.readBoolean(fieldName) def readBooleanOpt(fieldName: String): OrientRead[Option[Boolean]] = element.readBooleanOpt(fieldName) diff --git a/src/main/scala/oriented/free/dsl/ReadDSL.scala b/src/main/scala/oriented/free/dsl/ReadDSL.scala index 56f155c..a3ea2c7 100644 --- a/src/main/scala/oriented/free/dsl/ReadDSL.scala +++ b/src/main/scala/oriented/free/dsl/ReadDSL.scala @@ -18,6 +18,10 @@ case class Read[A](a: A) extends ReadDSL[A] case class ReadEmbedded[T](fieldName: String, orientFormat: OrientFormat[T]) extends ReadDSL[T] +case class ReadList[T](fieldName: String, orientFormat: OrientFormat[T]) extends ReadDSL[List[T]] + +case class ReadListOpt[T](fieldName: String, orientFormat: OrientFormat[T]) extends ReadDSL[Option[List[T]]] + case class ReadBoolean(fieldName: String) extends ReadDSL[Boolean] case class ReadBooleanOpt(fieldName: String) extends ReadDSL[Option[Boolean]] @@ -64,6 +68,12 @@ class Reads[F[_]](implicit inject: Inject[ReadDSL, F]) { def readEmbedded[T](fieldName: String, orientFormat: OrientFormat[T]): Free[F, T] = Free.inject[ReadDSL, F](ReadEmbedded(fieldName, orientFormat)) + def readList[T](fieldName: String, orientFormat: OrientFormat[T]): Free[F, List[T]] = + Free.inject[ReadDSL, F](ReadList(fieldName, orientFormat)) + + def readListOpt[T](fieldName: String, orientFormat: OrientFormat[T]): Free[F, Option[List[T]]] = + Free.inject[ReadDSL, F](ReadListOpt(fieldName, orientFormat)) + def readBoolean(fieldName: String): Free[F, Boolean] = Free.inject[ReadDSL, F](ReadBoolean(fieldName)) diff --git a/src/main/scala/oriented/free/interpreters/ReadInterpreter.scala b/src/main/scala/oriented/free/interpreters/ReadInterpreter.scala index 0dd51e9..567692d 100644 --- a/src/main/scala/oriented/free/interpreters/ReadInterpreter.scala +++ b/src/main/scala/oriented/free/interpreters/ReadInterpreter.scala @@ -18,6 +18,8 @@ object ReadInterpreter extends (ReadDSL ~> Reader[OrientElement, ?]) { fa match { case Read(a) => a case ReadEmbedded(fieldName, of) => of.readerMap(o.getProperty[Map[String, Any]](fieldName)) + case ReadList(fieldName, of) => o.getProperty[List[Map[String, Any]]](fieldName).map(of.readerMap.run) + case ReadListOpt(fieldName, of) => Try(o.getProperty[List[Map[String, Any]]](fieldName).map(of.readerMap.run)).toOption case ReadBoolean(fieldName) => o.getProperty[Boolean](fieldName) case ReadBooleanOpt(fieldName) => Try(o.getProperty[Boolean](fieldName)).toOption case ReadInt(fieldName) => o.getProperty[Int](fieldName) @@ -47,6 +49,8 @@ object ReadMapInterpreter extends (ReadDSL ~> Reader[Map[String, Any], ?]) { override def apply[A](fa: ReadDSL[A]): Reader[Map[String, Any], A] = Reader(map => fa match { case Read(a) => throw new Exception("") case ReadEmbedded(fieldName, orientFormat) => orientFormat.readerMap(map(fieldName).asInstanceOf[Map[String, Any]]) + case ReadList(fieldName, orientFormat) => map(fieldName).asInstanceOf[List[Map[String, Any]]].map(orientFormat.readerMap.run) + case ReadListOpt(fieldName, orientFormat) => map.get(fieldName).map(_.asInstanceOf[List[Map[String, Any]]].map(orientFormat.readerMap.run)) case ReadBoolean(fieldName) => map(fieldName).asInstanceOf[Boolean] case ReadBooleanOpt(fieldName) => map.get(fieldName).map(_.asInstanceOf[Boolean]) case ReadInt(fieldName) => map(fieldName).asInstanceOf[Int] diff --git a/src/test/scala/dsl/ReadSpec.scala b/src/test/scala/dsl/ReadSpec.scala index 11b35d9..31602e2 100644 --- a/src/test/scala/dsl/ReadSpec.scala +++ b/src/test/scala/dsl/ReadSpec.scala @@ -105,13 +105,14 @@ class ReadSpec extends FlatSpec with Matchers with BeforeAndAfter { blogVertex.element should equal(blogVertexFromQuery.element) } - case class BlogEmbed(tid: Long, blog: Blog) + case class BlogEmbed(tid: Long, blog: Blog, metas: List[Meta]) implicit val orientFormatBlogEmbeded: OrientFormat[BlogEmbed] = new OrientFormat[BlogEmbed] { def read: OrientRead[BlogEmbed] = for { tid <- readLong("tid") blog <- read[Blog]("blog") - } yield BlogEmbed(tid, blog) + metas <- readList[Meta]("metas") + } yield BlogEmbed(tid, blog, metas) def name: String = "BlogEmbed" @@ -120,12 +121,14 @@ class ReadSpec extends FlatSpec with Matchers with BeforeAndAfter { Map("tid" -> model.blog.tid, "content" -> model.blog.content, "meta" -> Map("date" -> model.blog.meta.date, - "user" -> model.blog.meta.user))) + "user" -> model.blog.meta.user)), + "metas" -> model.metas.map(m => Map("date" -> m.date, "user" -> m.user))) } "Read embedded" should "be able to read an embedded object in an embedded object" in { + val metaList = List(Meta(new Date(), "Foo"), Meta(new Date(), "Bar"), Meta(new Date(), "Baz")) val embededBlogVertex = orientClient - .addVertex(BlogEmbed(1, Blog(2, "Bla bla", Meta(new Date(), "Thomasso")))) + .addVertex(BlogEmbed(1, Blog(2, "Bla bla", Meta(new Date(), "Thomasso")), metaList)) .runGraphUnsafe(enableTransactions = false) val embeddedBlogQuery = sql"SELECT FROM BlogEmbed WHERE tid = '1'" @@ -134,6 +137,7 @@ class ReadSpec extends FlatSpec with Matchers with BeforeAndAfter { .runGraphUnsafe(enableTransactions = false) embededBlogVertex.element should equal(embeddedBlogQuery.element) + embededBlogVertex.element.metas.size should equal(embeddedBlogQuery.element.metas.size) } }