def version_tree(ob, root=False, reversion=False): """Create (if needed) a snapshot of the object graph starting at ob. Recursively visit all ob children, and: - check if they are cleanly versioned - version them if not (procedure="a"), set dirty True - version ob if necessary, and relate version of ob to children - return (version, dirty) -- dirty flag is also propagated upwards, and when True the version returned is just newly created else it is the latest previously-existing version found. root:bool -- a version of the root ob itself, even if cleanly vesrioned, is always created. Plus, parameters for other sub-calls are affected by whether we are daling with root instance or not. reversion:bool -- whether this is a revert to a previous version or not, in which case ob is the older version to revert to. -- current root types: Doc (only Event...), Attachment current child types: (only Event doc, that may not parent Events), Attachment """ assert get_feature_interface("version").providedBy(ob), \ "Not versionable! %s" % (ob) # !+reversion? # ob must be newly versioned if dirty, we always explicitly version root ob dirty = root or False child_obs = [] child_versions = [] # process children (determine via child-implicating features) if get_feature_interface("attachment").providedBy(ob): child_obs.extend(ob.attachments) #!+event-as-feature if hasattr(ob, "sa_events") and ob.sa_events: child_obs.extend(ob.sa_events) #!+signatory-as-feature #if hasattr(ob, "item_signatories") and ob.item_signatories: # child_obs.extend(ob.item_signatories) for child in child_obs: child_dirty, child_version = version_tree(child) child_versions.append(child_version) dirty = dirty or child_dirty def changed_since_last_version(ob): """Does ob need to be freshly versioned? """ try: # ordered by audit_id, newest first return ob.changes[0].action != "version" # !+what if a sub-child has been reversioned since last child version? except IndexError: return True dirty = dirty or changed_since_last_version(ob) if dirty: # create version if needed if reversion: auditor = audit.get_auditor(ob.audit_head) else: auditor = audit.get_auditor(ob) last_version = auditor.object_version(ob, root=root) session = Session() for cv in child_versions: # relate newly created ob last_version to child versions ct = domain.ChangeTree() ct.parent_id = last_version.audit_id ct.child_id = cv.audit_id session.add(ct) else: # retrieve newest version for ob last_version = ob.changes[0] return dirty, last_version
def _change_object(self): auditor = audit.get_auditor(self.context) return auditor.change_object
def version_tree(ob, root=False, reversion=False): """Create (if needed) a snapshot of the object graph starting at ob. Recursively visit all ob children, and: - check if they are cleanly versioned - version them if not (procedure="a"), set dirty True - version ob if necessary, and relate version of ob to children - return (dirty, version) -- dirty flag is also propagated upwards, and when True the version returned is just newly created else it is the latest previously-existing version found. root:bool -- a version of the root ob itself, even if cleanly vesrioned, is always created. Plus, parameters for other sub-calls are affected by whether we are daling with root instance or not. reversion:bool -- whether this is a revert to a previous version or not, in which case ob is the older version to revert to. """ assert feature.provides_feature(ob, "version"), "Not versionable! %s" % (ob) # !+reversion? # ob must be newly versioned if dirty, we always explicitly version root ob dirty = root or False # process children (determine via child-implicating features) child_obs = [] child_versions = [] for feature_subtype_name, sa_container_attr_name in VERSIONABLE_SUBTYPES_AS_FEATURES: if feature.get_feature_interface(feature_subtype_name).providedBy(ob): if feature.provides_feature(feature_subtype_name, "version"): child_obs.extend(getattr(ob, sa_container_attr_name)) for child in child_obs: child_dirty, child_version = version_tree(child) child_versions.append(child_version) dirty = dirty or child_dirty def changed_since_last_version(ob): """Does ob need to be freshly versioned? """ try: # ordered by audit_id, newest first return ob.changes[0].action != "version" # !+what if a sub-child has been reversioned since last child version? except IndexError: return True dirty = dirty or changed_since_last_version(ob) if dirty: # create version if needed if reversion: auditor = audit.get_auditor(ob.audit_head) else: auditor = audit.get_auditor(ob) last_version = auditor.object_version(ob, root=root) session = Session() for cv in child_versions: # relate newly created ob last_version to child versions ct = domain.ChangeTree() ct.parent_id = last_version.audit_id ct.child_id = cv.audit_id session.add(ct) else: # retrieve newest version for ob last_version = ob.changes[0] return dirty, last_version