Last active
August 29, 2015 14:00
-
-
Save mathieuancelin/11284292 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package fwk | |
import scala.concurrent.{Future, ExecutionContext} | |
import play.api.libs.json.{JsUndefined, Json, JsObject, Format} | |
import play.modules.reactivemongo.json.collection.JSONCollection | |
import reactivemongo.bson.BSONObjectID | |
import reactivemongo.core.commands.LastError | |
import play.modules.reactivemongo.ReactiveMongoPlugin | |
import play.modules.reactivemongo.json.BSONFormats._ | |
trait GenericCollection[T, Id, Error] { | |
def insert(t: T)(implicit ctx: ExecutionContext): Future[(Id, Error)] | |
def delete(id: Id)(implicit ctx: ExecutionContext): Future[Error] | |
def update(id: Id, t: T)(implicit ctx: ExecutionContext): Future[Error] | |
def get(id: Id)(implicit ctx: ExecutionContext): Future[Option[(T, Id)]] | |
def findAll()(implicit ctx: ExecutionContext): Future[Traversable[(T, Id)]] = find(Json.obj())(ctx) | |
def find(sel: JsObject)(implicit ctx: ExecutionContext): Future[Traversable[(T, Id)]] | |
def findOne(sel: JsObject)(implicit ctx: ExecutionContext): Future[Option[(T, Id)]] | |
} | |
abstract class GenericMongoCollection[T](implicit format: Format[T]) extends GenericCollection[T, BSONObjectID, LastError] { | |
def coll: JSONCollection | |
override def insert(t: T)(implicit ctx: ExecutionContext): Future[(BSONObjectID, LastError)] = { | |
val id = BSONObjectID.generate | |
val obj = format.writes(t).as[JsObject] | |
obj \ "_id" match { | |
case _:JsUndefined => coll.insert(obj ++ Json.obj("_id" -> id)).map(err => (id, err)) | |
case _ => coll.insert(obj).map(err => (id, err)) | |
} | |
} | |
override def delete(id: BSONObjectID)(implicit ctx: ExecutionContext): Future[LastError] = { | |
coll.remove(Json.obj("_id" -> id)) | |
} | |
override def update(id: BSONObjectID, t: T)(implicit ctx: ExecutionContext): Future[LastError] = { | |
coll.update( | |
Json.obj("_id" -> id), | |
Json.obj("$set" -> t) | |
) | |
} | |
override def get(id: BSONObjectID)(implicit ctx: ExecutionContext): Future[Option[(T, BSONObjectID)]] = { | |
coll.find(Json.obj("_id" -> id)).cursor[JsObject].headOption.map(_.map( js => (js.as[T], id))) | |
} | |
override def findAll()(implicit ctx: ExecutionContext): Future[Traversable[(T, BSONObjectID)]] = find(Json.obj())(ctx) | |
override def find(sel: JsObject)(implicit ctx: ExecutionContext): Future[Traversable[(T, BSONObjectID)]] = { | |
coll.find(sel).cursor[JsObject].collect[Traversable]().map(_.map(item => (item.as[T], (item \ "_id").as[BSONObjectID]))) | |
} | |
override def findOne(sel: JsObject)(implicit ctx: ExecutionContext): Future[Option[(T, BSONObjectID)]] = { | |
coll.find(sel).one[JsObject].map(_.map(item => (item.as[T], (item \ "_id").as[BSONObjectID]))) | |
} | |
} | |
class GenericMongoCrud[T](c: JSONCollection)(implicit format: Format[T]) extends GenericMongoCollection[T] { | |
override def coll: JSONCollection = c | |
} | |
package object models { | |
case class Person(name: String, surname: String, age: Int) | |
object Person { | |
implicit val fmt = Json.format[Person] | |
} | |
} | |
package object repositories { | |
import models.Person | |
import models.Person._ | |
object MyMongoColl extends GenericMongoCollection[Person] { | |
override def coll: JSONCollection = ReactiveMongoPlugin.db(play.api.Play.current).collection[JSONCollection]("truc") | |
} | |
object MyMongoRepo { | |
lazy val crud = new GenericMongoCrud[Person](ReactiveMongoPlugin.db(play.api.Play.current).collection[JSONCollection]("truc")) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment