Permalink
Browse files

[reactivemongo] Write request convenient extractors

  • Loading branch information...
cchantep
cchantep committed Oct 23, 2014
1 parent 25f299f commit 9b641b8e3b1252611a1e9d5376b84a2580ca8f42
View
@@ -365,6 +365,27 @@ val handler = WriteHandler { (op, wreq) =>
}
```
There is also convenient extractor for write operations.
```
import acolyte.reactivemongo.{
WriteHandler,
DeleteRequest,
InsertRequest,
UpdateRequest
}
val handler = WriteHandler { (op, req) =>
case InsertRequest("colname", ("prop1", BSONString("val")) :: _) => ???
case UpdateRequest("colname",
("sel", BSONString("ector")) :: Nil,
("prop1", BSONString("val")) :: _) => ???
case DeleteRequest("colname", ("sel", BSONString("ector")) :: _) => ???
}
```
> In case of insert operation, the `_id` property is added to original document, so it must be taken in account if pattern matching over properties of saved document.
### Result creation for queries
Mongo result to be returned by query handler, can be created as following:
@@ -119,6 +119,37 @@ object RequestBody {
Some(body.map(_.underlying.elements.toList))
}
/** Insert request */
object InsertRequest {
/** @return Collection name and elements of document to be inserted. */
def unapply(insert: (WriteOp, Request)): Option[(String, List[(String, BSONValue)])] = (insert._1, insert._2.body) match {
case (InsertOp, body :: Nil)
Some(insert._2.collection -> body.elements.toList)
case _ None
}
}
/** Update request */
object UpdateRequest {
/** @return Collection name, elements of selector/document to be updated. */
def unapply(update: (WriteOp, Request)): Option[(String, List[(String, BSONValue)], List[(String, BSONValue)])] = (update._1, update._2.body) match {
case (UpdateOp, selector :: body :: Nil)
Some(update._2.collection,
selector.elements.toList, body.elements.toList)
case _ None
}
}
/** Delete request */
object DeleteRequest {
/** @return Collection name and elements of selector. */
def unapply(delete: (WriteOp, Request)): Option[(String, List[(String, BSONValue)])] = (delete._1, delete._2.body) match {
case (DeleteOp, selector :: Nil)
Some(delete._2.collection, selector.elements.toList)
case _ None
}
}
/**
* Extractor of properties for a document used a BSON value
* (when operator is used, e.g. `{ 'age': { '\$gt': 10 } }`).
@@ -366,17 +366,43 @@ object DriverSpec extends org.specs2.mutable.Specification
}
}
"using withWriteHandler" in {
awaitRes(AcolyteDSL.withFlatWriteHandler({
case (UpdateOp, Request(_, RequestBody(
List(("sel", BSONString("hector"))) ::
List(("filter", BSONString("valC"))) :: Nil)))
WriteResponse(1)
}) { driver
AcolyteDSL.withFlatCollection(driver, "col") {
_.update(BSONDocument("sel" -> "hector"), write3._2.body.head)
}
}) aka "write result" must beSuccessfulTry[LastError]
"using withWriteHandler" >> {
"for insert" in {
awaitRes(AcolyteDSL.withFlatWriteHandler({
case InsertRequest("acolyte.col1", ("a", BSONString("val")) ::
("b", BSONInteger(2)) :: ("_id", _) :: Nil)
WriteResponse.successful(1, false)
}) { driver
AcolyteDSL.withFlatCollection(driver, "col1") {
_.save(BSONDocument("a" -> "val", "b" -> 2))
}
}) aka "write result" must beSuccessfulTry[LastError]
}
"for update" in {
awaitRes(AcolyteDSL.withFlatWriteHandler({
case UpdateRequest("acolyte.col2",
("sel", BSONString("hector")) :: Nil,
("filter", BSONString("valC")) :: Nil)
WriteResponse(1)
}) { driver
AcolyteDSL.withFlatCollection(driver, "col2") {
_.update(BSONDocument("sel" -> "hector"), write3._2.body.head)
}
}) aka "write result" must beSuccessfulTry[LastError]
}
"for delete" in {
awaitRes(AcolyteDSL.withFlatWriteHandler({
case DeleteRequest("acolyte.col3",
("a", BSONString("val")) :: Nil)
WriteResponse.successful(2, true)
}) { driver
AcolyteDSL.withFlatCollection(driver, "col3") {
_.remove(BSONDocument("a" -> "val"))
}
}) aka "write result" must beSuccessfulTry[LastError]
}
}
}
}
@@ -87,27 +87,74 @@ object WriteHandlerSpec extends org.specs2.mutable.Specification
}
"return no response" in {
handler aka "mixed handler" must beLike {
case h h(1, write1._1, write1._2) aka "prepared" must beNone
}
handler(1, write1._1, write1._2) aka "prepared" must beNone
}
"return an error response" in {
handler aka "mixed handler" must beLike {
case h h(2, write2._1, write2._2) aka "prepared" must beSome.which(
_ aka "write response" must beWriteError("Error #2"))
}
handler(2, write2._1, write2._2) aka "prepared" must beSome.which(
_ aka "write response" must beWriteError("Error #2"))
}
"return an success response" in {
handler aka "mixed handler" must beLike {
case h h(3, write3._1, write3._2) aka "prepared" must beSome.which(
_ aka "write response" must beResponse {
case ValueDocument(("ok", BSONInteger(1)) ::
("updatedExisting", BSONBoolean(true)) ::
("n", BSONInteger(2)) :: Nil) :: Nil ok
})
}
handler(3, write3._1, write3._2) aka "prepared" must beSome.which(
_ aka "write response" must beResponse {
case ValueDocument(("ok", BSONInteger(1)) ::
("updatedExisting", BSONBoolean(true)) ::
("n", BSONInteger(2)) :: Nil) :: Nil ok
})
}
}
"Convenient extractor" should {
"handle insert" in {
WriteHandler { (op, req)
(op, req) match {
case InsertRequest("col1",
("a", BSONInteger(1)) :: ("b", BSONBoolean(true)) :: Nil)
WriteResponse.successful(1, false)
case _ WriteResponse.failed("Unexpected")
}
} apply (2, InsertOp, new Request {
val collection = "col1"
val body = List(BSONDocument("a" -> 1, "b" -> true))
}) aka "prepared" must beSome.which(
_ aka "result" must beResponse(
_ aka "response" must beWriteSuccess(1, false)))
}
"handle update" in {
WriteHandler { (op, req)
(op, req) match {
case UpdateRequest("col2", ("id", BSONString("id1")) :: Nil,
("a", BSONInteger(1)) :: ("b", BSONBoolean(true)) :: Nil)
WriteResponse.successful(1, true)
case _ WriteResponse.failed("Unexpected")
}
} apply (3, UpdateOp, new Request {
val collection = "col2"
val body = List(BSONDocument("id" -> "id1"),
BSONDocument("a" -> 1, "b" -> true))
}) aka "prepared" must beSome.which(
_ aka "result" must beResponse(
_ aka "response" must beWriteSuccess(1, true)))
}
"handle delete" in {
WriteHandler { (op, req)
(op, req) match {
case DeleteRequest("col3", ("name", BSONString("xyz")) :: Nil)
WriteResponse.successful(2, true)
case _ WriteResponse.failed("Unexpected")
}
} apply (4, DeleteOp, new Request {
val collection = "col3"
val body = List(BSONDocument("name" -> "xyz"))
}) aka "prepared" must beSome.which(
_ aka "result" must beResponse(
_ aka "response" must beWriteSuccess(2, true)))
}
}
}

0 comments on commit 9b641b8

Please sign in to comment.