If I'm not mistaken the reason why I used a mixin trait and not LifecycleCallback in OneToMany is to affect the return value of save and delete_!.
------------------------------------- Jeppe Nejsum Madsen<je...@ingolfs.dk> wrote: On Thu, Jan 7, 2010 at 6:34 PM, David Pollak <feeder.of.the.be...@gmail.com> wrote: > Can you post some example code of your current thinking as a GitHub project > and we can work on refining it and tuning Mapper/MetaMapper to suit your > needs? I realize the original mail wasn't that informative. What can I say, I was in a hurry running out the door :-) I've been implementing this with the current mapper code and before creating GitHub projects etc let me try to explain the use case and we can see if something needs to be changed in mapper. I need to implement support for temporal database concepts (http://en.wikipedia.org/wiki/Temporal_database). For know I don't need full bi-temporal data, only valid-time. Lets assume the following simple schema: class Person extends LongKeyedMapper[Person] with IdPK { def getSingleton = Person object name extends MappedPoliteString(this, 20) object address extends MappedLongForeignKey(this,Address) } object Person extends Person with LongKeyedMetaMapper[Person] class Address extends LongKeyedMapper[Address] with IdPK { def getSingleton = Address object street extends MappedPoliteString(this, 20) } object Address extends Address with LongKeyedMetaMapper[Address] The challenge is now to be able to track the different addresses that this person have had over time and be able to answer questions such as: what's the current address? What was the address at 2009-12-31 etc. Ideally, I would like to just change the line object address extends MappedLongForeignKey(this,Address) to object address extends MappedTemporalObject(this,Address) and then be able to say e.g. person.address.set(addr, validInterval) // Add address that is valid in the specified interval person.address.set(addr) // Add address that is valid from current date person.address.history // Get list of addresses person.address.current // Get current address etc This is pretty close to a OneToMany scenario with the added complexity of a validity interval on the "many" part. I've used the OneToMany code as inspiration and made a solution that works (while not being as non-intrusive as the above) There are at least two things that needs to happen: 1) Add new fields to the Address object. We need validFrom/to dates, and foreign key. So currently, I must change my Address class into this: class Address extends LongKeyedMapper[Address] with IdPK with ValidTime[Long,Address] { def getSingleton = Address object person extends MappedLongForeignKey(this, Person) object street extends MappedPoliteString(this, 20) } where ValidTime is a trait containing the fields validFrom, validTo 2) Hook into the person object so that any changed addresses are saved class Person extends TemporalMapper[Long,Person] with LongKeyedMapper[Person] with IdPK { def getSingleton = Person object field extends MappedPoliteString(this, 20) object address extends MappedTemporalObject(Person,Address.person) } where TemporalMapper is a trait that overrides save/delete etc and MappedTemporalObject handles the collection of addresses. The above solution works and is not too cumbersome. To make the really nice solution, a few changes are need to mapper: 1) Ability construct a persisted entity dynamically. I.e I have the original Address class with no valid time fields or fk reference, but need to persist "Address with ValidTime with ForeignKey". This, I think, is the hard part :-) 2) The MappedTemporalObject needs to hook into the lifecycle events of the owner. I think what is needed is just for the LifecycleCallbacks to be extended with methods that can actually influence the lifecycle (ie if a lifecycle callback "save" fails, the owner "save" should fail) Let me know if this makes it more clear. As I said I have this working, so it's not high priority to get these changes, but they might come in handy in other scenarios as well..... /Jeppe -- You received this message because you are subscribed to the Google Groups "Lift" group. To post to this group, send email to lift...@googlegroups.com. To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.
-- You received this message because you are subscribed to the Google Groups "Lift" group. To post to this group, send email to lift...@googlegroups.com. To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.