Skip to content

Instantly share code, notes, and snippets.

@sundorf
Created March 14, 2012 19:20
Show Gist options
  • Save sundorf/2038811 to your computer and use it in GitHub Desktop.
Save sundorf/2038811 to your computer and use it in GitHub Desktop.
Play 2.0 Utility-Trait for Casbah/MongoDB
package models
import scala.Option.option2Iterable
import org.scalastuff.scalabeans.Preamble.descriptorOf
import org.scalastuff.scalabeans.BeanDescriptor
import com.mongodb.casbah.Imports._
import play.Logger
/**
* Utility trait for MongoDB to mix into entity classes.
*
* Add the following dependencies in Build.scala:
* "com.mongodb.casbah" % "casbah_2.9.1" % "2.1.5-1",
* "org.scalastuff" % "scalabeans" % "0.2"
**/
trait MongoModel {
var _id: org.bson.types.ObjectId = null
def save() = DB.getCollection(this).save(toDBObject())
def findModel(): MongoModel = {
val mongoColl = DB.getCollection(this)
val list = mongoColl.findOne(toDBObject())
if (list.isEmpty) null else fromDBObject(list.head.asInstanceOf[DBObject])
}
def findModel(modelClass: String, oid: ObjectId): DBObject = {
val o: DBObject = MongoDBObject("_id" -> oid)
val mongoColl = DB.getCollection(modelClass)
mongoColl.findOne(o).head
}
def find(searchObj: DBObject): MongoModel = {
val mongoColl = DB.getCollection(this)
val obj = mongoColl.findOne(searchObj)
if (obj.isEmpty) null else fromDBObject(obj.head.asInstanceOf[DBObject])
}
def find(t2: Tuple2[String, Object]): MongoModel = find(DBObject(t2))
def all(): List[MongoModel] = dbo2Model(collection().find)
def all(q: DBObject): List[MongoModel] = dbo2Model(collection().find(q))
def deleteAll() = collection().drop
def delete(): Any = delete(DBObject("_id" -> _id))
def delete(q: DBObject) = collection().remove(q)
def displayName = DB.simpleName(getClass.getSimpleName()).toUpperCase()
def collection() = DB.getCollection(this)
def count = collection().count
def casbah2Model(dbObj: MongoDBObject): MongoModel = {
val modelClass = this.getClass.getSuperclass.getName
val obj = Class.forName(modelClass).newInstance.asInstanceOf[MongoModel]
obj.fromDBObject(dbObj)
}
def dbo2Model(dbos: MongoCursor): List[MongoModel] = {
dbos.toList.map((dbObj: DBObject) => casbah2Model(dbObj))
}
def toDBObject(): DBObject = {
val obj = MongoDBObject()
for (property <- descriptor().properties) {
obj += property.name -> property.get(this)
}
obj
}
def fromDBObject(obj: DBObject): MongoModel = {
obj.foreach(tuple => this += (tuple._1, tuple._2))
this
}
def descriptor(): BeanDescriptor = descriptorOf(getClass())
def +=(name: String, value: Object) = {
try {
descriptor().set(this, name, value)
} catch {
case e: Exception => {
Logger.error("+=: " + e)
}
}
}
}
object DB {
val conn = MongoConnection()
//TODO: use caching
def getCollection(model: MongoModel) : MongoCollection = {
val name = model.getClass.getName
getCollection(name)
}
def getCollection(name: String) : MongoCollection = {
db(simpleName(name))
}
def getCollection(db: String, coll: String) = conn(db)(coll)
def apply(name: String) = getCollection(name)
def simpleName(name: String) = {
if(name.endsWith("$")) name.substring(0, name.length - 1) else name
}
//TODO read db name from config
def db : MongoDB = conn("mydb")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment