Created
January 23, 2013 17:12
-
-
Save tgpfeiffer/4610213 to your computer and use it in GitHub Desktop.
How to add generic versioning to Lift's MongoDB classes.
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
/** | |
* Carries some page content. | |
*/ | |
class Content extends MongoRecord[Content] | |
with ObjectIdPk[Content] | |
with Versioned[Content, ContentRevision] { | |
def meta = Content | |
def revisionMeta = ContentRevision | |
// ... | |
} |
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
/** | |
* Stores revisions of the Content class. | |
*/ | |
class ContentRevision | |
extends Revision[Content, ContentRevision] | |
with MongoRecord[ContentRevision] | |
with ObjectIdPk[ContentRevision] { | |
override def meta = ContentRevision | |
override def versionedMeta = Content | |
} | |
object ContentRevision | |
extends ContentRevision | |
with MongoMetaRecord[ContentRevision] {} |
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
/** | |
* Represents a revision of a certain versioned class (e.g., a ContentRevision). | |
* Thanks to Tim Nelson for help with the Manifest parameter. | |
*/ | |
abstract class Revision[T <: MongoRecord[T], TREV <: MongoRecord[TREV]](implicit mf: Manifest[T]) { | |
self: MongoRecord[TREV] => | |
def versionedMeta: T with MongoMetaRecord[T] | |
/** The object that this is a revision of */ | |
object of extends ObjectIdRefField(this.asInstanceOf[TREV], versionedMeta) | |
/** The date when the revision was created */ | |
object created extends DateField(this.asInstanceOf[TREV]) { | |
override def defaultValue = new Date() | |
} | |
/** The actual data of the archived object */ | |
object data extends BsonRecordField[TREV, T](this.asInstanceOf[TREV], versionedMeta) | |
} |
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
/** | |
* This is needed so that we can call super.save() from Versioned. | |
*/ | |
trait PreVersioned[T <: MongoRecord[T], TREV <: MongoRecord[TREV] with ObjectIdPk[TREV] with Revision[T, TREV]] { | |
def save: T | |
} | |
/** | |
* Represents a class that is versioned, i.e., has revisions. | |
*/ | |
trait Versioned[T <: MongoRecord[T], TREV <: MongoRecord[TREV] with ObjectIdPk[TREV] with Revision[T, TREV]] | |
extends PreVersioned[T, TREV] | |
with Loggable { | |
self: MongoRecord[T] with ObjectIdPk[T] => | |
/** | |
* To be overridden: points to the meta object of the class that we | |
* want to have versioned. | |
*/ | |
def revisionMeta: TREV with MongoMetaRecord[TREV] | |
/** | |
* Store a version of this object in the history before save. | |
*/ | |
abstract override def save = { | |
logger.debug("before saving " + id.is) | |
meta.find(id.is).foreach(obj => { | |
tryo { | |
val hist = revisionMeta.createRecord.of(id.is).data(obj).asInstanceOf[TREV].save | |
hist | |
} match { | |
case Failure(msg, _, _) => | |
logger.error("error while creating history item for " + id.is + ": " + msg) | |
case _ => | |
logger.info("created history item for " + id.is) | |
} | |
}) | |
super.save | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment