Permalink
Browse files

2.10: lift-mapper

  • Loading branch information...
1 parent 37c7256 commit d175b71de428efdc895b259261707819ba666f17 @nafg nafg committed Sep 19, 2012
@@ -71,9 +71,6 @@ trait ManyToMany extends BaseKeyedMapper {
val otherMeta: MetaMapper[T2],
val qp: QueryParam[O]*) extends scala.collection.mutable.Buffer[T2] {
- def thisFK[A](join: O)(f: MappedForeignKey[K,O,_>:T] => A): A =
- thisField.actualField(join) match { case mfk: MappedForeignKey[K,O,T] => f(mfk) }
-
def otherFK[A](join: O)(f: MappedForeignKey[K2,O,T2] => A): A =
otherField.actualField(join) match { case mfk: MappedForeignKey[K2,O,T2] => f(mfk) }
@@ -106,7 +103,9 @@ trait ManyToMany extends BaseKeyedMapper {
removedJoin // well, noLongerRemovedJoin...
case None =>
val newJoin = joinMeta.create
- thisFK(newJoin)(_.apply(ManyToMany.this))
+ thisField.actualField(newJoin) match {
+ case mfk: MappedForeignKey[K,O,T] => mfk.set(primaryKeyField.is.asInstanceOf[K])
+ }
otherFK(newJoin)(_.apply(e))
newJoin
}
@@ -120,7 +119,7 @@ trait ManyToMany extends BaseKeyedMapper {
removedJoins = join :: removedJoins
val o = otherField.actualField(join)
o.set(o.defaultValue)
- thisFK(join)(f => f.set(f.defaultValue))
+ thisField.actualField(join) match { case mfk => mfk set mfk.defaultValue }
Some(join)
case None =>
None
@@ -190,7 +189,7 @@ trait ManyToMany extends BaseKeyedMapper {
* Discard the cached state of this MappedManyToMany's children and reinitialize it from the database
*/
def refresh = {
- val by = new Cmp[O, TheKeyType](thisField, OprEnum.Eql, Full(primaryKeyField.is), Empty, Empty)
+ val by = new Cmp[O, TheKeyType](thisField, OprEnum.Eql, Full(primaryKeyField.is.asInstanceOf[K]), Empty, Empty)
_joins = joinMeta.findAll( (by :: qp.toList): _*)
all
@@ -210,7 +209,9 @@ trait ManyToMany extends BaseKeyedMapper {
_joins = joins.filter { join =>
otherFK(join)(f => f.is != f.defaultValue)
}
- _joins foreach { thisFK(_)(_ set ManyToMany.this.primaryKeyField.is) }
+ _joins foreach {
+ thisField.actualField(_).asInstanceOf[MappedForeignKey[K,O,X] forSome {type X <: KeyedMapper[K,X]}] set ManyToMany.this.primaryKeyField.is.asInstanceOf[K]
+ }
removedJoins.forall {_.delete_!} & ( // continue saving even if deleting fails
children.forall(_.save) &&
@@ -449,7 +449,7 @@ trait MappedField[FieldType <: Any,OwnerType <: Mapper[OwnerType]] extends Typed
def toForm: Box[NodeSeq] = {
- def mf(in: Node): NodeSeq = in match {
+ def mf(in: scala.xml.Node): NodeSeq = in match {
case g: Group => g.nodes.flatMap(mf)
case e: Elem => e % toFormAppendedAttributes
case other => other
@@ -690,7 +690,7 @@ trait MappedField[FieldType <: Any,OwnerType <: Mapper[OwnerType]] extends Typed
case _ => false
}
- override def asHtml : Node = Text(toString)
+ override def asHtml: scala.xml.Node = Text(toString)
}
object MappedField {
@@ -1785,17 +1785,25 @@ trait KeyedMetaMapper[Type, A<:KeyedMapper[Type, A]] extends MetaMapper[A] with
def asSafeJs(actual: A, f: KeyObfuscator): JsExp = {
val pk = actual.primaryKeyField
val first = (pk.name, JE.Str(f.obscure(self, pk.is)))
- JE.JsObj(first :: ("$lift_class", JE.Str(dbTableName)) :: mappedFieldList.
- map(f => this.??(f.method, actual)).
- filter(f => !f.dbPrimaryKey_? && f.renderJs_?).flatMap{
- case fk: Q =>
- val key = f.obscure(fk.dbKeyToTable, fk.is)
- List((fk.name, JE.Str(key)),
- (fk.name+"_obj",
- JE.AnonFunc("index", JE.JsRaw("return index["+key.encJs+"];").cmd)))
-
- case x => x.asJs}.toList :::
- actual.suplementalJs(Full(f)) :_*)
+ JE.JsObj(
+ first ::
+ ("$lift_class", JE.Str(dbTableName)) ::
+ mappedFieldList
+ .map(f => this.??(f.method, actual))
+ .filter(f => !f.dbPrimaryKey_? && f.renderJs_?)
+ .flatMap{
+ case fk0: MappedForeignKey[_, _, _] with MappedField[_, _] =>
+ val fk = fk0.asInstanceOf[Q]
+ val key = f.obscure(fk.dbKeyToTable, fk.is)
+ List(
+ (fk.name, JE.Str(key)),
+ (fk.name+"_obj", JE.AnonFunc("index", JE.JsRaw("return index["+key.encJs+"];").cmd))
+ )
+ case x => x.asJs
+ }
+ .toList :::
+ actual.suplementalJs(Full(f)) : _*
+ )
}
private def convertToQPList(prod: Product): Array[QueryParam[A]] = {
@@ -18,6 +18,12 @@ package net.liftweb
package mapper
+private[mapper] object RecursiveType {
+ val rec: { type R0 <: Mapper[R0] } = null
+ type Rec = rec.R0
+}
@fmpwizard

fmpwizard Jan 7, 2013

Owner

would you mind explaining if this additional code fixed an error or what is the purpose of it? I'm not questioning that we need it, but it is more along the lines I have no idea what this does :)

@nafg

nafg Jan 7, 2013

Contributor

Yes, 2.10 is much more allergic to recursive "MyType." That is, it needs more strict proof; you can't use something that the compiler doesn't know is precisely that type. The above encodes the general "recursive Mapper MyType" so we can use it when the type is not fully known. See for instance line 40 below. I was really stuck on it, actually originally in Record, and this was suggested by Aleksey Nikiforov here: https://groups.google.com/d/topic/scala-language/bPWlyonbODI/discussion

+import RecursiveType._
+
/**
* Add this trait to a Mapper for managed one-to-many support
* For example: class Contact extends LongKeyedMapper[Contact] with OneToMany[Long, Contact] { ... }
@@ -26,13 +32,14 @@ package mapper
* @author nafg
*/
trait OneToMany[K,T<:KeyedMapper[K, T]] extends KeyedMapper[K,T] { this: T =>
- private[mapper] lazy val oneToManyFields: List[MappedOneToManyBase[_]] = {
- new FieldFinder[MappedOneToManyBase[_]](
+
+ private[mapper] lazy val oneToManyFields: List[MappedOneToManyBase[Rec]] = {
+ new FieldFinder[MappedOneToManyBase[Rec]](
getSingleton,
net.liftweb.common.Logger(classOf[OneToMany[K,T]])
- ).accessorMethods map (_.invoke(this).asInstanceOf[MappedOneToManyBase[_]])
+ ).accessorMethods map (_.invoke(this).asInstanceOf[MappedOneToManyBase[Rec]])
}
-
+
/**
* An override for save to propagate the save to all children
* of this parent.
@@ -52,9 +59,10 @@ trait OneToMany[K,T<:KeyedMapper[K, T]] extends KeyedMapper[K,T] { this: T =>
* If they are all successful returns true.
*/
override def delete_! = DB.use(connectionIdentifier){_ =>
- if(oneToManyFields.forall{
- case f: Cascade[_] => f.delete_!
- case _ => true
+ if(oneToManyFields.forall{(_: MappedOneToManyBase[_ <: Mapper[_]]) match {
+ case f: Cascade[_] => f.delete_!
+ case _ => true
+ }
})
super.delete_!
else {
@@ -97,7 +105,7 @@ trait OneToMany[K,T<:KeyedMapper[K, T]] extends KeyedMapper[K,T] { this: T =>
* @param foreign A function that gets the MappedForeignKey on the child that refers to this parent
*/
class MappedOneToManyBase[O <: Mapper[_]](val reloadFunc: ()=>Seq[O],
- val foreign: O => MappedForeignKey[K,_,T]) extends scala.collection.mutable.Buffer[O] {
+ val foreign: O => MappedForeignKey[K,_,T] /*forSome { type X <: Mapper[X] }*/) extends scala.collection.mutable.Buffer[O] {
private var inited = false
private var _delegate: List[O] = _
/**
@@ -117,10 +125,11 @@ trait OneToMany[K,T<:KeyedMapper[K, T]] extends KeyedMapper[K,T] { this: T =>
* Takes ownership of e. Sets e's foreign key to our primary key
*/
protected def own(e: O) = {
- foreign(e) match {
- case f: MappedLongForeignKey[O,T] with MappedForeignKey[_,_,T] =>
+ val f0 = foreign(e).asInstanceOf[Any]
+ f0 match {
+ case f: MappedLongForeignKey[O,T] with MappedForeignKey[K,_,T] =>
f.apply(OneToMany.this)
- case f =>
+ case f: MappedForeignKey[K,_,T] =>
f.set(OneToMany.this.primaryKeyField.get)
}
if(!OneToMany.this.saved_?)
@@ -64,7 +64,7 @@ trait ModelSnippet[T <: Mapper[T]] extends StatefulSnippet {
def load(entity: T) = view.entity = entity
- def dispatch = {
+ def dispatch: DispatchIt = {
case "list" => list _
case "edit" => edit _
case "newOrEdit" => view.newOrEdit _

1 comment on commit d175b71

Owner

fmpwizard commented on d175b71 Jan 7, 2013

+1

Please sign in to comment.