Определите MongoRecord в лифте с картой внутри него - PullRequest
1 голос
/ 22 февраля 2012

Я не могу найти способ определить MongoRecord с полем Map[String,String] внутри него в Lift - MongoRecord.

Документация Lift гласит:

Все стандартные записиПоля поддерживаются.Также есть поддержка специфических типов Mongo;ObjectId, UUID, Pattern, List и Map.

Как определить поля Map и List?

Ответы [ 2 ]

4 голосов
/ 22 февраля 2012

Я определил BsonRecordMapField:

class BsonRecordMapField[OwnerType <: BsonRecord[OwnerType], SubRecordType <: BsonRecord[SubRecordType]]
(rec: OwnerType, valueMeta: BsonMetaRecord[SubRecordType])(implicit mf: Manifest[SubRecordType])
  extends MongoMapField[OwnerType, SubRecordType](rec: OwnerType) {

  import scala.collection.JavaConversions._

  override def asDBObject: DBObject = {
    val javaMap = new HashMap[String, DBObject]()
    for ((key, element) <- value)  {
      javaMap.put(key.asInstanceOf[String], element.asDBObject)
    }
    val dbl = new BasicDBObject(javaMap)
    dbl
  }

  override def setFromDBObject(dbo: DBObject): Box[Map[String, SubRecordType]] = {
    val mapResult: Map[String, SubRecordType] = (for ((key, dboEl) <- dbo.toMap.toSeq) yield (key.asInstanceOf[String], valueMeta.fromDBObject(dboEl.asInstanceOf[DBObject]))).toMap
    setBox(Full(mapResult))
  }


  override def asJValue = {
    val fieldList = (for ((key, elem) <- value) yield JField(key, elem.asJValue)).toList
    JObject(fieldList)
  }

  override def setFromJValue(jvalue: JValue) = jvalue match {
    case JNothing | JNull if optional_? => setBox(Empty)
    case JObject(fieldList) => val retrievedMap = fieldList.map {
      field =>
        val key = field.name
      val valRetrieved = valueMeta.fromJValue(field.value) openOr valueMeta.createRecord
      (key, valRetrieved)
    }.toMap
    setBox(Full(retrievedMap))
    case other => setBox(FieldHelpers.expectedA("JObject", other))
  }
}

Это неявный запрос для Rogue:

class BsonRecordMapQueryField[M <: BsonRecord[M], B <: BsonRecord[B]](val field: BsonRecordMapField[M, B])(implicit mf: Manifest[B]) {

  def at(key: String): BsonRecordField[M, B] = {
    val listBox = field.setFromJValue(JObject(List(JField("notExisting", JInt(0)))))
    val rec = listBox.open_!.head._2
    new BsonRecordField[M, B](field.owner, rec.meta)(mf) {
      override def name = field.name + "." + key
    }
  }
}

object ExtendedRogue extends Rogue {
  implicit def bsonRecordMapFieldToBsonRecordMapQueryField[M <: BsonRecord[M], B <: BsonRecord[B]](f: BsonRecordMapField[M, B])(implicit mf: Manifest[B]): BsonRecordMapQueryField[M, B] = new BsonRecordMapQueryField[M, B](f) (mf)


}

Теперь вы можете использовать оператор at на карте.

0 голосов
/ 03 мая 2012

А как насчет MongoMapField ?

...