Skip to content

Latest commit

 

History

History
186 lines (124 loc) · 5.44 KB

README.md

File metadata and controls

186 lines (124 loc) · 5.44 KB

ReactiveMongo Extensions

This is a library providing DAO and DSL support for ReactiveMongo. The goal of ReactiveMongo Extensions is to provide all the necessary tools for ReactiveMongo other than the core functionality.

Build Status

Introduction

ReactiveMongo Extensions currently provides two DAO types, which are BsonDao for BSONCollection and JsonDao for JSONCollection. DAOs provide an abstraction layer on top of ReactiveMongo adding higher levels of APIs like findOne, findById, count, foreach, fold, etc.

You will need to define a DAO for each of your models(case classes).

Below is a sample model.

import reactivemongo.bson._
import reactivemongo.extensions.dao.Handlers._

case class Person(
  _id: BSONObjectID = BSONObjectID.generate,
  name: String,
  surname: String,
  age: Int)

object Person {
  implicit val personHandler = Macros.handler[Person]
}

DAOs to Serve You

To define a BsonDao for the Person model you just need to extend BsonDao.

import reactivemongo.api.{ MongoDriver, DB }
import reactivemongo.bson.BSONObjectID
import reactivemongo.bson.DefaultBSONHandlers._
import reactivemongo.extensions.dao.BsonDao
import scala.concurrent.ExecutionContext.Implicits.global

object MongoContext {
  val driver = new MongoDriver
  val connection = driver.connection(List("localhost"))
  def db(): DB = connection("reactivemongo-extensions")
}

object PersonDao extends BsonDao[Person, BSONObjectID](MongoContext.db, "persons")

From now on you can insert a Person instance, find it by id, find a random person or etc.

val person1 = Person(name = "foo", surname = "bar", age = 16)
val person2 = Person(name = "fehmi can", surname = "saglam", age = 32)
val person3 = Person(name = "ali", surname = "veli", age = 64)

PersonDao.insert(person1)
PersonDao.insert(Seq(person2, person3))

PersonDao.findById(person1._id)
PersonDao.findRandom(BSONDocument("age" -> BSONDocument("$ne" -> 16)))

Easy Query Construction

There are also DSL helpers for each DAO type, which are BsonDsl and JsonDsl. DSL helpers provide utilities to easily construct JSON or BSON queries.

By mixing or importing BsonDsl you could write the query above like this:

import reactivemongo.extensions.dsl.BsonDsl._

PersonDao.findRandom($ne("age" -> 16))

Functional DSL

Even better there is also an infix version for each DSL type.

import reactivemongo.extensions.dsl.functional.BsonDsl._

PersonDao.findRandom("age" $gt 16 $lt 32)

Auto Indexes

ReactiveMongo Extensions support auto indexes which ensures indexes on DAO load.

object PersonDao extends {
  override val autoIndexes = Seq(
    Index(Seq("name" -> IndexType.Ascending), unique = true, background = true),
    Index(Seq("age" -> IndexType.Ascending), background = true)
  )
} with BsonDao[Person, BSONObjectID](MongoContext.db, "persons")

Default Write Concern

You can override writeConcern in your DAO definition which defaults to GetLastError().

object PersonDao extends BsonDao[Person, BSONObjectID](MongoContext.db, "persons") {
  override def defaultWriteConcern = GetLastError(j = true)
}

~ Operator for the Happy Path

While composing futures with for comprehensions, handling option values can be cumbersome. ~ operator converts a Future[Option[T]] to Future[T]. It throws a java.util.NoSuchElementException if the Option is None. Then you can check the exception in Future.recover.

import reactivemongo.extensions.Implicits._

(for {
  model1 <- ~dao.findOne("none" $eq "unknown")
  model2 <- ~dao.findOne("none" $eq "unknown")
  result <- compute(model1, model2)
} yield result) recover {
  case ex: java.util.NoSuchElementException =>
    println("Option is None")
    throw ex
}

Further documentation

Each type has its own dedicated documentation page, however API for all types are very similar.

BsonDao

BsonDsl

JsonDao

JsonDsl

Using ReactiveMongo Extensions in your project

The general format is that release a.b.c.d is compatible with ReactiveMongo a.b.c. Current version matrix is below:

ReactiveMongo Extensions Release Target ReactiveMongo version
0.10.0.2 0.10.0
0.10.0.3-SNAPSHOT 0.10.0
0.11.0.0-SNAPSHOT 0.11.0-SNAPSHOT

Note: Only available for scala 2.10.

If you use SBT, you just have to edit build.sbt and add the following:

libraryDependencies ++= Seq(
  "net.fehmicansaglam" %% "reactivemongo-extensions" % "0.10.0.2"
)

Or if you want to be on the bleeding edge using snapshots:

resolvers += "Sonatype Snapshots" at "http://oss.sonatype.org/content/repositories/snapshots/"

libraryDependencies ++= Seq(
  "net.fehmicansaglam" %% "reactivemongo-extensions" % "0.10.0.3-SNAPSHOT"
)

Contributions

Contributions are always welcome. Good ways to contribute include:

  • Raising bugs and feature requests
  • Fixing bugs
  • Improving the performance
  • Adding to the documentation