Skip to content

ruseinov/reactivemongo-extensions

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

83 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

About

ReactiveMongo Extensions

Resources

License

Stars

Watchers

Forks

Packages

No packages published