[ZODB-Dev] Can I abort part of a transaction setting self._p_changed=0?

Steve Spicklemire steve@spvi.com
Fri, 29 Jun 2001 07:04:41 -0500


Hi ZODB folk... 

Hmmm.. I've been persuaded, offline, that this approach is probably
doomed. 

The concept was to 'fake-out' the persistence mechanism, and as such,
it's clearly a hack. The problem arises due to a need to separate a
container and it's contents so that a synchronization mechanism can
operate on the two parts differently (e.g., recurse into the contents,
but also deal with the metadata in/about the container itself.)
ZCVSFolder and ZSyncer both currently suffer from this problem, and I
suppose any other synchronization techique that relies on the
import/export mechanism would as well. The problem would 'go away' of
the import/export mechanism allowed the caller to optionally 'exclude'
certain attributes from being exported in the zexp/xml. 

Another approach I thought of was to use object.__dict__[....] to get to
the attributes rather than direct assignment so that the persistence
machinery would not be alerted to the fact that _obejects was being
fiddled with (to prolong discussion of the 'hack' approach.) Thoughts?

thanks,
-steve


> Michel Pelletier wrote:
> >
> > On Thu, 28 Jun 2001, Steve Spicklemire wrote:
> >
> > > Hmm.. so either this question was:
> > >
> > > 1) Totally unclear and therefore unanswerable
> > >
> > > 2) Totally stupid and therefore not worth the time ... or..
> > >
> > > 3) So far out that nobody really knows...
> > >
> > > In case it's (1) I should clarify that by 'self.CommitObject', I mean
> > > "export self as a .zexp/.xml to CVS (or something)".
> >
> > That was definatly a confusing part.
> >
> > > does that help? I is (2)? I can't believe it's (3), but if so... I
> > > should start digging in the code.
> > >
> > > def CommitMetaDataOfObjectManager(self, anObjectManager):
> > >
> > >         holder = anObjectManager._objects
> > >         delete anObjectManager._objects
> > >         result = self.CommitObject(anObjectManager)
> > >         anObjectManager._objects = holder
> > >         return result
> > >
> > > so that the 'committed' objectManager is stripped of it's objects,
> > > committed, and then it's objects are restored. (it would be great if
> > > ObjectManager could present an interface that did that!). The problem is
> > > that fiddling with _objects will set the _p_changed flag and introduce
> > > an unwanted side effect of updating ZODB. Can I force _p_changed=0?
> > > Would that make this a thinkable possibility?
> >
> > I just looked at cPersistence.c, and it looks like you *can* set
> > _p_changed to 0.  But I'm not expert, so I'll let *you* make the call
> > (excerpted from _setattro):
> >
> >  if(name[3]=='c' && strcmp(name+4,"hanged")==0)
> >    {
> >      if (! v)
> >        {
> >          /* delatter is used to invalidate the object
> >             *even* if it has changed.
> >           */
> >          if (self->state != cPersistent_GHOST_STATE)
> >            self->state = cPersistent_UPTODATE_STATE;
> >          v=Py_None;
> >        }
> >      if (v==Py_None)
> >        {
> >          v=PyObject_GetAttr(OBJECT(self), py__p_deactivate);
> >          if (v) { ASSIGN(v, PyObject_CallObject(v, NULL)); }
> >          if (v) { Py_DECREF(v); }
> >          self->state=cPersistent_GHOST_STATE;
> >          return 0;
> >        }
> >      if (PyObject_IsTrue(v)) return changed(self);
> >      if (self->state >= 0) self->state=cPersistent_UPTODATE_STATE;
> >      return 0;
> >    }
> >
> > It looks to me like the if(!v) clause is checking to see if the value
> > is 0 and setting the objects state to cPersistent_UPTODATE_STATE.  The
> > if(PyObject_IsTrue(v)) clause looks like it's calling change().
> >
> > -Michel