Created
March 24, 2011 09:33
-
-
Save kxbmap/884797 to your computer and use it in GitHub Desktop.
LiftでMongoDBにEnumeration#ValueをキーにしたMapを格納する
net.liftweb.mongodb.Metaがprivate[mongodb]なのでLiftのパッケージ。。
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
object RoboPartsType extends Enumeration { | |
val BD = Value("BD") | |
val HD = Value("HD") | |
val BS = Value("BS") | |
val AM = Value("AM") | |
val LG = Value("LG") | |
} | |
class RoboParts extends MongoRecord[RoboParts] with MongoId[RoboParts] { | |
def meta = RoboParts | |
object name extends StringField(this, 32) | |
object partsType extends EnumNameField(this, RoboPartsType) | |
object joints extends MongoEnumNameMapField[RoboParts, RoboPartsType.type, Int](this, RoboPartsType) | |
} | |
object RoboParts extends RoboParts with MongoMetaRecord[RoboParts] |
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
def test() { | |
import RoboPartsType._ | |
RoboParts.createRecord | |
.name("test") | |
.partsType(BD) | |
.joints(Map( | |
HD -> 1, BS -> 1, AM -> 2, LG -> 1 | |
)) | |
.save | |
RoboParts where (_.name eqs "test") fetch(1) foreach { p => | |
println(p) | |
println(p.joints.is(AM)) | |
} | |
} |
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 net.liftweb.mongodb.record.field | |
import _root_.net.liftweb.common.{Failure, Empty, Box, Full} | |
import _root_.net.liftweb.json.JsonAST.{JValue, JObject, JField, JNothing, JNull} | |
import _root_.net.liftweb.json.JsonParser | |
import _root_.net.liftweb.record.{Field, MandatoryTypedField, FieldHelpers} | |
import _root_.net.liftweb.mongodb.record.MongoRecord | |
import _root_.net.liftweb.util.Helpers.tryo | |
import _root_.com.mongodb.{BasicDBObject, DBObject} | |
class MongoEnumNameMapField[OwnerType <: MongoRecord[OwnerType], EnumType <: Enumeration, MapValueType](rec: OwnerType, enum: EnumType) | |
extends Field[Map[EnumType#Value, MapValueType], OwnerType] | |
with MandatoryTypedField[Map[EnumType#Value, MapValueType]] | |
with MongoFieldFlavor[Map[EnumType#Value, MapValueType]] { | |
import _root_.net.liftweb.mongodb.Meta.Reflection._ | |
def owner = rec | |
def defaultValue = Map[EnumType#Value, MapValueType]() | |
def setFromAny(in: Any): Box[Map[EnumType#Value, MapValueType]] = in match { | |
case dbo: DBObject => setFromDBObject(dbo) | |
case map: Map[EnumType#Value, MapValueType] => setBox(Full(map)) | |
case Some(map: Map[EnumType#Value, MapValueType]) => setBox(Full(map)) | |
case Full(map: Map[EnumType#Value, MapValueType]) => setBox(Full(map)) | |
case (map: Map[EnumType#Value, MapValueType]) :: _ => setBox(Full(map)) | |
case s: String => setFromString(s) | |
case Some(s: String) => setFromString(s) | |
case Full(s: String) => setFromString(s) | |
case null | None | Empty => setBox(defaultValueBox) | |
case f: Failure => setBox(f) | |
case o => setFromString(o.toString) | |
} | |
def setFromJValue(jvalue: JValue): Box[Map[EnumType#Value, MapValueType]] = jvalue match { | |
case JNothing | JNull if optional_? => setBox(Empty) | |
case JObject(obj) => setBox(Full( | |
Map() ++ obj.collect { | |
case jf if enum.values.exists(_.toString == jf.name) => | |
(enum.values.find(_.toString == jf.name).get, jf.value.values.asInstanceOf[MapValueType]) | |
} | |
)) | |
case other => setBox(FieldHelpers.expectedA("JObject", other)) | |
} | |
def setFromString(in: String): Box[Map[EnumType#Value, MapValueType]] = tryo(JsonParser.parse(in)) match { | |
case Full(jv: JValue) => setFromJValue(jv) | |
case f: Failure => setBox(f) | |
case other => setBox(Failure("Error parsing String into a JValue: "+in)) | |
} | |
def toForm = Empty // FIXME | |
def asJValue = JObject(value.keys.map { | |
k => | |
JField(k.toString, value(k).asInstanceOf[AnyRef] match { | |
case x if primitive_?(x.getClass) => primitive2jvalue(x) | |
case x if mongotype_?(x.getClass) => mongotype2jvalue(x)(owner.meta.formats) | |
case x if datetype_?(x.getClass) => datetype2jvalue(x)(owner.meta.formats) | |
case _ => JNothing | |
}) | |
}.toList) | |
/* | |
* Convert this field's value into a DBObject so it can be stored in Mongo. | |
*/ | |
def asDBObject: DBObject = { | |
val dbo = new BasicDBObject | |
value.keys.foreach { k => | |
dbo.put(k.toString, value.getOrElse(k, "")) | |
} | |
dbo | |
} | |
// set this field's value using a DBObject returned from Mongo. | |
def setFromDBObject(dbo: DBObject): Box[Map[EnumType#Value, MapValueType]] = { | |
import scala.collection.JavaConversions._ | |
setBox(Full( | |
Map() ++ dbo.keySet.collect { | |
case k if enum.values.exists(_.toString == k) => | |
(enum.values.find(_.toString == k).get, dbo.get(k).asInstanceOf[MapValueType]) | |
} | |
)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment