Piotr Chamera wrote at 2006-12-6 00:57 +0100:
>I am using Zope 2.9 (zodb 3.6, FileStorage). The object I am interested 
>has several updates. Is there any way to get its previous states ("dead" 
>versions) to "live" objects (I need current state and all past states so 
>I cant? simply undo changes).

Yes -- But it might be a bit difficult when the object has
persistent subobjects.

The following code has chances to work (I used it for ZODB 3.2;
not sure whether it needs some modifications for ZODB 3.6).

#       $Id: History.py,v 1.3 2006/11/29 12:54:00 dieter Exp $
'''Support for access to the history of objects.'''

from OFS.History import historicalRevision
from Acquisition import aq_base

from DateTime import DateTime
from struct import unpack

# code extracted from "OFS/History.py"
def getHistory(obj,firstIndex=0,lastIndex=20):
  '''return the history records for *obj* between *firstIndex* and *lastIndex*.'''
  try: parent= obj.aq_inner.aq_parent
  except AttributeError: parent= None
  r= obj._p_jar.db().history(obj._p_oid,None,lastIndex)
  r= r[firstIndex:]
  for d in r:
    d['time']= DateTime(d['time'])
    d['key']= '.'.join(map(str, unpack(">HHHH", d['tid'])))
    h_obj= historicalRevision(obj, d['tid'])
    if parent is not None and hasattr(h_obj,'__of__'):
      h_obj= h_obj.__of__(parent)
    d['obj']= h_obj
  return r

def getObjectAt(obj,time):
  '''return the object *obj* as it has been at *time*.'''
  first= 0; last= 10; tc= obj.bobobase_modification_time()
  if time >= tc: return obj
  while 1:
    ts= getHistory(obj,first,last)
    if not ts: return None
    for t in getHistory(obj,first,last):
      if t['time'] <= time: return t['obj']
    first= last; last*= 2

def makeCurrent(target,version):
  '''make *version* current for *target*.'''
  # code extracted from "OFS.History.Historical.manage_historyCopy"
  # check, both *target* and *version* refer to the same object
  if target._p_oid != version._p_oid:
    raise ValueError, 'target and version refer to different objects'
  state= version.__getstate__()
  # Scrub the object before restoring the old state
  base = aq_base(target)

def getWorkflowHistoryAt(obj,time):
  '''auxiliary to obtain workflow history at *time* as a standard dict.'''
  wfh= getObjectAt(obj.workflow_history,time)
  if wfh is None: return {}
  d= {}
  for k,v in wfh.items(): d[k]= v
  return d

For more information about ZODB, see the ZODB Wiki:

ZODB-Dev mailing list  -  ZODB-Dev@zope.org

Reply via email to