Thanks you very much. I'm still having issues but I'll investigant it myself before I ask anything else. I think I came across as pushy and demanding and I'm sorry. I didn't mean to. I just ment this as questions and ideas.
You know ZODB much better than I and I'll go for a app-level implementation of undo unless I happen across a nice way to use ZODB for it. Thanks and sorry. -Arthur On 8/30/2005, "Tim Peters" <[EMAIL PROTECTED]> wrote: >[Arthur Peters] >> I want to do the following: commit a change to an object, then commit >> another. Now I want to undo the second change. Easy: get the tid using >> undoLog and call undo(tid, transaction.get()). Now the following >> transactions are in the DB: >> >> - Change 1 >> - Change 2 >> - Undo change 2 >> >> Now I want to take the DB back to the state before any of the three >> transactions were commited. I can find no way to do this because all the >> transactions change the same object and therefor I can never undo more >> than the most resent one. > >It might help if you showed a specific way you tried. The "obvious" way is >to undo the last 3 transactions at this point. For example: > >""" >import ZODB >import transaction >from ZODB.FileStorage import FileStorage > >st = FileStorage("Temp.fs") >db = ZODB.DB(st) >cn = db.open() >rt = cn.root() > >rt['state'] = 'start' >transaction.commit() > >rt['state'] = 'two' >transaction.commit() > >rt['state'] = 'three' >transaction.commit() >print "current state %r" % rt['state'] # prints 'three' > >undoable = st.undoLog() >db.undo(undoable[0]['id']) >transaction.commit() >print "after undoing: %r" % rt['state'] # prints 'two' > ># Undo the last three (the undo, setting 'three', and ># setting 'two'). Should get back to 'start' then. >undoable = st.undoLog() >for i, desc in enumerate(undoable): > if i > 2: > break > db.undo(desc['id']) >transaction.commit() >print "after undoing 3: %r" % rt['state'] # prints 'start' >""" > >Output from running that: > > current state 'three' > after undoing: 'two' > after undoing 3: 'start' > >> It seems to me reasonable that with this state ZODB should be able to >> undo "Change 1" because it is actually in the same state as it was >> between change 1 and change 2. >> >> I tried undoing them all in one transaction in hopes that the system >> would smart enough to know that it would not cause a conflict, but no >> luck. > >As above, it worked for me. BTW, I was using ZODB 3.4 there, but it >shouldn't matter except for spelling details. > >> The reason for all this is that I want to implement standard GUI-style >> undo/redo features in a ZODB application. >> >> Probably the easiest way to provide this functionality would be to >> implement a kind of undo that undoes all transactions back to a given >> point. > >My advice is to implement undo/redo in your application, not to rely on ZODB >for it. Some storages don't support undo at all, while those that do lose >old state after packing (or lose old state all by themselves). In addition, >it's very easy to create inconsistent database state by mucking with >DB-level undo unless undos are treated strictly in stack-like fashion. > >> Also in the back of my mind is the idea of being able to configure a >> connection to give me a non-current view of the DB (using MVCC). This >> would allow me to implement suffisticated diff'ing algorithms between >> states of the DB. This seems like it would be very easy to implement. >> With MVCC in place and all. > >It's not an intended use case for MVCC, and there's no direct support for >that now. Don't know how hard it would be to add; there are no current >plans to do so. > >> And would allow applications to implement much more suffisticates undo >> than could be implemented in the current system. Thoughts? > >ZODB isn't intended to be a version control system <0.6 wink>. Some >storages support undo(), but it's intended to be used lightly at worst -- >the implementation isn't warped toward doing undo efficiently. Seems to me >it's been treated as a necessary convenience, but no more than that. > >> and is this what custom conflict resolution is for? > >Not specifically, no. There is no general conflict resolution, BTW: all >conflict resolution is "custom". A type can choose to implement conflict >resolution if the author judges that it's OK for two (or more) transactions >to mutate the same piece of state simultaneously. Whether that makes any >sense at all, and the precise sense it may make, are entirely up to the >conflict resolution method's author. Undo isn't special here, it's just >another way of mutating state. > _______________________________________________ For more information about ZODB, see the ZODB Wiki: http://www.zope.org/Wikis/ZODB/ ZODB-Dev mailing list - ZODB-Dev@zope.org http://mail.zope.org/mailman/listinfo/zodb-dev