Skip to content

Instantly share code, notes, and snippets.

@haywood
Created April 8, 2015 03:50
Show Gist options
  • Save haywood/9642b9c1cacf43f54f68 to your computer and use it in GitHub Desktop.
Save haywood/9642b9c1cacf43f54f68 to your computer and use it in GitHub Desktop.
Casbah DBObject/Play JsValue Conversion
/**
* This was something I explored today.
* The approach is fundamentally flawed for a couple of reasons.
*
* 1. play JSON serializes dates to strings,
* but they are better represented as timestamps or ISODates in mongo.
*
* 2. ObjectId's cannot be round-tripped, since they turn into JSON
* strings on the way out.
*
* There are probably further issues as well...
*/
package dao.mongodb
import play.api.libs.json._
import com.mongodb.casbah.Implicits._
import com.mongodb.BasicDBList
import com.mongodb.DBObject
import com.mongodb.casbah.commons.MongoDBObject
import com.mongodb.casbah.commons.MongoDBList
import org.bson.types.ObjectId
object JsonUtil {
def toMongoDBObject(obj: JsObject): DBObject = {
MongoDBObject {
obj.fields.toList.map { case (key, value) =>
key -> toMongo(value)
}
}
}
def toMongoDBList(list: JsArray): BasicDBList = {
MongoDBList.concat {
list.value.map { value => toMongo(value) }
}
}
def toMongo(json: JsValue): Any = json match {
case list: JsArray => toMongoDBList(list)
case JsBoolean(value) => value
case JsNull => null
case JsNumber(value) => value.toDouble
case obj: JsObject => toMongoDBObject(obj)
case JsString(value) => value
case undefined: JsUndefined => sys.error(undefined.toString)
}
def fromMongoDBObject(obj: MongoDBObject): JsObject = {
JsObject(obj.toSeq.map { case (key, value) =>
key -> fromMongo(value)
})
}
def fromMongoDBList(list: MongoDBList): JsArray = {
JsArray(list.map(fromMongo))
}
private def fromMongo(a: Any): JsValue = a match {
case id: ObjectId => JsString(id.toString)
case list: BasicDBList => fromMongoDBList(list)
case obj: DBObject => fromMongoDBObject(obj)
case long: Long => JsNumber(long)
case int: Int => JsNumber(int)
case float: Float => JsNumber(float)
case double: Double => JsNumber(double)
case decimal: java.math.BigDecimal => JsNumber(decimal)
case decimal: scala.BigDecimal => JsNumber(decimal)
case string: String => JsString(string)
case boolean: Boolean => JsBoolean(boolean)
case null => JsNull
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment